# HG changeset patch # User Thomas Arendsen Hein # Date 1348827238 -7200 # Node ID 11d8cc2deb92a34ab09fc4cd7e4212d7d1500d86 # Parent 3f9fc88aec2b51a2847c078ad23de675d66892a3# Parent 975bb59bb136f62d660b5d8e407d17d5be3b68fe merged doc/1.0 diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/ChangeLog Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,686 @@ +2010-04-28 Ingo Weinzierl + + * Changes, NEWS, ChangeLog: Summarized changes. + +2010-04-28 Ingo Weinzierl + + * src/test/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleanerTestCase.java, + src/main/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleaner.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutor.java, + src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/DatasourceException.java, + src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java: Removed + trailing whitespace. + +2010-04-20 Tim Englich + + * src/test/ressources/QueryExecutorTestCase.properties, + src/test/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleanerTestCase.java: + Integrated Testcase for testing the Basefunctionality of the CacheCleaner. + +2010-04-20 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java: + Integrated the initialization of the CacheCleaner if an SQl-Cache is used. + Also implemented the Method for CleanUp the SQL-Cache in the extended + QueryExecutor. + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutor.java: + Extended Interface adding an Method that should do the Cleanup of the + SQL-Cache. + + * src/main/java/de/intevation/gnv/geobackend/base/query/cache/package.html: + Added Documentation. + + * src/main/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleaner.java: + Added Threadimplementation that looks every n-Seconds into the Database + if there are Tables that where updated during the Time to the last Cleanup. + If there are Tables that has been modified the CacheCleaner will call the + used QueryExecutor. The Queryexecutor will clean up it's Cache using the + Names of the affected Tables. + It is Possible to configure the Interval between two cleanups. for this + you have to set the Systemproperty -Dcaching.cleaner.interval using Seconds + as unit. + +2010-04-16 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/ConnectionException.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ColDefinition.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ResultSet.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/DatasourceException.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/TechnicalException.java, + src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java: + Using unix line endings only. + +2010-04-17 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java: + Removed trailing whitespace. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/query/package.html, + src/main/java/de/intevation/gnv/geobackend/util/package.html, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/package.html, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/package.html, + src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/package.html, + src/main/java/de/intevation/gnv/geobackend/sde/package.html, + src/main/java/de/intevation/gnv/geobackend/base/query/exception/package.html, + src/main/java/de/intevation/gnv/geobackend/base/query/container/exception/package.html, + src/main/java/de/intevation/gnv/geobackend/base/query/container/package.html, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/package.html, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/package.html, + src/main/java/de/intevation/gnv/geobackend/base/package.html: + Added more Javadoc. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java, + src/main/java/de/intevation/gnv/geobackend/base/Result.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java: + Modified some JavaDoc so that the Warnings that where caused by mistakes + are removed. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java, + src/main/java/de/intevation/gnv/geobackend/base/Result.java, + src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ResultSet.java, + src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java: + Modified some JavaDoc so that the Warnings that where caused by mistakes + are removed. + +2009-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/**/package.html: New. + Added package description with text 'DOCUMENT ME!'. + +2009-03-29 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/geobackend/**/*.java: + Bring @author javadoc tags in form '@author John Doe' + + find -name \*.java | \ + xargs sed -i \ + -e 's/@author[ ]\+\([^(<]\+\)[<(]\([^>)]\+\)[>)]/@author \1<\/a>/g' \ + -e 's@[ ]\+@@g' + +2009-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/**/*.java: + Ordered imports. Removed empty headers. + +2009-03-29 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java, + src/test/java/de/intevation/gnv/geobackend/base/query/ToCharSample.java, + src/test/java/de/intevation/gnv/geobackend/base/query/GroupBySample.java, + src/test/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnectionPoolTestCase.java, + src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java, + src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java, + src/main/java/de/intevation/gnv/geobackend/base/query/DefaultQueryExceutor.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPoolFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPool.java, + src/main/java/de/intevation/gnv/geobackend/base/ResultDescriptor.java, + src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java, + src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEResultSetMetaData.java, + src/main/java/de/intevation/gnv/geobackend/util/BlockCollection.java, + src/main/java/de/intevation/gnv/geobackend/util/RedundancyRemover.java: + Removed trailing whitespace. + find -name \*.java | xargs sed -i 's/[ \t]\+$//' + +2010-03-26 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/*.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/*.java, + src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/query/exception/QueryException.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/ConnectionException.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPoolFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/*.java: + Updated Javadocs to the Listed Classes. + Also done some Codecleanup and removed unused Methods from the Code. + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnectionParams.java: + Removed unused Class ArcSDEConnectionParams. + +2010-03-26 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Datasource.java: + Removed unused Class Datasource. + +2010-03-26 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/DatasourceConnection.java: + Removed unused Class DatasourceConnection. + +2010-03-26 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEQuery.java: + Removed unused Class SDEQuery. + +2010-03-16 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java (createPoints): + Now it is also possible to extract Points from a given LineString. + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Added Support for SpatialQueries using LineString as Geometry of Interest. + +2010-03-12 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Added support for MultiLineString-Geometries. The Points do not belong to one + Geometryelement. We have to lookup if the Geometry is Multiparted. + If it is we have to split the Points into several LineStrings which belongs + to one MultiLineString. + +2010-03-12 Tim Englich + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEResultSetMetaData.java (getColumnClassName): + Added more ClassName identificaton for the different datatypes of the ArcSDE. + Now it is possible to distinguish between Integer, Long, String, Date, + Float and Double Objects. + This is required to get a valid Shape- and WMS-Export. + +2010-03-09 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Switched to using asText(...)-Function of SeShapes-Objects for generating + an WKT-String for Polygons. Going this way we are able to produce valid + WKT for all kinds of Polygons deliverd by the ArcSDE. + We cannot use this Method for Points and LineStrings because the WKT + which will be produced is invalid e.g. Point Z (...) LineString m (...) + I didn't find Invalid WKTs for Polygons which in Database-Rables we are + using right now. + + It has to be monitored if there are Polygons in the Database which will + produce invalid WKT-Strings. + +2010-03-08 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Implemented Support of MultiPolygons. The Points do not belong to one + Geometryelement. We have to Lookup ifthe Geometry is Multiparted. + If it is we have to split the Points into several Polygons which belongs + to one Multipolygon. + This Fix solve did not solve any Parsingerros. Some geometries are still + corrupt. + +2010-03-08 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Added Suport for the Geometrytyp SimpleLine. + SimpleLine will be handled as an Line. + +2010-02-05 Ingo Weinzierl + + Issue170 + + * artifact-database/pom.xml: Changed log4j version to 1.2.14 (later version + causes errors and breaks while maven build process). + +2010-02-05 Tim Englich + + * pom.xml: + Changed from ArcSDE version 9.2.5 to Version 9.3 + You have to Install the required Libraries as described in + https://bsh-intern.intevation.de/Mavenbuildprozess + +2010-01-27 Hans Plum + + RELEASE 0.4 + + * Changes, NEWS, ChangeLog: Summarized changes. + +2009-01-25 Sascha L. Teichmann + + Fix for gnv/issue107 + + * src/main/java/de/intevation/gnv/geobackend/util/RedundancyRemover.java: + New. Used to reduce the redundancy of data in SQL result sets. Column + values are very distinct so the degree or redundancy is very high. E.g + the SDE produces for each date value a java.util.GregorianCalendar object + which are very heavy weighted. We only use them r/o so we can hash each date + value to one unique representative. Same logic applys to integer values + and so on. + + With this technique we are able to reduce the memory consumption by + over 90%. Because it is not very feasible to store the whole history + of column we only have a limited number of cached values per column. + This is controlled via the system property + "de.intevation.gnv.geobackend.util.RedundancyRemover.lookback" which + defaults to 1029. + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java: + Use RedundancyRemovers to filter the incoming traffic from SDE. + +2010-01-26 Tim Englich + + * src/test/java/de/intevation/gnv/geobackend/base/query/ToCharSample.java : + Added Sample for bug in ArcSDE 9.3 using to_char-Function with SpatialQuery + * src/test/java/de/intevation/gnv/geobackend/base/query/GroupBySample.java : + Added Sample for Bug in ArcSDE using group by with SpatialQuery + +2009-01-25 Sascha L. Teichmann + + Another attempt to fix gnv/issue34 + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java: + Add a toString() method. + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java: + Added an idle time detection mechanism. You can call touch() on + a connection to refresh the internal timestamp and ask with isActive() + if a constructor given time interval in milliseconds is exceeded. + + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java: + Added a check of inactivity to validateObject() before relying on SDE logic. + This is the last line of defence if the testServer() call is going not to respond. + This duplicates the eviction policy of Apache Commons pool a bit but I found + this way to be more trustworthy. + + The idle time is configure with the property 'serverInactiveInterval'. + units: seconds. Defaults to 5 minutes. + + The unit of 'serverRoundtripInterval' (parameter of testServer()) is now + in seconds, too. Default: 5 seconds. This is the value used in GeoTools. + +2009-01-09 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEQuery.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Cleanup imports. + +2010-01-15 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java (isValid): + Implemented the isValid-method of the ArcSDEConnection for + getting a propper Validation of the used SEConnection. + For the Validation the Method testServer of the SEConnection is used. + + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java (ArcSDEPoolableObjectFactory): + Added Member serverRoundtripInterval to represent the Time in + Milliseconds which is allowed to reused a returned Connection. + Also used Connection.isValid Method instead of Connection.isClosed + to validate the Connection befor it could be borrowed from the Pool. + +2009-01-12 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Added bicubic spline interpolation on raster tiles. This + should increase the 'virtual' resolution more than the + bilinear interpolation. To enable it write 'bicubic' into + the configuration file. + + * pom.xml: Added dependency to Apache Common Math 2.0 for + the cubic spline interpolation. + +2009-01-09 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Added static method to fetch matching interpolation type for + given string. Defaults to nearest neighbor if no string is matching. + +2009-01-09 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Implemented bilinear interpolation. + +2009-01-09 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java: + Fixed transformations to figure out the right tile in the SDE. + Taking the tile origin into account now and does not do wrong rounding + of column and row indices. Simplified the code a lot. + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Fixed access to right right pixel now. Removed the envelope code because + its not needed any longer. You can ask a RasterObject directly now if + a given coordinate is on the tile now. The tile space is now correctly + spanned between (0, 0) and (tile width - 1, tile height - 1) now which + allows other access patterns like bilinear interpolation. TODO: implement + bilinear interpolation. + +2010-01-08 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEQuery.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java, + src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPoolFactory.java (initializeConnectionPool): + Removed Encodingerrors from listed Files. All Files are now UTF-8 compliant. + +2010-01-05 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java: + Made it serializable to be cachable beyond reboot. + +2010-01-05 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (handleResultSet): + Switched to return the RasterObject instead of the depth in an Rasterquery. + This should help to get a better performance. + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java (RasterObject): + Added new Object for Caching Rastertiles and all Informations that are + required for calculating the Depth to a given Coordinate. + +2010-01-04 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (handleResultSet): + Added Rasterdatasupport to the ARCSDESTATEMENT. + Now it is possible to Query the Value of an Pixel like that: + SELECT ST_ASTEXT(RASTER) FROM MEDIAN.TOPO_BS_D_6X10SEC where INTERSECTS(RASTER, "POINT( 12.084721594184593 54.35583351483295)") + +2009-12-19 Sascha L. Teichmann + + * contrib/sql-cache.xml: Configured disk storage to survive restarts. + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java: + Added explicit shutdown hook. + + * src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java: + Fixed spelling of cacheResults() which prevented results to be stored in cache. + Added some logging. + +2009-12-18 Sascha L. Teichmann + + Experimental caching of SQL results via Ehcache + + * pom.xml: Added dependency to Ehcache + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutor.java: + Extended interface to support caching by SQL statements as Strings. + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java: + Implements new interface with no caching + + * src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java: + synchronized access to singleton. + + * src/main/java/de/intevation/gnv/geobackend/base/query/DefaultQueryExceutor.java: + calls caching methods of base class. + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java: + When system property 'query.executor.factory' is given the value is used as + a class name to be instantiated as a sub class of QueryExecutorFactory. + This happens if the singleton of QueryExecutorFactory is created. With the + mechanism it is possible to replace the standard behavior of creating QueryExecutors. + + * src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java: + New: This class extends QueryExecutorFactory and can be used as replacement for + the standard QueryExecutorFactory. Usage: + + -Dquery.executor.factory=de.intevation.gnv.geobackend.base.query.CachingQueryExecutorFactory + + If you pass in another system property 'caching.query.executor.config' you can + customize the caching. The value is used as a file name to an XML file with + Ehcache configuration. + + * contrib/sql-cache.xml: Demo configuration for sql caching. Usage: + + -Dquery.executor.factory=de.intevation.gnv.geobackend.base.query.CachingQueryExecutorFactory + -Dcaching.query.executor.config=contrib/sql-cache.xml + +2009-12-17 Sascha L. Teichmann + + RELEASE 0.3 + + * Changes, NEWS, ChangeLog: Summarized changes. + +2009-12-17 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java: + Fixed bug in DefaultResult when querying an index out of bounds. + +2009-12-15 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + We have to use a different SpatialFilter for Point in Polygon Queries as + in AreaIntersection Statements. + So we have to include a switch which will do that. + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java (createPoints): + Added Support of Point-Objects for the possibility to execute a Point in Pologon + Statement using the ArcSDE. + +2009-12-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java: + DefaultResult will return null if it doesn't contain the specified column + name in method getString(String columnName), instead of throwing an + exception. + +2009-12-11 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java, + src/main/java/de/intevation/gnv/geobackend/base/query/container/DefaultQueryContainer.java: + Removed needless imports. + +2009-11-30 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEResultSetMetaData.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java: + Added missing Methodstubs for Java 1.6 compability. + ################################################### + ###### ATTENTION: ONLY USE JAVA 1.6 FOR THIS ###### + ###### AND ALL USING MODULES. ###### + ################################################### + +2009-11-27 Tim Englich + + * src/test/ressources/QueryExecutorTestCase.properties, + src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java: + Revert Changes of the commit of Revision 377 which was unintended + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Changed Splitalgorithm of Statements so that it is Possible to add to_date Colums into a Statement + with Spatial-Columns or Spatial-Filters + +2009-11-13 Hans Plum + + RELEASE 0.2 + + * Changes, NEWS: Summarized changes. + +2009-11-13 Hans Plum + + * Made some ChangeLog entries a bit clearer. + +2009-11-10 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Changed the splitting of the Statements for ARCSDE-Transformation. + Now it is possible to use a Select-Statement as an Table. + +2009-11-06 Ingo Weinzierl + + * target/**: Removed. Should not be in version control. + +2009-11-05 Tim Englich + + * src/test/ressources/QueryExecutorTestCase.properties, + src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java (testSpatialQueryWithInnerSelect): + Added an Tescase to test the InnerSelect Statments in Spatial-Queries. + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Bugfix. An Point could not have an Z-Coordinate-Value + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Added the possibility to execute Spatial-Queries using InnerStatements instead + of WKT in Intersects-where-clauses. + +2009-11-02 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java (createStatement): + Changed TODO to a question + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + CodeCleanup: Removed deprecated TODO + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java (getColumnIndex): + Removed Typo. + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java: + CodeCleanup: Removed deprecated TODOS and replace Tabs with whitespaces. + * src/main/java/de/intevation/gnv/geobackend/base/query/container/DefaultQueryContainer.java:, + src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java: + CodeCleanup: Removed unused Method getQueryIds + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java (closeConnection): + CodeCleanup: Inspect TODO and ansewerd the Question that the Connection has not to + be closed at that position but perhaps insite the ConnectionPool. + +2009-10-30 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Added Support for Polygons without interior Rings. This is required for generating + Horizontal Cross-Section Outputs. + The Z-Value of an Point was also added to the WKT-Represantation. + +2009-10-29 Tim Englich + + Issue 45: Defintion of gaps in temporal and spatial data + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java (getInteger): + Added Integer-Support for DoubleValues because the ArcSDE does + not read values like -1 as Integer-values. issue45 + +2009-10-20 Tim Englich + + Issue 57: Improving memory usage of data objects + + * src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java (QueryExecutorBase), + src/main/java/de/intevation/gnv/geobackend/base/ResultDescriptor.java (getColumnClassName), + src/main/java/de/intevation/gnv/geobackend/base/Result.java, + src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java (serialVersionUID), + src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java (getDate): + Integrated Patch of issue57 to get some Memoryusage-improvements + +2009-10-19 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java: + Extends from HashMap directly to avoid one level of indirection and + do not create so much needless objects. + + TODO: The representation in form of HashMaps is not very efficent! + Use array with index instead. + +2009-10-14 Tim Englich + + * src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java (testSpatialQueryWithoutIntersects), + src/test/ressources/QueryExecutorTestCase.properties: + Added further Queries for Testing Spatial-Query-Support + +2009-10-14 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getPosValue): + Add WKT-Syntaxt to Shape ReturnValue + * src/test/ressources/QueryExecutorTestCase.properties: + Changed Test-Query-Statement for Spatial-Queries with INNERJOINS and ORDER BY + * src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java (testSpatialQueryWithoutIntersects): + Changed expected Result-Size because of Changes in the QueryStatement which is used. + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Added INNERJOIN, ORDER BY and GROUP BY support to Spatial Queries + +2009-10-13 Tim Englich + + * src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java (testSpatialQueryWithoutIntersects): + Added an TaesCase for Querying spatial Data without an spatial restriction + * src/test/ressources/QueryExecutorTestCase.properties: + Added TestQuery with no spatial restriction + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Now it is possible to send spatial Quieries without an spatial restriction in the where clause. + +2009-10-13 Tim Englich + + Issue 34: SQL Exception in REST Server when accessing geo-backend + + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java (validateObject) Edited: + Added Tests if the Object is Closed. And add propper instance Tests + * src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java (initialize): + Added further ConfigurationParameters that could be set in the *.properties-File. + maxWait, maxIdle, minIdle, testOnBorrow, testOnReturn, testWhileIdle, numTestsPerEvictionRun, + timeBetweenEvictionRunsMillis, testWhileIdle + * src/test/ressources/ArcSDEConnectionPoolTestCase.properties: + Added som Configurationproperties for testing. + + +2009-10-13 Tim Englich + * src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java (QueryExecutorTestCase): + Changed expected Result of Spatial-Query-TestCase because of Changes to the used Query + * src/test/ressources/QueryExecutorTestCase.properties: + Added SFS-Conformal Query + * pom.xml: + Added dependency to JTS 1.9 + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (executeQuery): + Added Spatial-Query-Support for ArcSDE + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java (createPoints): + Switched Method Signature to JTS-Geometry-Support + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java (getStringValue): + Added String-Support for GeometryObjects + +2009-10-07 Sascha L. Teichmann + + RELEASE 0.1 + + * Changes, NEWS: Summarized changes. + +2009-10-06 Sascha L. Teichmann + + * Changelog -> ChangeLog: Renamed to make eclipse happy. Unified changelog style. + + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEQuery.java, + src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java: + Removed needless imports. + + * pom.xml: xmllint-ed + +2009-09-29 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java (DATE_PATTERN) Edited: + Make the Constants assessible for other Parts of the Project to reduce the TouchPoints for + Dateformats. + +2009-09-24 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/ResultDescriptor.java Edited, + src/main/java/de/intevation/gnv/geobackend/base/Result.java Edited, + src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java Edited, + src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java Edited: + Make Classes Serializable for Storing in ArtifactDatabase + +2009-09-21 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java: + Added formatted Date Handling in getString Method + * src/test/ressources/QueryExecutorTestCase.properties Edited, + src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java Edited: + Some tests for Spatialqueries added + * src/main/java/de/intevation/gnv/geobackend/base/query/DefaultQueryExceutor.java Edited: + Put the final Querystring into a Logmessage + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java (getDate): + . Intance Check for DateValues + * src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java (next): + Logging removed because the performance slowdown fetching many ResultSets + +2009-09-04 Tim Englich + + * pom.xml: diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/Changes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/Changes Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,91 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for MultiLinestring and MultiPolygon detection retrieved by + the database. + + * Spatial queries using LineStrings can be sent to the database. + + * Sql-cache synchronization after database upates have taken place. A + thread is started in a specific time interval. Elements are removed + from cache if the sql-statement that has been used to retrieve these + elements contains a table that have been updated since the last + synchronization. The time interval (in seconds) can be configured via + system property 'caching.cleaner.interval' (e.g. + caching.cleaner.interval=600 for an interval of 10 minutes). + + Added: + + * JavaDoc documentation. + + +2010-03-08 RELEASE 0.5 + + +2010-01-27 RELEASE 0.4 + + New: + + * Experimental Cache for database queries and + results of parameterisation: Database queries are + transparent against cache. + + * Support for raster data access to SDE via RasterObject + + * Added interpolation for bilinear and bicubic + spline interpolation on rasters + + * Improved connection pooling for re-use of connections (#34) + + * Improved memory consumption of SQL results produced by SDE by + over 90% while removing redundancies for objects (especially + date objects): e.g. from 256 MB per Interpolation to 15 MB. (#107) + + +2009-12-17 RELEASE 0.3 + + New: + + * !!!! Java6 is mandatory now! Older version are not supported any longer !!! + * Added "point on polygon" spatial query support. + + Fixed: + + * Avoid index out of bounds exception in some case when accessing database + columns that are not provided by the database result set. + + +2009-11-13 RELEASE 0.2 + + New: + + * Added spatial query support for the first use cases. It uses OGC Simple Features for + SQL Syntax (SFS) to the inside and OGC WKT (Well Known Text) for + geometry respresentations + + * Enhanced configuration to ArcSDE Backend in Pool-Mechanism for + fine-tuning interaction and pooling. + + * Added support for INNERJOIN, ORDER BY and GROUP BY for spatial + queries (needs more testing) + + * Support for gaps in temporal and spatial data added. + + Improvements: + + * Improved memory handling of Backend-results in geo-backend + + * Stabilized binding to ArcSDE Backend (issue 34), + https://roundup-intern.intevation.de/gnv/issue34 + + + +2009-10-07 RELEASE 0.1 + + New: + + * Imported proto type database access layer. + * Made access layer look like java.sql.* + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/NEWS Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,66 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for MultiPolygons retrieved by database. + + * Support for MultiLinestrings retrieved by database. + + * Support for spatial queries using LineStrings. + + * Support for cache synchronization after database updates. + + + Added: + + * Added JavaDoc documentation. + + +2010-03-08 RELEASE 0.5 + + +2010-01-27 RELEASE 0.4 + + * Support for raster data access to SDE via RasterObject + + * Added interpolation for bilinear and bicubic + spline interpolation on rasters + + * Improved connection pooling for re-use of connections (#34) + + * Improved memory consumption of SQL results produced by SDE by + over 90% while removing redundancies for objects (especially + date objects): e.g. from 256 MB per Interpolation to 15 MB. (#107) + + * Experimental Cache for database queries and + results of parameterisation: Database queries are + transparent against cache. + Acceleration by at least factor 5-8 depending on circumstances. + + +2009-12-17 RELEASE 0.3 + + New: + + * !!!! Java6 is mandatory now! Older version are not supported any longer !!! + The backend now stubs the Java6 SQL API which is nor compability with + earlier versions. + +2009-11-13 RELEASE 0.2 + + New: + + * Added first support for spatial queries for time series, + vertical profile, horizontal profile, vertical cross section + and horizontal cross section. + + * Improved memory footprint of data objects in geo-backend. + + * Stabilized binding to ArcSDE datasources. + + +2009-10-07 RELEASE 0.1 + + New: + + * Initial version of the database access layer. diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/contrib/sql-cache.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/contrib/sql-cache.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,15 @@ + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/pom.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,93 @@ + + + 4.0.0 + de.intevation.bsh + geo-backend + jar + + 1.0-SNAPSHOT + geo-backend + http://maven.apache.org + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.5.1 + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.5 + 1.5 + + + + + + + junit + junit + 3.8.1 + test + + + com.esri.sde + jsde_sdk + 9.3 + compile + + + com.esri.sde + jpe_sdk + 9.3 + compile + + + com.esri.sde + jpe_sdkres + 9.3 + compile + + + com.ibm + icu4j + 3.2 + compile + + + log4j + log4j + 1.2.14 + + + commons-pool + commons-pool + 1.5.2 + + + org.apache.commons + commons-math + 2.0 + + + com.vividsolutions + jts + 1.9 + + + net.sf.ehcache + ehcache + 1.6.2 + + + + + gt2.repo + GeoTools2 Repository including JTS + http://maven.geotools.fr/repository + + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/DefaultResult.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,157 @@ +package de.intevation.gnv.geobackend.base; + +import java.util.Date; +import java.util.GregorianCalendar; + +import de.intevation.gnv.geobackend.util.DateUtils; + +/** + * Defaultimplementation of the Interface Result. + * This Class stores the Attributevalues of one Result. + * @author Tim Englich + * + */ +public class DefaultResult +implements Result +{ + /** + * THE UID of this Classe + */ + private static final long serialVersionUID = -6886218808840982766L; + /** + * Array which stores the Columnvalues + */ + private Object [] values; + /** + * The ResultDescriptor which describes the ColumnValues + */ + private ResultDescriptor resultDescriptor = null; + + /** + * Constructor + */ + public DefaultResult(ResultDescriptor resultDescriptor) { + this.resultDescriptor = resultDescriptor; + values = new Object[resultDescriptor.getColumnCount()]; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getDate(java.lang.String) + */ + public Date getDate(String columnName) { + return getDate(resultDescriptor.getColumnIndex(columnName)); + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getDate(int) + */ + public Date getDate(int column) { + Object o = values[column]; + Date d = null; + if(o instanceof Date){ + d = (Date)o; + }else if (o instanceof GregorianCalendar){ + d = ((GregorianCalendar)o).getTime(); + } + return d; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getDouble(java.lang.String) + */ + public Double getDouble(String columnName) { + return getDouble(resultDescriptor.getColumnIndex(columnName)); + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getDouble(int) + */ + public Double getDouble(int column) { + return (Double)values[column]; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getFloat(java.lang.String) + */ + public Float getFloat(String columnName) { + return getFloat(resultDescriptor.getColumnIndex(columnName)); + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getFloat(int) + */ + public Float getFloat(int column) { + return (Float)values[column]; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getInteger(java.lang.String) + */ + public Integer getInteger(String columnName) { + int idx = resultDescriptor.getColumnIndex(columnName); + return idx > -1 ? getInteger(idx) : -1; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getInteger(int) + */ + public Integer getInteger(int column) { + Object value = values[column]; + if (value instanceof Double){ + value = new Integer(((Double)value).intValue()); + } + return (Integer)value; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getResultDescriptor() + */ + public ResultDescriptor getResultDescriptor() { + return this.resultDescriptor; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getString(java.lang.String) + */ + public String getString(String columnName) { + int idx = resultDescriptor.getColumnIndex(columnName); + return idx > -1 ? getString(idx) : null; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getString(int) + */ + public String getString(int column) { + Object o = values[column]; + if (o instanceof Date){ + return DateUtils.getPatternedDateAmer((Date)o); + } + if (o instanceof GregorianCalendar){ + Date d = ((GregorianCalendar)o).getTime(); + return DateUtils.getPatternedDateAmer(d); + } + return o != null ? o.toString() : null; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#addColumnValue(int, java.lang.Object) + */ + public void addColumnValue(int column, Object value) { + values[column] = value; + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getObject(java.lang.String) + */ + public Object getObject(String columnName) { + return getObject(resultDescriptor.getColumnIndex(columnName)); + } + + /** + * @see de.intevation.gnv.geobackend.base.Result#getObject(int) + */ + public Object getObject(int column) { + return values[column]; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/DefaultResultDescriptor.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,111 @@ +package de.intevation.gnv.geobackend.base; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This Class is the DefaultImplementation of the + * Interface ResultDescriptor + * @author Tim Englich + * + */ +public class DefaultResultDescriptor implements ResultDescriptor { + + /** + *The Uid of this Class + */ + private static final long serialVersionUID = 7016889733270716130L; + /** + * The Names of the Columns of one Result + */ + private List columnNames = new ArrayList(); + /** + * The Name of the Classes of the Values of one Result. + */ + private List columnClassNames = new ArrayList(); + /** + * The Lookup for the Columnindex of the Columnnames + */ + private Map columnIndexLookup = new HashMap(); + + /** + * Constructor + */ + public DefaultResultDescriptor() { + super(); + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#getColumnClassName(int) + */ + public String getColumnClassName(int column) { + return this.columnClassNames.get(column); + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#getColumnCount() + */ + public int getColumnCount() { + return this.columnClassNames.size(); + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#getColumnName(int) + */ + public String getColumnName(int column) { + return this.columnNames.get(column); + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#addColumn(java.lang.String, java.lang.String) + */ + public void addColumn(String name, String className) { + this.columnClassNames.add(className); + this.columnNames.add(name); + this.columnIndexLookup.put(name,this.columnNames.size()-1); + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#getColumnIndices(java.lang.String[]) + */ + public int [] getColumnIndices(String [] columnNames) { + if (columnNames == null) { + return null; + } + int [] indices = new int[columnNames.length]; + for (int i = 0; i < indices.length; ++i) { + indices[i] = this.getColumnIndex(columnNames[i]); + } + return indices; + } + + /** + * @see de.intevation.gnv.geobackend.base.ResultDescriptor#getColumnIndex(java.lang.String) + */ + public int getColumnIndex(String columnName) { + + Integer value = this.columnIndexLookup.get(columnName); + return value != null ? value.intValue() : -1; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + int N = Math.min(columnNames.size(), columnClassNames.size()); + for (int i = 0; i < N; ++i) { + if (i > 0) { + sb.append(", "); + } + sb.append(columnNames.get(i)) + .append(": ") + .append(columnClassNames.get(i)); + } + sb.append(']'); + return sb.toString(); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/Result.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/Result.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,111 @@ +package de.intevation.gnv.geobackend.base; + +import java.io.Serializable; +import java.util.Date; + +/** + * Interface which provides the Methods for Accessing + * the Data of an ResultEntry + * @author Tim Englich + * + */ +public interface Result extends Serializable{ + + /** + * Returns the ResultDescriptor which provides the + * ResultMetadatse + * @return the ResultDescriptor + */ + public ResultDescriptor getResultDescriptor(); + + /** + * Returns the Columnvalue as a String + * @param columnName the Name of the column + * @return the Columnvalue as a String + */ + public String getString(String columnName); + + /** + * Returns the Columnvalue as a String + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a String + */ + public String getString(int column); + + /** + * Returns the Columnvalue as a Date + * @param columnName the Name of the column + * @return the Columnvalue as a Date + */ + public Date getDate(String columnName); + + /** + * Returns the Columnvalue as a Date + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a Date + */ + public Date getDate(int column); + + /** + * Returns the Columnvalue as a Integer + * @param columnName the Name of the column + * @return the Columnvalue as a Integer + */ + public Integer getInteger(String columnName); + + /** + * Returns the Columnvalue as a Integer + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a Integer + */ + public Integer getInteger(int column); + + /** + * Returns the Columnvalue as a Float + * @param columnName the Name of the column + * @return the Columnvalue as a Float + */ + public Float getFloat(String columnName); + + /** + * Returns the Columnvalue as a Float + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a Float + */ + public Float getFloat(int column); + + /** + * Returns the Columnvalue as a Double + * @param columnName the Name of the column + * @return the Columnvalue as a Double + */ + public Double getDouble(String columnName); + + /** + * Returns the Columnvalue as a Double + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a Double + */ + public Double getDouble(int column); + + /** + * Returns the Columnvalue as a Object + * @param columnName the Name of the column + * @return the Columnvalue as a Object + */ + public Object getObject(String columnName); + + /** + * Returns the Columnvalue as a Object + * @param column the Position of the Column that should be returned. + * @return the Columnvalue as a Object + */ + public Object getObject(int column); + + /** + * Adds an new Columnvalue to the Result. + * @param column the Position where the column should be inserted. + * @param value the Value of the Column + */ + public void addColumnValue(int column, Object value); +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/ResultDescriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/ResultDescriptor.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.gnv.geobackend.base; + +import java.io.Serializable; + +/** + * Interface which provides the Methods for Accessing + * the MetaData of an ResultEntry + * @author Tim Englich + */ +public interface ResultDescriptor extends Serializable{ + + /** + * Returns the Classname of the Column + * @param column the id of the Column which is requested + * @return the Classname of the Column + */ + public String getColumnClassName(int column); + + /** + * Returns the Number of Columns + * @return the Number of Columns + */ + public int getColumnCount(); + + /** + * Returns the Name of the Column which belongs to the given Columnindex + * @param column the Index of the Column + * @return the Name of the Column + */ + public String getColumnName(int column); + + /** + * Adds a new ColumnDescription into the Descriptor + * @param name the Name of the Column (unique) + * @param className the Name of the Class (e.g. Double, Integer + */ + public void addColumn(String name, String className); + + /** + * Returns the Indices of the Columns which are specified in the + * param columnNames. + * @param columnNames the Name of the Columns for which the Indices should returned. + * @return the Indices of the Columns which are specified in the + * param columnNames. + */ + public int [] getColumnIndices(String [] columnNames); + + /** + * Returns the index of the given columnName + * @param columnName the Name of the Index which should be looked up. + * @return the index of the given columnName + */ + public int getColumnIndex(String columnName); +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPool.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.gnv.geobackend.base.connectionpool; + +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; + +import java.sql.Connection; + +import java.util.Properties; + +/** + * Interfacedefinition for an Generic ConnectionPool + * @author Tim Englich + */ +public interface ConnectionPool { + + /** + * Delivers the Connection to the Database + * @param connectionID the ID of the Connection + * @return the Connection to the Database + * @throws ConnectionException + */ + public Connection getConnection(String connectionID) throws ConnectionException; + + /** + * Returns the Connection to the Pool + * @param connection the Connection which should be returned to the Pool + * @throws ConnectionException + */ + public void closeConnection(Connection connection) throws ConnectionException; + + /** + * Initializes the ConnectionPool + * @param properties The Properties which should be used for initializing theConnectionPool + */ + public void initialize(Properties properties); + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPoolFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/ConnectionPoolFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,81 @@ +package de.intevation.gnv.geobackend.base.connectionpool; + +import de.intevation.gnv.geobackend.sde.connectionpool.ArcSDEConnectionPool; + +import java.util.Properties; + +import org.apache.log4j.Logger; + +/** + * Factoryimplementation for the Interface ConnectionPool. + * This factory delivers Instances of the Interface ConnectionPool. + * @author Tim Englich + */ +public class ConnectionPoolFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ConnectionPoolFactory.class); + + + /** + * The singleton Instance of this Factory. + */ + private static ConnectionPoolFactory instance = null; + + /** + * The ConnectionPool providing the Connections to the DatabaseBackends + */ + private ConnectionPool connectionPool = null; + + /** + * Basic-Constructor of this Class + */ + private ConnectionPoolFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * @return an singleton Instance of this Class + */ + public static ConnectionPoolFactory getInstance(){ + if (instance == null){ + instance = new ConnectionPoolFactory(); + } + return instance; + } + + /** + * Getting the ConnectionPool + * @return the ConnectionPool + */ + public ConnectionPool getConnectionPool(){ + return this.connectionPool; + } + + /** + * Initializes the ConnectionPool. + * Should only be called once on system startup + * @param properties the Properties for the Individual Configuration of the ConnectionPool + */ + public void initializeConnectionPool(Properties properties){ + log.debug("ConnectionPoolFactory.initializeConnectionPool"); + if (this.connectionPool == null){ + //TODO: Here it might be possible to switch the ConnectionPoolInstance using a FLAG. + this.connectionPool = new ArcSDEConnectionPool(); + this.connectionPool.initialize(properties); + }else{ + log.warn("ConnectionPool already initialized"); + } + } + + /** + * Checks if the ConnectionPool has already been initialized. + * @return true if the ConnectionPool is initialized. + */ + public boolean isInitialized(){ + return this.connectionPool != null; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/ConnectionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/ConnectionException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.gnv.geobackend.base.connectionpool.exception; + +import com.esri.sde.sdk.client.SeError; +import com.esri.sde.sdk.client.SeException; + +import de.intevation.gnv.geobackend.sde.datasources.exception.TechnicalException; + +import org.apache.log4j.Logger; + +/** + * The class lConnectionException fulfills the following purposes: + * + * @author blume + * @author Tim Englich + */ +public class ConnectionException extends TechnicalException { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 102459262123219617L; + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(ConnectionException.class); + + /** + * Constructs a new exception with null as its detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + */ + public ConnectionException() { + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public ConnectionException(String message) { + super(message); + } + + /** + * Constructor + * @param pCause the Throwable which cause this exception + */ + public ConnectionException(Throwable pCause) { + super(pCause); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * cause is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public ConnectionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Displays the details of an SeException (if available). + * + */ + public void printError() { + if (getCause() != null && getCause() instanceof SeException) { + SeException exception = (SeException) getCause(); + SeError error = exception.getSeError(); + + sLogger.debug("\n ArcSDE Error Number : " + error.getSdeError()); + sLogger.debug(" Error Description : " + error.getErrDesc()); + + int extError = error.getExtError(); + if (extError != 0) + sLogger.debug(" Extended Error Number : " + extError); + + String desc = error.getSdeErrMsg(); + if (desc != null && desc.length() != 0) + sLogger.debug(" Extended Error Description : " + desc); + + desc = error.getExtErrMsg(); + if (desc != null && desc.length() != 0) + sLogger.debug(" Extended Error Description : " + desc); + + sLogger.debug(exception); + + } + + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Package that contains Exceptionclasses for it's Parentpackage. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/connectionpool/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains Classes that provides an ConnectionPool +for java.sql.Connection-Objects + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains Interfaces and Classes to provide Access to Data without +using an java.sql.ResultSet-object in the Code that use this Module. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,88 @@ +package de.intevation.gnv.geobackend.base.query; + +import java.util.Collection; +import java.util.Iterator; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; + +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.cache.CacheCleaner; + +/** + * @author Sascha L. Teichmann + */ +public class CachingQueryExecutorFactory +extends QueryExecutorFactory +{ + public static final String QUERY_EXECUTOR_FACTORY = "caching.query.executor.config"; + public static final String CACHE_NAME = "sql.cache"; + + private static Logger log = Logger.getLogger(CachingQueryExecutorFactory.class); + + protected CacheManager manager; + + public CachingQueryExecutorFactory() { + log.info("using SQL cache"); + String configFile = System.getProperty(QUERY_EXECUTOR_FACTORY); + manager = configFile != null + ? new CacheManager(configFile) + : new CacheManager(); + manager.addCache(CACHE_NAME); + CacheCleaner cc = new CacheCleaner(); + cc.start(); + } + + public QueryExecutor getQueryExecutor() { + return new DefaultQueryExceutor() { + + public Collection cachedResults(String query) { + Cache cache = manager.getCache(CACHE_NAME); + Element element = cache.get(query); + if (log.isDebugEnabled()) { + log.debug("found results in SQL cache: " + (element != null)); + } + return element != null + ? (Collection)element.getObjectValue() + : null; + } + + public void cacheResults(String query, Collection results) { + log.debug("store results in SQL cache"); + Cache cache = manager.getCache(CACHE_NAME); + cache.put(new Element(query, results)); + } + + public void clearCache(String[] tableNames) { + Cache cache = manager.getCache(CACHE_NAME); + Iterator keys = cache.getKeys().iterator(); + while (keys.hasNext()){ + String origKey = (String)keys.next(); + String key = origKey.toUpperCase(); + log.debug(key); + for (int i = 0; i < tableNames.length; i++){ + if (key.contains(tableNames[i])){ + log.debug(tableNames[i]+ " is contained in "+key); + log.debug("Cacheentry will be removed"); + boolean success = cache.remove(origKey); + if (!success){ + log.warn("Object could not be reoved from Cache."); + } + break; + } + } + } + } + }; + } + + public void shutdown() { + log.info("shutting down SQL cache"); + manager.getCache(CACHE_NAME).flush(); + manager.shutdown(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/DefaultQueryExceutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/DefaultQueryExceutor.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.gnv.geobackend.base.query; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool; +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; + +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; + +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import java.util.Collection; + +import org.apache.log4j.Logger; + +/** + * This is an Standard Implementation of the Interface QueryExecutor. + * It fetchs the Query from the Querycontainer an put the Filtervalues into the Query. + * @author Tim Englich + * + */ +public class DefaultQueryExceutor extends QueryExecutorBase{ + + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(DefaultQueryExceutor.class); + + /** + * The ConnectionID identifing the Connection to use executing the Query. + */ + private String connectionID = "N/N"; + + /** + * Constructor + */ + public DefaultQueryExceutor() { + super(); + } + + /** + * @see de.intevation.gnv.geobackend.base.query.QueryExecutor#executeQuery(java.lang.String, java.lang.String[]) + */ + public Collection executeQuery(String queryID, String[] filter) throws QueryException { + Collection returnValue = null; + try { + String queryString = QueryContainerFactory.getInstance().getQueryContainer().getQuery(queryID); + if (queryString != null){ + if (filter != null && filter.length > 0){ + //Insert the Filtervalues into the QueryString + queryString = super.setFilterValues(queryString, filter); + } + + if (log.isDebugEnabled()) { + log.debug("############ QUERY ##################"); + log.debug(queryString); + log.debug("#######################################"); + } + + returnValue = cachedResults(queryString); + + if (returnValue != null) { + return returnValue; + } + + Connection connection = null; + ConnectionPool connectionPool = ConnectionPoolFactory.getInstance().getConnectionPool(); + try { + // Submit the Query + connection = connectionPool.getConnection(this.connectionID); + if (connection != null){ + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery(queryString); + returnValue = super.createResultCollection(rs); + + }else{ + log.error("Could not establish Databaseconnection."); + throw new QueryException("Could not establish Databaseconnection."); + } + + cacheResults(queryString, returnValue); + + } catch (ConnectionException e) { + log.error(e,e); + throw new QueryException("Could not establish Databaseconnection.",e); + } catch (SQLException e) { + log.error(e,e); + throw new QueryException(e); + }finally{ + if (connection != null){ + try { + connectionPool.closeConnection(connection); + } catch (ConnectionException e) { + log.error("Connection could not be returned to ConnectionPool."); + log.error(e,e); + } + } + } + }else{ + log.error("No QueryString defined for "+queryID); + throw new QueryException("Cannot get the Querystring"); + } + + } catch (QueryContainerException e) { + log.error(e,e); + throw new QueryException("Cannot get the Querystring",e); + } + + return returnValue; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutor.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.geobackend.base.query; + +import java.util.Collection; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +/** + * This Interface provides the Method to execute Queries + * against a Datastore eg. Databases + * @author Tim Englich + * + */ +public interface QueryExecutor { + + + /** + * This Method executes the Query an returns the Result + * in an Collection. + * @param queryID the ID of the Query which should be used. + * @param filter the Filterarguments to limit the Data + * @return the fetched Values + * @throws QueryException + */ + Collection executeQuery(String queryID, + String[] filter) + throws QueryException; + + /** + * Returns the cached results to a given Query. + * @param query the Query that should identify the Result + * @return the Cached results or null if no results are cached. + */ + Collection cachedResults(String query); + + /** + * Writes the Result into the Cache + * @param query the Query that will be used as Identifier. + * @param results The Results that should be cached. + */ + void cacheResults(String query, Collection results); + + /** + * Clears the Cache using the Names of the Database-Tables + * @param tableNames the Tablenames that should be used to Clear the Cache. + */ + void clearCache(String[] tableNames); +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,104 @@ +package de.intevation.gnv.geobackend.base.query; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.intevation.gnv.geobackend.base.DefaultResult; +import de.intevation.gnv.geobackend.base.DefaultResultDescriptor; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +/** + * This is an abstract Basicimplementation of the Interface + * QueryExecutor providing several Helpermethods. + * @author Tim Englich + * + */ +public abstract class QueryExecutorBase implements QueryExecutor { + + /** + * Constructor + */ + public QueryExecutorBase() { + super(); + } + + /** + * This Method puts the Filtervalues into the Querystring + * @param queryString the Query which should be manipulated + * @param filter the values which should be put into the Query + * @return the manipulated Query + */ + protected String setFilterValues(String queryString, String[] filter){ + String returnValue = queryString; + for (int i = 0; i < filter.length; i++){ + returnValue = returnValue.replaceFirst("[?]", filter[i]); + } + return returnValue; + } + + /** + * This Methods converts the ResultSet into an Collection of Result-objects + * @param resultSet the ResultSet which should be converted + * @return an Collection containing Result-Objects + * @throws SQLException + */ + protected Collection createResultCollection(ResultSet resultSet) throws SQLException{ + Collection returnValue = new ArrayList(); + + ResultDescriptor resultDescriptor = null; + int columns = -1; + + List columnNames = null; + + while (resultSet.next()){ + if (resultDescriptor == null){ + resultDescriptor = new DefaultResultDescriptor(); + ResultSetMetaData rsmd = resultSet.getMetaData(); + columns = rsmd.getColumnCount(); + + for (int i = 1; i <= columns; i++){ + resultDescriptor.addColumn(rsmd.getColumnName(i), rsmd.getColumnClassName(i)); + } + } + + Result result = convertResult(resultSet, resultDescriptor); + + returnValue.add(result); + } + return returnValue; + } + + /** + * This Method converts one Singel ResultSetEntry into an Result-Object + * @param resultSet the ResultSet where the Entry should be took from. + * @param resultDescriptor the ResultsetDescriptor which describes the Entry + * @return an new Result-Objects containing the Values of the ResultSet-Entry + * @throws SQLException + */ + private Result convertResult(ResultSet resultSet, ResultDescriptor resultDescriptor) + throws SQLException { + + Result result = new DefaultResult(resultDescriptor); + + for (int i = 0, N = resultDescriptor.getColumnCount(); i < N; i++) { + result.addColumnValue(i, resultSet.getObject(i+1)); + } + return result; + } + + public Collection cachedResults(String query) { + return null; + } + + public void cacheResults(String query, Collection result) { + } + + public void clearCache(String[] tableNames) { + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,80 @@ +package de.intevation.gnv.geobackend.base.query; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class QueryExecutorFactory { + + public static final String QUERY_EXECUTOR_FACTORY = "query.executor.factory"; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(QueryExecutorFactory.class); + + + /** + * The singleton Instance of this Factory. + */ + private static QueryExecutorFactory instance = null; + + /** + * Basic-Constructor of this Class + */ + public QueryExecutorFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * @return an singleton Instance of this Class + */ + public static synchronized QueryExecutorFactory getInstance(){ + if (instance == null) { + String className = System.getProperty(QUERY_EXECUTOR_FACTORY); + if (className != null) { + try { + Class clazz = Class.forName(className); + final QueryExecutorFactory factory = + (QueryExecutorFactory)clazz.newInstance(); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + factory.shutdown(); + } + }); + return instance = factory; + } + catch (ClassNotFoundException cnfe) { + log.error(cnfe); + } + catch (InstantiationException ie) { + log.error(ie); + } + catch(IllegalAccessException iae) { + log.error(iae); + } + catch (ClassCastException cce) { + log.error(cce); + } + } + + instance = new QueryExecutorFactory(); + } + return instance; + } + + public void shutdown() { + } + + /** + * Getting the QueryExecutor + * @return the QueryExecutor + */ + public QueryExecutor getQueryExecutor(){ + return new DefaultQueryExceutor(); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleaner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleaner.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,229 @@ +/** + * + */ +package de.intevation.gnv.geobackend.base.query.cache; + +import java.sql.Date; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.DefaultQueryExceutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.geobackend.util.DateUtils; + +/** + * Thread that looks every n - Minutes if an Cache has to be cleanedup. + * You can configure the Timeout in Seconds using the Systemproperty + * @author Tim Englich + * + */ +public class CacheCleaner extends Thread { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(CacheCleaner.class); + + /** + * The Systemproperty-identifier for the Configuration of the TimeInterval + */ + public static final String CACHE_CLEANER_INTERVAL = "caching.cleaner.interval"; + + /** + * The Time To wait between two Cleanups. + */ + private long timeout = 1000 * 60; // 1 Minute + + /** + * The Border which has to be used to Query the updated Tables. + */ + private long lowerBorderTime = 0; + + /** + * The Id to Lookup the SQL-Statement for fetchung the Names of the + * updated Tables. + */ + private String queryID = "updated_tables"; + + /** + * Constructor + */ + public CacheCleaner() { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + */ + public CacheCleaner(Runnable arg0) { + super(arg0); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + */ + public CacheCleaner(String arg0) { + super(arg0); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public CacheCleaner(ThreadGroup arg0, Runnable arg1) { + super(arg0, arg1); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public CacheCleaner(ThreadGroup arg0, String arg1) { + super(arg0, arg1); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public CacheCleaner(Runnable arg0, String arg1) { + super(arg0, arg1); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + * @param arg2 + */ + public CacheCleaner(ThreadGroup arg0, Runnable arg1, String arg2) { + super(arg0, arg1, arg2); + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + * @param arg2 + * @param arg3 + */ + public CacheCleaner(ThreadGroup arg0, Runnable arg1, String arg2, long arg3) { + super(arg0, arg1, arg2, arg3); + this.setUp(); + } + + /** + * Sets up the members of the CacheCleaner. + */ + protected void setUp(){ + String intervalValue = System.getProperty(CACHE_CLEANER_INTERVAL); + if (intervalValue != null){ + log.info("Set Interval to "+intervalValue+" Seconds"); + try { + this.timeout = Long.parseLong(intervalValue) * 1000; + } catch (NumberFormatException e) { + log.error(e,e); + } + } + } + + /** + * This Method can be used do run the Main-Mechanism of the Thread e.g + * from a Unittest. + * @return + */ + public boolean test(){ + log.debug("CacheCleaner.test"); + this.cleanup(); + return true; + } + + @Override + public void run() { + log.debug("CacheCleaner.run"); + long requiredTime = 0; + this.lowerBorderTime = System.currentTimeMillis(); + while (true){ + long startTime = 0; + try { + long nextTimeout = timeout-requiredTime; + if (nextTimeout > 0){ + Thread.sleep(nextTimeout); + } + startTime = System.currentTimeMillis(); + log.debug("Sleep "+nextTimeout+"ms cleanup Cache now"); + this.cleanup(); + } catch (InterruptedException e) { + log.error(e,e); + } catch (Exception e){ + log.error(e,e); + } catch (Throwable t){ + log.error(t,t); + }finally{ + requiredTime = System.currentTimeMillis() - startTime; + log.debug("CleanUp required "+requiredTime); + } + } + } + + /** + * Method that do the Cleanup-Work + */ + protected void cleanup(){ + log.debug("CacheCleaner.cleanup"); + try { + // We have to go this Way to avoid using the Cache for this Query. + String[] tableNames = this.getUpdatedTableNames(); + if (tableNames != null){ + QueryExecutorFactory.getInstance() + .getQueryExecutor().clearCache(tableNames); + } + } catch (QueryException e) { + log.error(e,e); + } + + } + + /** + * Returns the Names of the Tables which have been updated. + * @return the Names of the Tables which have been updated. + * @throws QueryException + */ + protected String[] getUpdatedTableNames()throws QueryException { + String[] tableNames = null; + QueryExecutor queryExecutor = new DefaultQueryExceutor(); + Date date = new Date(this.lowerBorderTime); + this.lowerBorderTime = System.currentTimeMillis(); + log.debug("New Lookup at "+DateUtils.getPatternedDateAmer(new Date(lowerBorderTime))); + String queryDate = DateUtils.getPatternedDateAmer(date); + Collection result = queryExecutor. + executeQuery(queryID, + new String[]{queryDate}); + if (result != null && !result.isEmpty()){ + tableNames = new String[result.size()]; + Iterator it = result.iterator(); + int i = 0; + while (it.hasNext()){ + tableNames[i++] = it.next().getString(0).toUpperCase(); + log.debug("Table that was updated: "+tableNames[i-1]); + } + } + return tableNames; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/cache/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/cache/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains the CacheCleaner. An Thread that is responsible to +Cleanup the SQL-Cache if the Data in the Database has been updated. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/DefaultQueryContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/DefaultQueryContainer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,44 @@ +package de.intevation.gnv.geobackend.base.query.container; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +import java.util.Properties; + +/** + * Defaultimplementation of an QueryContainer. + * All Queries are provided using a Propertiescontainer. + * @author Tim Englich + */ +public class DefaultQueryContainer implements QueryContainer { + + /** + * The Properties-Object all Queries are provided in. + */ + private Properties queries = null; + + /** + * Constructor + */ + public DefaultQueryContainer() { + super(); + } + + /** + * @see de.intevation.gnv.geobackend.base.query.container.QueryContainer#getQuery(java.lang.String) + */ + public String getQuery(String queryID) throws QueryContainerException { + String returnValue = null; + if (this.queries != null){ + returnValue = this.queries.getProperty(queryID); + } + return returnValue; + } + + /** + * @see de.intevation.gnv.geobackend.base.query.container.QueryContainer#initialize(java.util.Properties) + */ + public void initialize(Properties properties) throws QueryContainerException { + this.queries = properties; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.gnv.geobackend.base.query.container; + +import java.util.Properties; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +/** + * Querycontainer is an Interface which defines the Method that are + * required to provide the access to SQL-Queries. + * @author Tim Englich + * + */ +public interface QueryContainer { + + + /** + * Returns the Query specified by the given queryID. + * @param queryID the ID which speciogies the Query which should be returned + * @return the Query + * @throws QueryContainerException + */ + public String getQuery(String queryID) throws QueryContainerException; + + /** + * Initializes the QueryContainer + * @param properties The Properties which should be used for initializing QueryContainer + * @throws QueryContainerException + */ + public void initialize(Properties properties) throws QueryContainerException; +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/QueryContainerFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +package de.intevation.gnv.geobackend.base.query.container; + +import java.util.Properties; + +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +/** + * Factoryclass to provide a singleton-Instance of an + * QueryContainer-Object + * @author Tim Englich + */ +public class QueryContainerFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(QueryContainerFactory.class); + + + /** + * The singleton Instance of this Factory. + */ + private static QueryContainerFactory instance = null; + + /** + * The ConnectionPool providing the Connections to the DatabaseBackends + */ + private QueryContainer queryContainer = null; + + /** + * Basic-Constructor of this Class + */ + private QueryContainerFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * @return an singleton Instance of this Class + */ + public static synchronized QueryContainerFactory getInstance(){ + if (instance == null){ + instance = new QueryContainerFactory(); + } + return instance; + } + + + /** + * Getting the QueryContainer + * @return the QueryContainer + */ + public QueryContainer getQueryContainer(){ + return this.queryContainer; + } + + /** + * Initializes the QueryContainer. + * Should only be called once on system startup + * @param properties the Properties for the Individual Configuration of the QueryContainerbb + * @throws QueryContainerException + */ + public synchronized void initializeQueryContainer(Properties properties) throws QueryContainerException{ + log.debug("ConnectionPoolFactory.initializeConnectionPool"); + if (this.queryContainer == null){ + this.queryContainer = new DefaultQueryContainer(); + this.queryContainer.initialize(properties); + }else{ + log.warn("ConnectionPool already initialized"); + } + } + + /** + * Checks if the QueryContainer has already been initialized. + * @return true if the QueryContainer is initialized. + */ + public boolean isInitialized(){ + return this.queryContainer != null; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/exception/QueryContainerException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/exception/QueryContainerException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.geobackend.base.query.container.exception; + +/** + * Exceptioncalls which will be used to retun Exception in + * the QuerContainer-Package. + * @author Tim Englich + * + */ +public class QueryContainerException extends Exception { + + /** + * The UID auf this Class + */ + private static final long serialVersionUID = -1811252311941938708L; + + /** + * Constructor + */ + public QueryContainerException() { + } + + /** + * Constructor + * @param arg0 + */ + public QueryContainerException(String arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + */ + public QueryContainerException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public QueryContainerException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Package that contains Exceptionclasses for it's Parentpackage. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/container/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains Classes which provide the Access to SQL-Queries which +are stored in an separate Resource-File (e.g. an Propertiesfile). + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/exception/QueryException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/exception/QueryException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.geobackend.base.query.exception; + +/** + * This is a specialized Exceptionclass for Exceptions that occurse during + * querying Data from the Database- + * @author Tim Englich + * + */ +public class QueryException extends Exception { + + /** + * The UID for this Class + */ + private static final long serialVersionUID = -1337567603858112424L; + + /** + * Constructor + */ + public QueryException() { + } + + /** + * Constructor + * @param message + */ + public QueryException(String message) { + super(message); + } + + /** + * Constructor + * @param cause + */ + public QueryException(Throwable cause) { + super(cause); + } + + /** + * Constructor + * @param message + * @param cause + */ + public QueryException(String message, Throwable cause) { + super(message, cause); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Package that contains Exceptionclasses for it's Parentpackage. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains Interfaces and Classes which provide the possibility to +send a SQL-Query against a Databasebackend and get the returned Rows as Result. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEConnectionPool.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,124 @@ +package de.intevation.gnv.geobackend.sde.connectionpool; + +import java.sql.Connection; +import java.util.Properties; + +import org.apache.commons.pool.PoolableObjectFactory; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool; +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; + +/** + *This is the ArcSDE specific implementation of the Interface ConnectionPool + * + * @author Tim Englich + */ +public class ArcSDEConnectionPool implements ConnectionPool { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(ArcSDEPoolableObjectFactory.class); + + /** + * The Pool which stores the Connections to the ArcSDE Backend + */ + private GenericObjectPool pool = null; + + /** + * @see de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool#closeConnection(java.sql.Connection) + */ + public void closeConnection(Connection connection) + throws ConnectionException { + try { + this.pool.returnObject(connection); + } catch (Exception e) { + log.error(e, e); + throw new ConnectionException(e); + } + + } + + /** + * @see de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool#getConnection(java.lang.String) + */ + public synchronized Connection getConnection(String connectionID) + throws ConnectionException { + try { + Object object = this.pool.borrowObject(); + + if (object instanceof Connection) { + return (Connection) object; + } else { + throw new ConnectionException( + "Created Object is not an java.sql.Connection"); + } + + } catch (Exception e) { + log.error(e, e); + throw new ConnectionException(e); + } + } + + /** + * @see de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool#initialize(java.util.Properties) + */ + public void initialize(Properties properties) { + log.info("ArcSDEConnectionPool.initialize has been called"); + log.info("ConnectionPool will be initialized"); + + PoolableObjectFactory poolableObjectFactory = new ArcSDEPoolableObjectFactory( + properties); + + int maxActive = Integer.parseInt(properties.getProperty("maxActive", + "10")); + long maxWait = Long.parseLong(properties.getProperty("maxWait", + "" + GenericObjectPool.DEFAULT_MAX_WAIT)); + int maxIdle = Integer.parseInt(properties.getProperty("maxIdle", + "" + GenericObjectPool.DEFAULT_MAX_IDLE)); + int minIdle = Integer.parseInt(properties.getProperty("minIdle", + "" + GenericObjectPool.DEFAULT_MIN_IDLE)); + boolean testOnBorrow = Boolean.parseBoolean(properties.getProperty( + "testOnBorrow", "" + GenericObjectPool.DEFAULT_TEST_ON_BORROW)); + boolean testOnReturn = Boolean.parseBoolean(properties.getProperty( + "testOnReturn", "" + GenericObjectPool.DEFAULT_TEST_ON_RETURN)); + long timeBetweenEvictionRunsMillis = Long + .parseLong(properties + .getProperty( + "timeBetweenEvictionRunsMillis", + "" + + GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS)); + int numTestsPerEvictionRun = Integer.parseInt(properties.getProperty( + "numTestsPerEvictionRun", + "" + GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN)); + long minEvictableIdleTimeMillis = Long + .parseLong(properties + .getProperty( + "minEvictableIdleTimeMillis", + "" + + GenericObjectPool.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS)); + boolean testWhileIdle = Boolean.parseBoolean(properties + .getProperty("testWhileIdle", + "" + GenericObjectPool.DEFAULT_TEST_WHILE_IDLE)); + + log.info("Maximum Number of active Connections: " + maxActive); + log.info("Maximum Number of waiting: " + maxWait); + log.info("Maximum Number of idle: " + maxIdle); + log.info("Minimum Number of idle: " + minIdle); + log.info("TestOnBorrow: " + testOnBorrow); + log.info("TestOnReturn: " + testOnReturn); + log.info("TimeBetweenEvictionRunsMillis: " + timeBetweenEvictionRunsMillis); + log.info("NumTestsPerEvictionRun: " + numTestsPerEvictionRun); + log.info("MinEvictableIdleTimeMillis: " + minEvictableIdleTimeMillis); + log.info("TestWhileIdle: " + testWhileIdle); + + this.pool = new GenericObjectPool(poolableObjectFactory, maxActive, + GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, maxWait, + maxIdle, minIdle, testOnBorrow, testOnReturn, + timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, + minEvictableIdleTimeMillis, testWhileIdle); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/ArcSDEPoolableObjectFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,204 @@ +package de.intevation.gnv.geobackend.sde.connectionpool; + +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; + +import de.intevation.gnv.geobackend.sde.datasources.ArcSDEConnection; + +import java.sql.Connection; +import java.sql.SQLException; + +import java.util.Properties; + +import org.apache.commons.pool.PoolableObjectFactory; + +import org.apache.log4j.Logger; + +/** + * ArcSDE specific Implementation of an PoolableObjectFactory. + * This factory instantiate Objects of type ArcSDEConnection. + * + * @author Tim Englich + * @author Sascha L. Teichmann + */ +public class ArcSDEPoolableObjectFactory implements PoolableObjectFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger( + ArcSDEPoolableObjectFactory.class); + + /** + * The 5 seconds are inspired by GeoTools's testServer() usage. + */ + private int serverRoundtripInterval = 5; + /** + * The value of the maximum Time a Connection is allowed to + * be inactive without the validation of the Connection. + */ + private long serverInactiveInterval = 5L*60L*1000L; // 5 minutes + /** + * The URL to the ArcSDE Server + */ + private String server = null; + /** + * The Port the ArcSDE Server is connected to. + */ + private String port = null; + /** + * The Name of the Database + */ + private String database = null; + /** + * The Username for the Authentication + */ + private String username = null; + /** + * The Credentials which belongs to the User + */ + private String credentials = null; + + /** + * Constructor of this Class + * @param properties the Properties which includes the ConnectionParams to the Database + */ + public ArcSDEPoolableObjectFactory(Properties properties) { + + log.debug("ArcSDEPoolableObjectFactory.Constructor"); + + server = properties.getProperty("server"); + port = properties.getProperty("port"); + database = properties.getProperty("database"); + username = properties.getProperty("username"); + credentials = properties.getProperty("credentials"); + + String serverRoundtripIntervalValue = + properties.getProperty("serverRoundtripInterval"); + String serverInactiveIntervalValue = + properties.getProperty("serverInactiveInterval"); + + try { + if (serverRoundtripIntervalValue != null) { + serverRoundtripInterval = + Integer.parseInt(serverRoundtripIntervalValue); + } + } + catch (NumberFormatException e) { + log.error(e,e); + } + + try { + if (serverInactiveIntervalValue != null) { + serverInactiveInterval = 1000L * // input in seconds! + Long.parseLong(serverInactiveIntervalValue); + } + } + catch (NumberFormatException e) { + log.error(e,e); + } + + log.info("ArcSDEPoolableObjectFactory initialized"); + log.info("Server: " + server); + log.info("Port: " + port); + log.info("Database: " + database); + log.info("User: " + username); + log.info("Roundtrip check interval: " + serverRoundtripInterval); + log.info("Inactive check interval: " + serverInactiveInterval); + } + + /** + * @see org.apache.commons.pool.PoolableObjectFactory#activateObject(java.lang.Object) + */ + public void activateObject(Object arg0) throws Exception { + log.debug("ArcSDEPoolableObjectFactory.activateObject"); + } + + /** + * @see org.apache.commons.pool.PoolableObjectFactory#destroyObject(java.lang.Object) + */ + public void destroyObject(Object arg0) throws Exception { + log.debug("ArcSDEPoolableObjectFactory.destroyObjectb"); + if (arg0 instanceof ArcSDEConnection) { + ((ArcSDEConnection)arg0).close(); + }else{ + log.warn("Object cannot be handled"); + } + } + + /** + * @see org.apache.commons.pool.PoolableObjectFactory#makeObject() + */ + public Object makeObject() throws Exception { + log.debug("ArcSDEPoolableObjectFactory.makeObject"); + Connection con; + try { + con = new ArcSDEConnection( + server, + port, + database, + username, + credentials, + serverRoundtripInterval, + serverInactiveInterval); + } + catch (ConnectionException e) { + throw new ConnectionException( + "Establishing a connection to database failed: " + + e.toString(), e); + } + return con; + } + + /** + * @see org.apache.commons.pool.PoolableObjectFactory#passivateObject(java.lang.Object) + */ + public void passivateObject(Object arg0) throws Exception { + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("ArcSDEPoolableObjectFactory.passivateObject"); + } + + if (arg0 instanceof ArcSDEConnection) { + if (debug) { + log.debug(" touching connection"); + } + ((ArcSDEConnection)arg0).touch(); + } + } + + /** + * @see org.apache.commons.pool.PoolableObjectFactory#validateObject(java.lang.Object) + */ + public boolean validateObject(Object arg0) { + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("ArcSDEPoolableObjectFactory.validateObject"); + } + + if (!(arg0 instanceof ArcSDEConnection)) { + return false; + } + + try { + ArcSDEConnection con = (ArcSDEConnection)arg0; + + boolean isValid = + con.isActive() && con.isValid(serverRoundtripInterval); + + if (!isValid && debug) { + log.debug("connection is invalid!"); + } + + return isValid; + } + catch (SQLException sqle) { + log.error(sqle, sqle); + } + + return false; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/connectionpool/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains Classes that provides an ConnectionPool +for ArcSDEConnection-Objects. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnection.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,469 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; + +import org.apache.log4j.Logger; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; + +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; +import de.intevation.gnv.geobackend.sde.connectionpool.ArcSDEPoolableObjectFactory; + +/** + * Wrapperclass between an @see java.sql.Connection and an + * @see com.esri.sde.sdk.client.SeConnection + * @author Tim Englich + */ +public class ArcSDEConnection implements Connection { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ArcSDEPoolableObjectFactory.class); + + /** + * The Connection to the ArcSDE-backend. + */ + private SeConnection seConnection = null; + /** + * Time that have to be gone until the Server will be requested if + * the Connection is valid. + */ + private long serverRoundtripInterval ; + + /** + * The Time which a Connection can be inactive until the Connection + * will be set to invalid. + */ + private long inactiveInterval; + + /** + * The TimeStamp of the last usage of this Connection. + */ + private long lastTouch; + + + /** + * Constructor + * @param server the URL to the Server + * @param port the Port of the Server + * @param database the Name of the Database + * @param username the Name of the User + * @param credentials the Credentials to the User- + * @param serverRoundtripInterval Time that have to be gone until the Server + * will be requested if the Connection is valid. + * @param inactiveInterval the Time which a Connection can be inactive until + * the Connection will be set to invalid. + * @throws ConnectionException + */ + public ArcSDEConnection( + String server, + String port, + String database, + String username, + String credentials, + long serverRoundtripInterval, + long inactiveInterval + ) + throws ConnectionException + { + this.serverRoundtripInterval = serverRoundtripInterval; + this.inactiveInterval = inactiveInterval; + lastTouch = System.currentTimeMillis(); + + try { + seConnection = new SeConnection( server, port, database, username, credentials); + } + catch (SeException e) { + log.error(e,e); + throw new ConnectionException(e); + } + } + + /** + * Validates if the Connection is active + * @return true if the Connection is active. False if not. + */ + public boolean isActive() { + long current = System.currentTimeMillis(); + long last; + synchronized (this) { + last = lastTouch; + } + return Math.abs(current - last) < inactiveInterval; + } + + /** + * Sets the last-Usage-Time to the Current-time + */ + public void touch() { + long time = System.currentTimeMillis(); + synchronized (this) { + lastTouch = time; + } + } + + /** + * @see java.sql.Connection#clearWarnings() + */ + public void clearWarnings() throws SQLException { + } + + /** + * @see java.sql.Connection#close() + */ + public void close() throws SQLException { + try { + this.seConnection.close(); + } catch (SeException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.Connection#commit() + */ + public void commit() throws SQLException { + try{ + this.seConnection.commitTransaction(); + } catch (SeException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.Connection#createStatement() + */ + public Statement createStatement() throws SQLException { + return new ArcSDEStatement(this); + } + + /** + * @see java.sql.Connection#createStatement(int, int) + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency) + throws SQLException { + return new ArcSDEStatement(this); + } + + /** + * @see java.sql.Connection#createStatement(int, int, int) + */ + public Statement createStatement(int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return new ArcSDEStatement(this); + } + + /** + * @see java.sql.Connection#getAutoCommit() + */ + public boolean getAutoCommit() throws SQLException { + return false; + } + + /** + * @see java.sql.Connection#getCatalog() + */ + public String getCatalog() throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#getHoldability() + */ + public int getHoldability() throws SQLException { + return 0; + } + + /** + * @see java.sql.Connection#getMetaData() + */ + public DatabaseMetaData getMetaData() throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#getTransactionIsolation() + */ + public int getTransactionIsolation() throws SQLException { + return 0; + } + + /** + * @see java.sql.Connection#getTypeMap() + */ + public Map> getTypeMap() throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#getWarnings() + */ + public SQLWarning getWarnings() throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#isClosed() + */ + public boolean isClosed() throws SQLException { + try{ + return this.seConnection.isClosed(); + } catch (Exception e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.Connection#isReadOnly() + */ + public boolean isReadOnly() throws SQLException { + return false; + } + + /** + * @see java.sql.Connection#nativeSQL(java.lang.String) + */ + public String nativeSQL(String sql) throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String) + */ + public CallableStatement prepareCall(String sql) throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String, int, int) + */ + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int) + */ + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String) + */ + public PreparedStatement prepareStatement(String sql) throws SQLException { + + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int) + */ + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) + throws SQLException { + + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int[]) + */ + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) + throws SQLException { + + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[]) + */ + public PreparedStatement prepareStatement(String sql, String[] columnNames) + throws SQLException { + + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int, int) + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int) + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint) + */ + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + } + + /** + * @see java.sql.Connection#rollback() + */ + public void rollback() throws SQLException { + try { + this.seConnection.rollbackTransaction(); + } catch (SeException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.Connection#rollback(java.sql.Savepoint) + */ + public void rollback(Savepoint savepoint) throws SQLException { + this.rollback(); + } + + /** + * @see java.sql.Connection#setAutoCommit(boolean) + */ + public void setAutoCommit(boolean autoCommit) throws SQLException { + } + + /** + * @see java.sql.Connection#setCatalog(java.lang.String) + */ + public void setCatalog(String catalog) throws SQLException { + } + + /** + * @see java.sql.Connection#setHoldability(int) + */ + public void setHoldability(int holdability) throws SQLException { + } + + /** + * @see java.sql.Connection#setReadOnly(boolean) + */ + public void setReadOnly(boolean readOnly) throws SQLException { + } + + /** + * @see java.sql.Connection#setSavepoint() + */ + public Savepoint setSavepoint() throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#setSavepoint(java.lang.String) + */ + public Savepoint setSavepoint(String name) throws SQLException { + return null; + } + + /** + * @see java.sql.Connection#setTransactionIsolation(int) + */ + public void setTransactionIsolation(int level) throws SQLException { + } + + /** + * @see java.sql.Connection#setTypeMap(java.util.Map) + */ + public void setTypeMap(Map> map) throws SQLException { + } + + /** + * @return the seConnection + */ + public SeConnection getSeConnection() { + return seConnection; + } + + public Array createArrayOf(String arg0, Object[] arg1) throws SQLException { + return null; + } + + public Blob createBlob() throws SQLException { + return null; + } + + public Clob createClob() throws SQLException { + return null; + } + + public NClob createNClob() throws SQLException { + return null; + } + + public SQLXML createSQLXML() throws SQLException { + return null; + } + + public Struct createStruct(String arg0, Object[] arg1) throws SQLException { + return null; + } + + public Properties getClientInfo() throws SQLException { + return null; + } + + public String getClientInfo(String arg0) throws SQLException { + return null; + } + + public boolean isValid(int arg0) throws SQLException { + boolean valid = true; + try { + this.seConnection.testServer(serverRoundtripInterval); + } catch (SeException e) { + log.debug("The validation of the Connection has occured an Error. The connection is invalid."); + valid = false; + } + + return valid; + } + + public void setClientInfo(Properties arg0) throws SQLClientInfoException { + } + + public void setClientInfo(String arg0, String arg1) + throws SQLClientInfoException { + } + + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + public T unwrap(Class iface) throws SQLException { + return null; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEResultSetMetaData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEResultSetMetaData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,208 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +import java.util.List; + +/** + * This Class is an Wrapperclass for the ResultSetMetaData and the + * ColumnDefinitions which are retrieved from the ArcSDE-Backend. + * @author Tim Englich + * + */ +public class ArcSDEResultSetMetaData implements ResultSetMetaData { + + /** + * The Columndefinitions which are required to explain the retrieved Data. + */ + private List columnDefinitions = null; + + /** + * Constructor + */ + public ArcSDEResultSetMetaData(List columnDefinitions) { + this.columnDefinitions = columnDefinitions; + } + + /** + * @see java.sql.ResultSetMetaData#getCatalogName(int) + */ + public String getCatalogName(int column) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSetMetaData#getColumnClassName(int) + */ + public String getColumnClassName(int column) throws SQLException { + int type = this.getColumnType(column); + if (type == ColDefinition.INT16){ + return "Integer"; + }else if (type == ColDefinition.INT32){ + return "Integer"; + }else if (type == ColDefinition.INT64){ + return "Long"; + }else if (type == ColDefinition.NSTRING || type == ColDefinition.STRING){ + return "String"; + }else if (type == ColDefinition.DATE){ + return "Date"; + }else if (type == ColDefinition.FLOAT){ + return "Float"; + }else if (type == ColDefinition.FLOAT32){ + return "Double"; + }else if (type == ColDefinition.FLOAT64){ + return "Double"; + }else{ + return java.lang.Object.class.getName(); + } + } + + /** + * @see java.sql.ResultSetMetaData#getColumnCount() + */ + public int getColumnCount() throws SQLException { + return columnDefinitions.size(); + } + + /** + * @see java.sql.ResultSetMetaData#getColumnDisplaySize(int) + */ + public int getColumnDisplaySize(int column) throws SQLException { + return 0; + } + + /** + * @see java.sql.ResultSetMetaData#getColumnLabel(int) + */ + public String getColumnLabel(int column) throws SQLException { + return columnDefinitions.get(column-1).getName(); + } + + /** + * @see java.sql.ResultSetMetaData#getColumnName(int) + */ + public String getColumnName(int column) throws SQLException { + return columnDefinitions.get(column-1).getName(); + } + + /** + * @see java.sql.ResultSetMetaData#getColumnType(int) + */ + public int getColumnType(int column) throws SQLException { + return columnDefinitions.get(column-1).getType(); + } + + /** + * @see java.sql.ResultSetMetaData#getColumnTypeName(int) + */ + public String getColumnTypeName(int column) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSetMetaData#getPrecision(int) + */ + public int getPrecision(int column) throws SQLException { + return 0; + } + + /** + * @see java.sql.ResultSetMetaData#getScale(int) + */ + public int getScale(int column) throws SQLException { + return 0; + } + + /** + * @see java.sql.ResultSetMetaData#getSchemaName(int) + */ + public String getSchemaName(int column) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSetMetaData#getTableName(int) + */ + public String getTableName(int column) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSetMetaData#isAutoIncrement(int) + */ + public boolean isAutoIncrement(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSetMetaData#isCaseSensitive(int) + */ + public boolean isCaseSensitive(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSetMetaData#isCurrency(int) + */ + public boolean isCurrency(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSetMetaData#isDefinitelyWritable(int) + */ + public boolean isDefinitelyWritable(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSetMetaData#isNullable(int) + */ + public int isNullable(int column) throws SQLException { + return 0; + } + + /** + * @see java.sql.ResultSetMetaData#isReadOnly(int) + */ + public boolean isReadOnly(int column) throws SQLException { + return true; + } + + /** + * @see java.sql.ResultSetMetaData#isSearchable(int) + */ + public boolean isSearchable(int column) throws SQLException { + return true; + } + + /** + * @see java.sql.ResultSetMetaData#isSigned(int) + */ + public boolean isSigned(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSetMetaData#isWritable(int) + */ + public boolean isWritable(int column) throws SQLException { + return false; + } + + /** + * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) + */ + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + /** + * @see java.sql.Wrapper#unwrap(java.lang.Class) + */ + public T unwrap(Class iface) throws SQLException { + return null; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,672 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import com.esri.sde.sdk.client.SDEPoint; +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeExtent; +import com.esri.sde.sdk.client.SeFilter; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeQueryInfo; +import com.esri.sde.sdk.client.SeRaster; +import com.esri.sde.sdk.client.SeRasterAttr; +import com.esri.sde.sdk.client.SeRasterBand; +import com.esri.sde.sdk.client.SeRasterConstraint; +import com.esri.sde.sdk.client.SeRasterTile; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeShape; +import com.esri.sde.sdk.client.SeShapeFilter; +import com.esri.sde.sdk.client.SeSqlConstruct; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.util.RedundancyRemover; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.Statement; + +import org.apache.log4j.Logger; + +/** + * This Class wrapps an SDE-Statment to an java.sql.Statement. + * This Class also handles the SDE-Specific -Spatial-Queries and + * RasterQueries. + * @author Tim Englich + * @author Sascha L. Teichmann + */ +public class ArcSDEStatement implements Statement { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ArcSDEStatement.class); + + /** + * The Connection to the ArcSDE-Backend + */ + private ArcSDEConnection connection = null; + + /** + * Constructor + * @param connection the Connection to the ArcSDE-Backend. + */ + public ArcSDEStatement(ArcSDEConnection connection) { + this.connection = connection; + } + + /** + * @see java.sql.Statement#addBatch(java.lang.String) + */ + public void addBatch(String arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#cancel() + */ + public void cancel() throws SQLException { + } + + /** + * @see java.sql.Statement#clearBatch() + */ + public void clearBatch() throws SQLException { + } + + /** + * @see java.sql.Statement#clearWarnings() + */ + public void clearWarnings() throws SQLException { + } + + /** + * @see java.sql.Statement#close() + */ + public void close() throws SQLException { + } + + /** + * @see java.sql.Statement#execute(java.lang.String) + */ + public boolean execute(String arg0) throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#execute(java.lang.String, int) + */ + public boolean execute(String arg0, int arg1) throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#execute(java.lang.String, int[]) + */ + public boolean execute(String arg0, int[] arg1) throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#execute(java.lang.String, java.lang.String[]) + */ + public boolean execute(String arg0, String[] arg1) throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#executeBatch() + */ + public int[] executeBatch() throws SQLException { + return null; + } + + /** + * @see java.sql.Statement#executeQuery(java.lang.String) + */ + public ResultSet executeQuery(String statement) throws SQLException { + try { + SeQuery query = null; + if (statement.toLowerCase().contains("st_astext") || statement.toLowerCase().contains("intersects")){ + + String[] values = statement.toLowerCase().split("where", 2); + String where = values.length > 1 ? values[1].trim() : ""; + String[] tableNames = values[0].substring(values[0].indexOf("from")).replaceFirst("from", "").toUpperCase().trim().split(", "); + String columnValueString = values[0].substring(0, values[0].indexOf("from")).trim(); + columnValueString = columnValueString.replaceFirst("select", "").trim(); + String[] returnFields = columnValueString.split(", "); + String geometryColumnName = null; + String byClause = null; + int byClausePos = where.indexOf("group by"); + if (byClausePos < 0){ + byClausePos = where.indexOf("order by"); + } + if (byClausePos > 0){ + byClause = where.substring(byClausePos); + where = where.substring(0,byClausePos); + } + + for (int i = 0; i < returnFields.length; i++){ + returnFields[i] = returnFields[i].trim(); + if (returnFields[i].startsWith("st_astext(")){ + returnFields[i] = returnFields[i].replaceAll("st_astext", ""); + returnFields[i] = returnFields[i].substring(1, returnFields[i].length()-1); + geometryColumnName = returnFields[i]; + } + } + + for (int i = 0; i < tableNames.length; i++){ + tableNames[i] = tableNames[i].trim(); + } + + Geometry g = null; + int pos = where.indexOf("intersects"); + if (pos >= 0 ){ + String substr = where.substring(pos); + where = where.substring(0,where.lastIndexOf("intersects")); + int andPos = where.lastIndexOf("and"); + if (andPos < 0){ + andPos = 0; + } + where = where.substring(0,andPos); // TODO support or also + String intersectsStmt = substr.substring(0, substr.lastIndexOf(")")); // Spatial-Statment is the last one + String wkt = null; + if (intersectsStmt.contains("select")){ + // Anstelle eines WKT ist ein InnerSelect zum Bestimmen der Comparatorgeometrie gegeben. + String stmt = intersectsStmt.substring(intersectsStmt.indexOf("select"),intersectsStmt.lastIndexOf(")")); + ResultSet resultSet = this.executeQuery(stmt); + if (resultSet != null && resultSet.next()){ + // TODO: Support the selection of more than one Geometry + wkt = resultSet.getString("SHAPE"); + } + }else{ + wkt = intersectsStmt.substring(intersectsStmt.indexOf("\""), intersectsStmt.lastIndexOf("\"")).replace("\"", "").trim(); + } + g = new WKTReader().read(wkt.toUpperCase()); + + if (geometryColumnName == null){ + geometryColumnName = "SHAPE"; // TODO dynamisch aus Intersects auslesen. + } + + } + + return this.executeQuery(this.connection.getSeConnection(), tableNames, geometryColumnName, where, g, returnFields,byClause); + }else{ + query = new SeQuery(this.connection.getSeConnection()); + query.prepareSql(statement); + query.execute(); + return this.handleResultSet(query,false,null); + } + + } catch (Exception e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + + + } + /** + * This Methods Executes the ArcSDE Query if Spatial-Restrictions + * are given + * @param con The Connection to the ArcSDE-Backend. + * @param pLayername The Name of tables which should be used in the Query + * @param pSpatialColumnName the Name of the Spatial Column. + * @param pWhere The where-Clause to limit the Data + * @param g the Geometry to limit the Data + * @param pReturnFields the Fileds that should be fetched from the Database + * @param byClause the byClaus to order the Results. + * @return the @see java.sql.ResultSet with the Data which was retrieved. + * @throws SQLException + */ + private ResultSet executeQuery(SeConnection con, String[] pLayername, + String pSpatialColumnName, String pWhere, + Geometry g, String[] pReturnFields, String byClause) + throws SQLException { + log.debug("executeQuery()"); + try { + // get the layer for querying + boolean isRaster = pSpatialColumnName.equalsIgnoreCase("raster"); + + SeShapeFilter[] filters = null; + if (g != null){ + if (!isRaster){ + SeLayer lLayer = new SeLayer(con, pLayername[0], pSpatialColumnName); + SeShape shape = new SeShape(); + shape.setCoordRef(lLayer.getCoordRef()); + + SDEPoint[] lPoints = new ArcSDEUtils().createPoints(g); + + int searchMode = SeFilter.METHOD_AI; + if (g instanceof Polygon){ + shape.generatePolygon(lPoints.length, 1, null, lPoints); + }else if (g instanceof Point){ + shape.generatePoint(1, lPoints); + searchMode = SeFilter.METHOD_PC; + }else if (g instanceof LineString){ + shape.generateLine(lPoints.length, 1, null, lPoints); + searchMode = SeFilter.METHOD_LCROSS; + } + + SeShapeFilter filter = new SeShapeFilter(pLayername[0], + pSpatialColumnName, shape,searchMode); + filters = new SeShapeFilter[1]; + filters[0] = filter; + } + } + + SeQuery spatialQuery = null; + SeSqlConstruct sqlCons = new SeSqlConstruct(pLayername, pWhere); + spatialQuery = new SeQuery(con);//, pReturnFields, sqlCons); + + SeQueryInfo queryInfo = new SeQueryInfo(); + queryInfo.setColumns(pReturnFields); + + if (byClause != null){ + queryInfo.setByClause(byClause); + } + + queryInfo.setConstruct(sqlCons); + spatialQuery.prepareQueryInfo(queryInfo); + + /* + * Set spatial constraints + */ + if (filters != null){ + spatialQuery.setSpatialConstraints(SeQuery.SE_OPTIMIZE, false, + filters); + } + + if (!isRaster){ + spatialQuery.execute(); + } + + return this.handleResultSet(spatialQuery,isRaster,g); + + } catch (Exception e) { + if (e instanceof SeException){ + ArcSDEUtils.printError((SeException)e); + }else{ + log.error(e.getMessage(), e); + } + + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.Statement#executeUpdate(java.lang.String) + */ + public int executeUpdate(String arg0) throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#executeUpdate(java.lang.String, int) + */ + public int executeUpdate(String arg0, int arg1) throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#executeUpdate(java.lang.String, int[]) + */ + public int executeUpdate(String arg0, int[] arg1) throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#executeUpdate(java.lang.String, java.lang.String[]) + */ + public int executeUpdate(String arg0, String[] arg1) throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getConnection() + */ + public Connection getConnection() throws SQLException { + return this.connection; + } + + /** + * @see java.sql.Statement#getFetchDirection() + */ + public int getFetchDirection() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getFetchSize() + */ + public int getFetchSize() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getGeneratedKeys() + */ + public ResultSet getGeneratedKeys() throws SQLException { + return null; + } + + /** + * @see java.sql.Statement#getMaxFieldSize() + */ + public int getMaxFieldSize() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getMaxRows() + */ + public int getMaxRows() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getMoreResults() + */ + public boolean getMoreResults() throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#getMoreResults(int) + */ + public boolean getMoreResults(int arg0) throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#getQueryTimeout() + */ + public int getQueryTimeout() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getResultSet() + */ + public ResultSet getResultSet() throws SQLException { + return null; + } + + /** + * @see java.sql.Statement#getResultSetConcurrency() + */ + public int getResultSetConcurrency() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getResultSetHoldability() + */ + public int getResultSetHoldability() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getResultSetType() + */ + public int getResultSetType() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getUpdateCount() + */ + public int getUpdateCount() throws SQLException { + return 0; + } + + /** + * @see java.sql.Statement#getWarnings() + */ + public SQLWarning getWarnings() throws SQLException { + return null; + } + + /** + * @see java.sql.Statement#setCursorName(java.lang.String) + */ + public void setCursorName(String arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setEscapeProcessing(boolean) + */ + public void setEscapeProcessing(boolean arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setFetchDirection(int) + */ + public void setFetchDirection(int arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setFetchSize(int) + */ + public void setFetchSize(int arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setMaxFieldSize(int) + */ + public void setMaxFieldSize(int arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setMaxRows(int) + */ + public void setMaxRows(int arg0) throws SQLException { + } + + /** + * @see java.sql.Statement#setQueryTimeout(int) + */ + public void setQueryTimeout(int arg0) throws SQLException { + } + + /** + * This Method fetches all Rows from the SeQuery-Object and convert it into + * an @see java.sql.ResultSet. + * + * @param pSeQuery the Queryobject where the Data should be fetched from. + * @param isRaster Flag which indicates if the Result is Rasterdata. + * @param geometry The Geometry which might be used to limit the data. + * @return an java.sql:ResultSet which contains the Data. + * @throws SeException + */ + private ResultSet handleResultSet(SeQuery pSeQuery, + boolean isRaster, + Geometry geometry) throws SeException { + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("ArcSDEStatement.handleResultSet()"); + } + + SDEResultSet lSet = new SDEResultSet(); + SeRow row = null; + int lCount; + if (!isRaster){ + RedundancyRemover [] removers = null; + SeColumnDefinition [] lCols = null; + + for (lCount = 0; (row = pSeQuery.fetch()) != null; lCount++) { + // one time execution + if (lCount == 0) { + // analyze cols of result set + lCols = row.getColumns(); + for (SeColumnDefinition lCol : lCols) { + lSet.addCol(new ColDefinition(lCol.getName(), lCol.getType())); + // notice: esri-types have been copied into colDefinition class! + } + removers = new RedundancyRemover[lCols.length]; + for (int i = 0; i < removers.length; ++i) { + removers[i] = new RedundancyRemover(); + } + } + short lNumCols = row.getNumColumns(); + Row lBackingRow = new Row(lNumCols); + for (int i = 0; i < lNumCols; i++) { + lBackingRow.addObject( + removers[i].filter(row.getObject(i)), + i); + } + lSet.addRow(lBackingRow); + } + + if (debug && removers != null) { + log.debug("datasets: " + lCount); + StringBuilder sb = new StringBuilder("removed redundancy: "); + float percent = 100f/lCount; + for (int i = 0; i < removers.length; ++i) { + if (i > 0) sb.append(", "); + sb.append(lCols[i].getName()) + .append(": ").append(removers[i].numRemoved()) + .append(" (").append(removers[i].numRemoved()*percent) + .append("%)"); + } + log.debug(sb.toString()); + } + }else{ + try { + pSeQuery.execute(); + row = pSeQuery.fetch(); + SeRasterAttr attr = row.getRaster(0); + SeRaster raster = attr.getRasterInfo(); + SeRasterBand [] bands = raster.getBands(); + SeRasterBand rasterBand = bands[0]; + + SeExtent extent = rasterBand.getExtent(); + + double x = ((Point)geometry).getX(); + double y = ((Point)geometry).getY(); + + boolean isPointInRaster = + x >= extent.getMinX() && x <= extent.getMaxX() + && y >= extent.getMinY() && y <= extent.getMaxY(); + + if (isPointInRaster){ + + if (row == null){ + pSeQuery.execute(); + row = pSeQuery.fetch(); + } + + double midX = 0.5d*(extent.getMinX() + extent.getMaxX()); + double midY = 0.5d*(extent.getMinY() + extent.getMaxY()); + + SDEPoint origin = rasterBand.getTileOrigin(); + + double maxX = origin.getX() < midX + ? extent.getMaxX() + : extent.getMinX(); + + double maxY = origin.getY() < midY + ? extent.getMaxY() + : extent.getMinY(); + + double mx = rasterBand.getBandWidth()/(maxX-origin.getX()); + double bx = -origin.getX()*mx; + double px = mx*x + bx; + + double my = rasterBand.getBandHeight()/(maxY-origin.getY()); + double by = -origin.getY()*my; + double py = my*y + by; + + SeRasterConstraint constraint = new SeRasterConstraint(); + constraint.setLevel(0); // best resolution + constraint.setBands(rasterBand.getBandNumber()); + int tx = (int)Math.floor(px / rasterBand.getTileWidth()); + int ty = (int)Math.floor(py / rasterBand.getTileHeight()); + constraint.setEnvelope(tx, ty, tx, ty); + + pSeQuery.queryRasterTile(constraint); + SeRasterTile tile = row.getRasterTile(); + + if (tile != null){ + double[] tileValues = new double[tile.getNumPixels()]; + tileValues = tile.getPixels(tileValues); + lSet.addCol(new ColDefinition("tile", ColDefinition.FLOAT64)); + Row lBackingRow = new Row(1); + + double wx1 = (rasterBand.getTileWidth()*tx - bx)/mx; + double wx2 = (rasterBand.getTileWidth()*(tx+1) - bx)/mx; + double mxt = (rasterBand.getTileWidth()-1e-5d)/(wx2 - wx1); + double bxt = -wx1*mxt; + + double wy1 = (rasterBand.getTileHeight()*ty - by)/my; + double wy2 = (rasterBand.getTileHeight()*(ty+1) - by)/my; + double myt = (rasterBand.getTileHeight()-1e-5d)/(wy2 - wy1); + double byt = -wy1*myt; + + RasterObject ro = new RasterObject( + mxt, bxt, + myt, byt, + tile.getColumnIndex(), + tile.getRowIndex(), + tileValues, + rasterBand.getTileWidth(), + rasterBand.getTileHeight()); + lBackingRow.addObject(ro, 0); + lSet.addRow(lBackingRow); + + } + } + else{ + log.debug("The Query doesn't deliver any Information " + + "because the Point is located outside the Raster."); + } + } catch (Exception e) { + log.error(e,e); + } + } + pSeQuery.close(); + return lSet; + } + + /** + * @see java.sql.Statement#isClosed() + */ + public boolean isClosed() throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#isPoolable() + */ + public boolean isPoolable() throws SQLException { + return false; + } + + /** + * @see java.sql.Statement#setPoolable(boolean) + */ + public void setPoolable(boolean arg0) throws SQLException { + } + + /** + * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) + */ + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + /** + * @see java.sql.Wrapper#unwrap(java.lang.Class) + */ + public T unwrap(Class iface) throws SQLException { + return null; + + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,84 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import com.esri.sde.sdk.client.SDEPoint; +import com.esri.sde.sdk.client.SeError; +import com.esri.sde.sdk.client.SeException; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +import org.apache.log4j.Logger; + +/** + * The class ArcSDEUtils fulfills the following purposes: + * + * @author blume + * @author Tim Englich + */ +public class ArcSDEUtils { + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(ArcSDEUtils.class); + + /** + * Prints an SEEsception into the Logger of this Class + * @param exception + */ + public static void printError(SeException exception) { + + SeError error = exception.getSeError(); + + sLogger.debug("\n ArcSDE Error Number : " + error.getSdeError()); + sLogger.debug(" Error Description : " + error.getErrDesc()); + + int extError = error.getExtError(); + if (extError != 0) + sLogger.debug(" Extended Error Number : " + extError); + + String desc = error.getSdeErrMsg(); + if (desc != null && desc.length() != 0) + sLogger.debug(" Extended Error Description : " + desc); + + desc = error.getExtErrMsg(); + if (desc != null && desc.length() != 0) + sLogger.debug(" Extended Error Description : " + desc); + + sLogger.debug(exception); + + } + + /** + * Generate an SDEPoint-Array from a given Geometry. + * This Method did not put the Holes to the Array. + * @param g The Geometry which should be converted. + * @return an SDEPoint-Array from a given Ggeometry. + */ + public SDEPoint[] createPoints(Geometry g) { + sLogger.debug("createPoints()"); + Coordinate[] coords = null; + if (g instanceof Polygon) { + coords = ((Polygon) g).getCoordinates(); + }else if (g instanceof Point){ + coords = ((Point)g).getCoordinates(); + }else if (g instanceof LineString){ + coords = ((LineString)g).getCoordinates(); + }else{ + coords = g.getCoordinates(); + } + + if (coords != null){ + SDEPoint[] lSDEPoints = new SDEPoint[coords.length]; + for (int i = 0; i < coords.length; i++) { + lSDEPoints[i] = new SDEPoint(coords[i].x, coords[i].y); + } + return lSDEPoints; + }else{ + return null; + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ColDefinition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ColDefinition.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,77 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import org.apache.log4j.Logger; + +/** + * The class ColDefinition fulfills the following purposes: + * @author blume + * @author Tim Englich + */ +public class ColDefinition { + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(ColDefinition.class); + + /** + * @deprecated + */ + public static final int SMALLINT = 1; + /** + * @deprecated + */ + public static final int INTEGER = 2; + /** + * @deprecated + */ + public static final int FLOAT = 3; + /** + * @deprecated + */ + public static final int DOUBLE = 4; + public static final int INT16 = 1; + public static final int INT32 = 2; + public static final int FLOAT32 = 3; + public static final int FLOAT64 = 4; + public static final int STRING = 5; + public static final int BLOB = 6; + public static final int DATE = 7; + public static final int SHAPE = 8; + public static final int RASTER = 9; + public static final int XML = 10; + public static final int INT64 = 11; + public static final int UUID = 12; + public static final int CLOB = 13; + public static final int NSTRING = 14; + public static final int NCLOB = 15; + + private String mName; + private int mType; + + /** + * Constructor + * @param pName the Name of an Column. + * @param pType the Type of an Column. + */ + public ColDefinition(String pName, int pType) { + mName = pName; + mType = pType; + } + + /** + * Returns the Name of an Column. + * @return the Name of an Column. + */ + public String getName() { + return mName; + } + + /** + * Returns the Type of an Column. + * @return the Type of an Column. + */ + public int getType() { + return mType; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,303 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import com.vividsolutions.jts.geom.Coordinate; + +import java.io.Serializable; + +import org.apache.commons.math.ArgumentOutsideDomainException; + +import org.apache.commons.math.analysis.interpolation.SplineInterpolator; + +import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * @author Sascha L. Teichmann + */ +public class RasterObject +implements Serializable +{ + private static Logger log = Logger.getLogger(RasterObject.class); + + public static final int NEAREST_NEIGHBOR = 0; + public static final int BILINEAR = 1; + public static final int BICUBIC = 2; + + private double mx; + private double bx; + private double my; + private double by; + + private int columnIndex; + private int rowIndex; + + private int tileWidth; + private int tileHeight; + + private double [] rasterData; + + private transient PolynomialSplineFunction [] splines; + private transient double [] columns; + + public RasterObject() { + } + + public RasterObject( + double mx, double bx, + double my, double by, + int columnIndex, + int rowIndex, + double [] rasterData, + int tileWidth, + int tileHeight + ){ + this.mx = mx; + this.bx = bx; + this.my = my; + this.by = by; + this.columnIndex = columnIndex; + this.rowIndex = rowIndex; + this.rasterData = rasterData; + this.tileWidth = tileWidth; + this.tileHeight = tileHeight; + } + + public boolean contains(Coordinate coordinate) { + double px = mx*coordinate.x + bx; + double py = my*coordinate.y + by; + return px >= 0d && py >= 0d && px < tileWidth && py < tileHeight; + } + + public final double get(int posX, int posY) { + return rasterData[posY*tileWidth + posX]; + } + + public int getTileWidth() { + return tileWidth; + } + + public int getTileHeight() { + return tileWidth; + } + + public int getColumnIndex() { + return columnIndex; + } + + public int getRowIndex() { + return rowIndex; + } + + public double getValue(Coordinate coordinate) { + return getValue(coordinate, NEAREST_NEIGHBOR); + } + + public final double interpolateBilinear(double px, double py) { + + if (px < 0.5d) { // left border + if (py < 0.5d) { // upper left edge + return rasterData[0]; + } + if (py > tileHeight-0.5d) { // lower left edge + return rasterData[rasterData.length-tileWidth]; + } + // center left + int i = (int)(py -= 0.5d); + double t = py - i; + i *= tileWidth; + return (1d-t)*rasterData[i] + t*rasterData[i+tileWidth]; + } + + if (px > tileWidth-0.5d) { // right border + if (py < 0.5d) { // upper right edge + return rasterData[tileWidth-1]; + } + if (py > tileHeight-0.5d) { // lower right edge + return rasterData[rasterData.length-1]; + } + // center right + int i = (int)(py -= 0.5d); + double t = py - i; + i = i*tileWidth + tileWidth-1; + return (1d-t)*rasterData[i] + t*rasterData[i+tileWidth]; + } + + if (py < 0.5d) { // top border + int i = (int)(px -= 0.5d); + double t = px - i; + return (1d-t)*rasterData[i] + t*rasterData[i+1]; + } + + if (py > tileHeight-0.5d) { // bottom border + int i = (int)(px -= 0.5d); + double t = px - i; + i += rasterData.length-tileWidth; + return (1d-t)*rasterData[i] + t*rasterData[i+1]; + } + + // center + int i = (int)(py -= 0.5d); + int j = (int)(px -= 0.5d); + double ti = py - i; + double tj = px - j; + + int idx = i*tileWidth + j; + + double v1j1 = rasterData[idx]; + double v2j1 = rasterData[idx+1]; + + idx += tileWidth; + + double v1j2 = rasterData[idx]; + double v2j2 = rasterData[idx+1]; + + double v1 = (1d-tj)*v1j1 + tj*v2j1; + double v2 = (1d-tj)*v1j2 + tj*v2j2; + + return (1d-ti)*v1 + ti*v2; + } + + protected PolynomialSplineFunction [] createSplines() { + PolynomialSplineFunction [] splines = + new PolynomialSplineFunction[tileHeight]; + + double [] x = new double[tileWidth]; + double [] y = new double[tileWidth]; + + for (int i = 0; i < tileWidth; ++i) { + x[i] = i + 0.5d; + } + + columns = new double[tileHeight]; + + SplineInterpolator interpolator = new SplineInterpolator(); + + for (int i = 0; i < tileHeight; ++i) { + int row = i*tileWidth; + for (int j = 0; j < tileWidth; ++j) { + y[j] = rasterData[row + j]; + } + splines[i] = interpolator.interpolate(x, y); + columns[i] = i + 0.5d; + } + + return splines; + } + + protected synchronized PolynomialSplineFunction [] getSplines() { + if (splines == null) { + splines = createSplines(); + } + return splines; + } + + protected double [] columnValues(double x) { + PolynomialSplineFunction [] splines = getSplines(); + double [] y = new double[tileHeight]; + try { + for (int i = 0; i < tileHeight; ++i) { + y[i] = splines[i].value(x); + } + } + catch (ArgumentOutsideDomainException aode) { + log.error(aode.getLocalizedMessage(), aode); + } + return y; + } + + private final double evaluateBicubicVertical(double x, double y) { + try { + SplineInterpolator interpolator = new SplineInterpolator(); + double [] cs = columnValues(x); + PolynomialSplineFunction spline = interpolator.interpolate( + columns, cs); + return spline.value(y); + } + catch (ArgumentOutsideDomainException aode) { + log.error(aode.getLocalizedMessage(), aode); + } + return 0d; + } + + private final double evaluateBicubicHorizonal(int index, double x) { + try { + PolynomialSplineFunction spline = getSplines()[index]; + return spline.value(x); + } + catch (ArgumentOutsideDomainException aode) { + log.error(aode.getLocalizedMessage(), aode); + } + return 0d; + } + + public double interpolateBicubic(double px, double py) { + + if (px <= 0.5d) { // left + if (py <= 0.5d) { // upper left + return rasterData[0]; + } + if (py >= tileHeight-0.5d) { + return rasterData[rasterData.length-tileWidth]; + } + return evaluateBicubicVertical(0.5d, py); + } + + if (px >= tileWidth-0.5d) { // right + if (py < 0.5d) { // upper right edge + return rasterData[tileWidth-1]; + } + if (py > tileHeight-0.5d) { // lower right edge + return rasterData[rasterData.length-1]; + } + return evaluateBicubicVertical(tileHeight-0.5d, py); + } + + if (py <= 0.5d) { // top + return evaluateBicubicHorizonal(0, px); + } + + if (py >= tileHeight-0.5d) { // bottom + return evaluateBicubicHorizonal(tileHeight-1, px); + } + + return evaluateBicubicVertical(px, py); + } + + public double getValue(Coordinate coordinate, int interpolationType) { + + double px = mx*coordinate.x + bx; + double py = my*coordinate.y + by; + + if (px < 0d || py < 0d || px >= tileWidth || py >= tileHeight) { + return Double.NaN; + } + + switch (interpolationType) { + case BILINEAR: return interpolateBilinear(px, py); + case BICUBIC : return interpolateBicubic (px, py); + } + + int posX = Math.min(tileWidth-1, (int)Math.round(px)); + int posY = Math.min(tileHeight-1, (int)Math.round(py)); + + return get(posX, posY); + } + + public static final int getInterpolationType(String key) { + if (key == null || (key = key.trim().toLowerCase()).length() == 0) { + return NEAREST_NEIGHBOR; + } + + if ("bilinear".equals(key)) { + return BILINEAR; + } + + if ("bicubic".equals(key)) { + return BICUBIC; + } + + return NEAREST_NEIGHBOR; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ResultSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ResultSet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import org.apache.log4j.Logger; + +/** + * The class ResultSet fulfills the following purposes: + *

    + *
  1. Providing an abstract object for dealing with result sets.
  2. + *
+ * + * @author blume + * @author Tim Englich + */ +public abstract class ResultSet implements java.sql.ResultSet { + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(ResultSet.class); + + /** + * Returns the number of hits. + * @return count of results. + */ + public abstract int getCount(); + + /** + * Returns the number of columns returned through the query. + * @return the number of columns. + */ + public abstract int getNumberOfColumns(); + + /** + * A ResultSet can tell about the concrete definition of each column. + * This method returns an array of ColDefinition-Objects. + * @return the definitions describing the result set. + */ + public abstract ColDefinition[] getColumnDefinitions(); + + /** + * Returns an array of Rows. The rows contain the "content" of the current ResultSet. + * + * @return the results itself. + */ + public abstract Row[] getResults(); + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/Row.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,286 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import com.esri.sde.sdk.client.SDEPoint; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeShape; + +import de.intevation.gnv.geobackend.sde.datasources.exception.TechnicalException; + +import de.intevation.gnv.geobackend.util.DateUtils; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; + +import org.apache.log4j.Logger; + +/** + * A Row represents a set of values. + * In a technical manner (e.g. database manner) a row contains all attributes of a single "hit". + * + * @author blume + * @author Tim Englich + */ +public class Row { + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(Row.class); + + /** + * Data container. + */ + private Object[] mObjects; + + /** + * Constructor. + * @param pRowSize the number of attributes contained by this row. + */ + public Row(int pRowSize) { + mObjects = new Object[pRowSize]; + } + + /** + * Constructor. + * @param ArrayStr a line from CSV-File. + */ + public Row (String[] ArrayStr){ + this (ArrayStr.length); + int nLength = ArrayStr.length; + for (int i=0; i < nLength; i++){ + addObject(ArrayStr[i], i); + + } + + } + + /** + * Adds an attribute value to a specific position of this row. + * + * @param pObject the object to be stored. + * @param pPos the postion the value to be saved + */ + public void addObject(Object pObject, int pPos) { + mObjects[pPos] = pObject; + } + + /** + * Returns a Value out of the Row. + * + * @param pPos the position of the value to be returned. + * @return an Object! (not strongly typed) + * @throws TechnicalException + */ + public Object getValue(int pPos) throws TechnicalException { + if (pPos < mObjects.length) { + + Object o = mObjects[pPos]; + if (o instanceof SeShape){ + return this.getPosValue(pPos); + }else{ + return o; + } + } else { + throw new TechnicalException("Cannot access this field position. Size is: " + mObjects.length); + } + } + + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @return a strongly typed Date + * @throws TechnicalException + * @see #getValue(int) + */ + public Date getDateValue(int pPos) throws TechnicalException { + Date date = null; + try { + Calendar lCalendar = (Calendar) getValue(pPos); + date = lCalendar.getTime(); + } + catch (ClassCastException e) { + try{ + //SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); + date = DateUtils.getDateFromString ((String)getValue(pPos)); //(Date)formatter.parse((String)getValue(pPos)); + + + } + catch (Exception ex){ + sLogger.error(getValue(pPos) + " " + ex.getMessage(), ex); + throw new TechnicalException("Could not cast this value to the Date Type. Object is of value type: " + getValue(pPos).getClass().getName()); + } + } + + return date; + } + + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @return a strongly typed String + * @throws TechnicalException + * @see #getValue(int) + */ + public String getStringValue(int pPos) throws TechnicalException { + try { + Object o = this.getValue(pPos); + String returnValue = null; + if (o instanceof SeShape){ + returnValue = this.getPosValue(pPos); + }else{ + returnValue = (String)o; + } + return returnValue; + } catch (ClassCastException e) { + throw new TechnicalException("Could not cast this value to the String Type. Object is of value type: " + getValue(pPos).getClass().getName()); + } + } + + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @throws TechnicalException + * @see #getValue(int) + * * @return a strongly typed int + */ + public int getIntValue(int pPos) throws TechnicalException { + try { + return (Integer) getValue(pPos); + } catch (ClassCastException e) { + throw new TechnicalException("Could not cast this value to the Integer Type. Object is of value type: " + getValue(pPos).getClass().getName()); + } + } + + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @throws TechnicalException + * @see #getValue(int) + * * @return a strongly typed Double + */ + public Double getDoubleValue(int pPos) throws TechnicalException { + try { + return (Double) getValue(pPos); + } catch (ClassCastException e) { + try{ + return new Double ((String)getValue(pPos)); + } + catch(Exception ex){ + sLogger.error(getValue(pPos) + " " + ex.getMessage(), ex); + throw new TechnicalException("Could not cast this value to the Double Type. Object is of value type: " + getValue(pPos).getClass().getName()); + } + } + } + + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @return a strongly typed Float + * @throws TechnicalException + * @see #getValue(int) + */ + public Float getFloatValue(int pPos) throws TechnicalException { + try { + return (Float) getValue(pPos); + } catch (ClassCastException e) { + throw new TechnicalException("Could not cast this value to the Float Type. Object is of value type: " + getValue(pPos).getClass().getName()); + } + } + /** + * This is a covenient method for getting strongly typed objects out of the row. + * It has to be ensured, that the type of the requested row position has been resolved out of the ColumnDefinition ({@link ResultSet#getColumnDefinitions()}). + * In fact, this method executes a simple cast to the desired type. + * + * @param pPos the position of the object to be resolved. + * @return a strongly typed Float + * @throws TechnicalException + * @see #getValue(int) + */ + public String getPosValue(int pPos)throws TechnicalException{ + StringBuffer returnValue = new StringBuffer(); + synchronized (returnValue) { + try { + SeShape val = (SeShape) this.mObjects[pPos]; + if (val.isPoint()){ + // Cannot use val.asText() because the + // generated WKT is invalid. + ArrayList aList = val.getAllPoints(0,false); + SDEPoint[] mPoint = (SDEPoint[])aList.get(0); + returnValue.append("POINT(") + .append(mPoint[0].getX()) + .append(" ") + .append(mPoint[0].getY()); + if (mPoint[0].is3D()){ + returnValue.append(" ").append(mPoint[0].getZ()); + } + returnValue.append(")"); + }else if (val.isLine() || val.isSimpleLine()){ + // Cannot use val.asText() because the + // generated WKT is invalid. + ArrayList aList = val.getAllPoints(0,false); + SDEPoint[] mPoint = (SDEPoint[])aList.get(0); + boolean isMultiLineString = val.isMultiPart(); + int length = mPoint.length; + int nextOffset = length; + int[] offsets = (int[])aList.get(1); + int offsetPos = 1; + + if(isMultiLineString){ + returnValue.append("MULTILINESTRING(("); + nextOffset = offsets.length-1 >= offsetPos ? offsets[offsetPos++] : length; + }else{ + returnValue.append("LINESTRING("); + } + + for (int i = 0; i< length;i++){ + + if (i == nextOffset){ + returnValue.append("),("); + nextOffset = offsets.length-1 >= offsetPos ? offsets[offsetPos++] : length; + } + + returnValue.append(mPoint[i].getX()) + .append(" ") + .append(mPoint[i].getY()); + if (mPoint[i].is3D()){ + returnValue.append(" ").append(mPoint[i].getZ()); + } + if (i < length-1 && i < nextOffset -1){ + returnValue.append(" , "); + } + } + + if(isMultiLineString){ + returnValue.append("))"); + }else{ + returnValue.append(")"); + } + + } else{ + returnValue.append(val.asText(val.getTextSize())); + } + } catch (SeException e) { + throw new TechnicalException("Could not cast this value to the " + + "Float Type. Object is of value " + + "type: " + + getValue(pPos).getClass().getName()); + } + } + return returnValue.toString(); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/SDEResultSet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1508 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import de.intevation.gnv.geobackend.sde.datasources.exception.TechnicalException; + +import java.io.InputStream; +import java.io.Reader; + +import java.math.BigDecimal; + +import java.net.URL; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +/** + * SDEResultSet is an Implementation of the Interface @see java.sql.resultSet + * It is an Wrapper between the resultsets whcih are produced using the ArcSDE + * and the Java-Interface for the Representation of ResultSets. + * @author blume + * @author Tim Englich + */ +public class SDEResultSet extends ResultSet { + + /** + * Default Logging instance + */ + private static Logger log = Logger.getLogger(SDEResultSet.class); + + private List mRows = Collections.synchronizedList(new ArrayList()); + private List mCols = Collections.synchronizedList(new ArrayList()); + + private Row currentRow = null; + private int cursor = 0; + + /** + * Constructor + */ + public SDEResultSet() { + } + + /** + * @see de.intevation.gnv.geobackend.sde.datasources.ResultSet#getCount() + */ + public int getCount() { + return mRows.size(); + } + + /** + * @see de.intevation.gnv.geobackend.sde.datasources.ResultSet#getNumberOfColumns() + */ + public int getNumberOfColumns() { + return mCols.size(); + } + + /** + * @see de.intevation.gnv.geobackend.sde.datasources.ResultSet#getColumnDefinitions() + */ + public ColDefinition[] getColumnDefinitions() { + ColDefinition[] lColDefinitions = new ColDefinition[mCols.size()]; + return mCols.toArray(lColDefinitions); + } + + /** + * @see de.intevation.gnv.geobackend.sde.datasources.ResultSet#getResults() + */ + public Row[] getResults() { + Row[] lRows = new Row[mRows.size()]; + return mRows.toArray(lRows); + } + + /** + * Add an Row to the Resultset + * @param pRow The Row that should be added. + */ + public void addRow(Row pRow) { + mRows.add(pRow); + } + + /** + * Adds a Column to the Resultset. + * @param pColDefinition The Definition of the Column + */ + public void addCol(ColDefinition pColDefinition) { + mCols.add(pColDefinition); + } + + /** + * @see java.sql.ResultSet#absolute(int) + */ + public boolean absolute(int row) throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#afterLast() + */ + public void afterLast() throws SQLException { + } + + /** + * @see java.sql.ResultSet#beforeFirst() + */ + public void beforeFirst() throws SQLException { + } + + /** + * @see java.sql.ResultSet#cancelRowUpdates() + */ + public void cancelRowUpdates() throws SQLException { + } + + /** + * @see java.sql.ResultSet#clearWarnings() + */ + public void clearWarnings() throws SQLException { + } + + /** + * @see java.sql.ResultSet#close() + */ + public void close() throws SQLException { + } + + /** + * @see java.sql.ResultSet#deleteRow() + */ + public void deleteRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#findColumn(java.lang.String) + */ + public int findColumn(String columnName) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#first() + */ + public boolean first() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#getArray(int) + */ + public Array getArray(int i) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getArray(java.lang.String) + */ + public Array getArray(String colName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getAsciiStream(int) + */ + public InputStream getAsciiStream(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getAsciiStream(java.lang.String) + */ + public InputStream getAsciiStream(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBigDecimal(int) + */ + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBigDecimal(java.lang.String) + */ + public BigDecimal getBigDecimal(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBigDecimal(int, int) + */ + public BigDecimal getBigDecimal(int columnIndex, int scale) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBigDecimal(java.lang.String, int) + */ + public BigDecimal getBigDecimal(String columnName, int scale) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBinaryStream(int) + */ + public InputStream getBinaryStream(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBinaryStream(java.lang.String) + */ + public InputStream getBinaryStream(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBlob(int) + */ + public Blob getBlob(int i) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBlob(java.lang.String) + */ + public Blob getBlob(String colName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBoolean(int) + */ + public boolean getBoolean(int columnIndex) throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#getBoolean(java.lang.String) + */ + public boolean getBoolean(String columnName) throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#getByte(int) + */ + public byte getByte(int columnIndex) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getByte(java.lang.String) + */ + public byte getByte(String columnName) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getBytes(int) + */ + public byte[] getBytes(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getBytes(java.lang.String) + */ + public byte[] getBytes(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getCharacterStream(int) + */ + public Reader getCharacterStream(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getCharacterStream(java.lang.String) + */ + public Reader getCharacterStream(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getClob(int) + */ + public Clob getClob(int i) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getClob(java.lang.String) + */ + public Clob getClob(String colName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getConcurrency() + */ + public int getConcurrency() throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getCursorName() + */ + public String getCursorName() throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getDate(int) + */ + public Date getDate(int columnIndex) throws SQLException { + try { + return new java.sql.Date(this.currentRow.getDateValue(columnIndex-1).getTime()); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getDate(java.lang.String) + */ + public Date getDate(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getDate(columnIndex); + } + + /** + * @see java.sql.ResultSet#getDate(int, java.util.Calendar) + */ + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getDate(java.lang.String, java.util.Calendar) + */ + public Date getDate(String columnName, Calendar cal) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getDouble(int) + */ + public double getDouble(int columnIndex) throws SQLException { + try { + return this.currentRow.getDoubleValue(columnIndex-1); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getDouble(java.lang.String) + */ + public double getDouble(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getDouble(columnIndex); + } + + /** + * @see java.sql.ResultSet#getFetchDirection() + */ + public int getFetchDirection() throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getFetchSize() + */ + public int getFetchSize() throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getFloat(int) + */ + public float getFloat(int columnIndex) throws SQLException { + try { + return this.currentRow.getFloatValue(columnIndex-1); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getFloat(java.lang.String) + */ + public float getFloat(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getFloat(columnIndex); + } + + /** + * @see java.sql.ResultSet#getInt(int) + */ + public int getInt(int columnIndex) throws SQLException { + + try { + return this.currentRow.getIntValue(columnIndex-1); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getInt(java.lang.String) + */ + public int getInt(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getInt(columnIndex); + } + + /** + * @see java.sql.ResultSet#getLong(int) + */ + public long getLong(int columnIndex) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getLong(java.lang.String) + */ + public long getLong(String columnName) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getMetaData() + */ + public ResultSetMetaData getMetaData() throws SQLException { + log.debug("SDEREsultSet.getMetaData"); + return new ArcSDEResultSetMetaData(this.mCols); + } + + /** + * @see java.sql.ResultSet#getObject(int) + */ + public Object getObject(int columnIndex) throws SQLException { + try { + return this.currentRow.getValue(columnIndex-1); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getObject(java.lang.String) + */ + public Object getObject(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getObject(columnIndex); + } + + /** + * @see java.sql.ResultSet#getObject(int, java.util.Map) + */ + public Object getObject(int i, Map> map) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getObject(java.lang.String, java.util.Map) + */ + public Object getObject(String colName, Map> map) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getRef(int) + */ + public Ref getRef(int i) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getRef(java.lang.String) + */ + public Ref getRef(String colName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getRow() + */ + public int getRow() throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getShort(int) + */ + public short getShort(int columnIndex) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getShort(java.lang.String) + */ + public short getShort(String columnName) throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getStatement() + */ + public Statement getStatement() throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getString(int) + */ + public String getString(int columnIndex) throws SQLException { + + try { + return this.currentRow.getStringValue(columnIndex-1); + } catch (TechnicalException e) { + log.error(e,e); + throw new SQLException(e.getMessage()); + } + } + + /** + * @see java.sql.ResultSet#getString(java.lang.String) + */ + public String getString(String columnName) throws SQLException { + int columnIndex = this.getColumnIndex(columnName); + return this.getString(columnIndex); + } + + /** + * @see java.sql.ResultSet#getTime(int) + */ + public Time getTime(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTime(java.lang.String) + */ + public Time getTime(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTime(int, java.util.Calendar) + */ + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTime(java.lang.String, java.util.Calendar) + */ + public Time getTime(String columnName, Calendar cal) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTimestamp(int) + */ + public Timestamp getTimestamp(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTimestamp(java.lang.String) + */ + public Timestamp getTimestamp(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTimestamp(int, java.util.Calendar) + */ + public Timestamp getTimestamp(int columnIndex, Calendar cal) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getTimestamp(java.lang.String, + * java.util.Calendar) + */ + public Timestamp getTimestamp(String columnName, Calendar cal) + throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getType() + */ + public int getType() throws SQLException { + + return 0; + } + + /** + * @see java.sql.ResultSet#getURL(int) + */ + public URL getURL(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getURL(java.lang.String) + */ + public URL getURL(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getUnicodeStream(int) + */ + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getUnicodeStream(java.lang.String) + */ + public InputStream getUnicodeStream(String columnName) throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#getWarnings() + */ + public SQLWarning getWarnings() throws SQLException { + + return null; + } + + /** + * @see java.sql.ResultSet#insertRow() + */ + public void insertRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#isAfterLast() + */ + public boolean isAfterLast() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#isBeforeFirst() + */ + public boolean isBeforeFirst() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#isFirst() + */ + public boolean isFirst() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#isLast() + */ + public boolean isLast() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#last() + */ + public boolean last() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#moveToCurrentRow() + */ + public void moveToCurrentRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#moveToInsertRow() + */ + public void moveToInsertRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#next() + */ + public boolean next() throws SQLException { + + boolean next = this.mRows.size() > this.cursor; + if (next){ + //log.debug("Zeile "+(cursor+1)+" von "+this.mRows.size()+" wird angesteuert."); + this.currentRow = this.mRows.get(this.cursor); + this.cursor++; + }else{ + this.currentRow = null; + } + return next; + } + + /** + * @see java.sql.ResultSet#previous() + */ + public boolean previous() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#refreshRow() + */ + public void refreshRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#relative(int) + */ + public boolean relative(int rows) throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#rowDeleted() + */ + public boolean rowDeleted() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#rowInserted() + */ + public boolean rowInserted() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#rowUpdated() + */ + public boolean rowUpdated() throws SQLException { + + return false; + } + + /** + * @see java.sql.ResultSet#setFetchDirection(int) + */ + public void setFetchDirection(int direction) throws SQLException { + } + + /** + * @see java.sql.ResultSet#setFetchSize(int) + */ + public void setFetchSize(int rows) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateArray(int, java.sql.Array) + */ + public void updateArray(int columnIndex, Array x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateArray(java.lang.String, java.sql.Array) + */ + public void updateArray(String columnName, Array x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(int, java.io.InputStream, int) + */ + public void updateAsciiStream(int columnIndex, InputStream x, int length) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(java.lang.String, + * java.io.InputStream, int) + */ + public void updateAsciiStream(String columnName, InputStream x, int length) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBigDecimal(int, java.math.BigDecimal) + */ + public void updateBigDecimal(int columnIndex, BigDecimal x) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBigDecimal(java.lang.String, + * java.math.BigDecimal) + */ + public void updateBigDecimal(String columnName, BigDecimal x) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(int, java.io.InputStream, int) + */ + public void updateBinaryStream(int columnIndex, InputStream x, int length) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(java.lang.String, + * java.io.InputStream, int) + */ + public void updateBinaryStream(String columnName, InputStream x, int length) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(int, java.sql.Blob) + */ + public void updateBlob(int columnIndex, Blob x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(java.lang.String, java.sql.Blob) + */ + public void updateBlob(String columnName, Blob x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBoolean(int, boolean) + */ + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBoolean(java.lang.String, boolean) + */ + public void updateBoolean(String columnName, boolean x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateByte(int, byte) + */ + public void updateByte(int columnIndex, byte x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateByte(java.lang.String, byte) + */ + public void updateByte(String columnName, byte x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBytes(int, byte[]) + */ + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBytes(java.lang.String, byte[]) + */ + public void updateBytes(String columnName, byte[] x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(int, java.io.Reader, int) + */ + public void updateCharacterStream(int columnIndex, Reader x, int length) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(java.lang.String, + * java.io.Reader, int) + */ + public void updateCharacterStream(String columnName, Reader reader, + int length) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(int, java.sql.Clob) + */ + public void updateClob(int columnIndex, Clob x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(java.lang.String, java.sql.Clob) + */ + public void updateClob(String columnName, Clob x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateDate(int, java.sql.Date) + */ + public void updateDate(int columnIndex, Date x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateDate(java.lang.String, java.sql.Date) + */ + public void updateDate(String columnName, Date x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateDouble(int, double) + */ + public void updateDouble(int columnIndex, double x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateDouble(java.lang.String, double) + */ + public void updateDouble(String columnName, double x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateFloat(int, float) + */ + public void updateFloat(int columnIndex, float x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateFloat(java.lang.String, float) + */ + public void updateFloat(String columnName, float x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateInt(int, int) + */ + public void updateInt(int columnIndex, int x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateInt(java.lang.String, int) + */ + public void updateInt(String columnName, int x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateLong(int, long) + */ + public void updateLong(int columnIndex, long x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateLong(java.lang.String, long) + */ + public void updateLong(String columnName, long x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNull(int) + */ + public void updateNull(int columnIndex) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNull(java.lang.String) + */ + public void updateNull(String columnName) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateObject(int, java.lang.Object) + */ + public void updateObject(int columnIndex, Object x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateObject(java.lang.String, java.lang.Object) + */ + public void updateObject(String columnName, Object x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateObject(int, java.lang.Object, int) + */ + public void updateObject(int columnIndex, Object x, int scale) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateObject(java.lang.String, java.lang.Object, + * int) + */ + public void updateObject(String columnName, Object x, int scale) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateRef(int, java.sql.Ref) + */ + public void updateRef(int columnIndex, Ref x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateRef(java.lang.String, java.sql.Ref) + */ + public void updateRef(String columnName, Ref x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateRow() + */ + public void updateRow() throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateShort(int, short) + */ + public void updateShort(int columnIndex, short x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateShort(java.lang.String, short) + */ + public void updateShort(String columnName, short x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateString(int, java.lang.String) + */ + public void updateString(int columnIndex, String x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateString(java.lang.String, java.lang.String) + */ + public void updateString(String columnName, String x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateTime(int, java.sql.Time) + */ + public void updateTime(int columnIndex, Time x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateTime(java.lang.String, java.sql.Time) + */ + public void updateTime(String columnName, Time x) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateTimestamp(int, java.sql.Timestamp) + */ + public void updateTimestamp(int columnIndex, Timestamp x) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateTimestamp(java.lang.String, + * java.sql.Timestamp) + */ + public void updateTimestamp(String columnName, Timestamp x) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#wasNull() + */ + public boolean wasNull() throws SQLException { + + return false; + } + + /** + * TODO: DOCUMENT ME + * @param columnName + * @return + * @throws SQLException + */ + private int getColumnIndex(String columnName) throws SQLException{ + for (int i = 0 ; i < this.mCols.size();i++){ + if(this.mCols.get(i).getName().equalsIgnoreCase(columnName)){ + return i +1; // PLUS 1 da SQL-Cursor 1 basiert sind + } + } + throw new SQLException("Column "+columnName+" does not exist in ResulSet"); + } + + /** + * @see java.sql.ResultSet#getHoldability() + */ + public int getHoldability() throws SQLException { + return 0; + } + + /** + * @see java.sql.ResultSet#getNCharacterStream(int) + */ + public Reader getNCharacterStream(int arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getNCharacterStream(java.lang.String) + */ + public Reader getNCharacterStream(String arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getNClob(int) + */ + public NClob getNClob(int arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getNClob(java.lang.String) + */ + public NClob getNClob(String arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getNString(int) + */ + public String getNString(int arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getNString(java.lang.String) + */ + public String getNString(String arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getRowId(int) + */ + public RowId getRowId(int arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getRowId(java.lang.String) + */ + public RowId getRowId(String arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getSQLXML(int) + */ + public SQLXML getSQLXML(int arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#getSQLXML(java.lang.String) + */ + public SQLXML getSQLXML(String arg0) throws SQLException { + return null; + } + + /** + * @see java.sql.ResultSet#isClosed() + */ + public boolean isClosed() throws SQLException { + return false; + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(int, java.io.InputStream) + */ + public void updateAsciiStream(int arg0, InputStream arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(java.lang.String, java.io.InputStream) + */ + public void updateAsciiStream(String arg0, InputStream arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(int, java.io.InputStream, long) + */ + public void updateAsciiStream(int arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateAsciiStream(java.lang.String, java.io.InputStream, long) + */ + public void updateAsciiStream(String arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(int, java.io.InputStream) + */ + public void updateBinaryStream(int arg0, InputStream arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(java.lang.String, java.io.InputStream) + */ + public void updateBinaryStream(String arg0, InputStream arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(int, java.io.InputStream, long) + */ + public void updateBinaryStream(int arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBinaryStream(java.lang.String, java.io.InputStream, long) + */ + public void updateBinaryStream(String arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(int, java.io.InputStream) + */ + public void updateBlob(int arg0, InputStream arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(java.lang.String, java.io.InputStream) + */ + public void updateBlob(String arg0, InputStream arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(int, java.io.InputStream, long) + */ + public void updateBlob(int arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateBlob(java.lang.String, java.io.InputStream, long) + */ + public void updateBlob(String arg0, InputStream arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(int, java.io.Reader) + */ + public void updateCharacterStream(int arg0, Reader arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(java.lang.String, java.io.Reader) + */ + public void updateCharacterStream(String arg0, Reader arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(int, java.io.Reader, long) + */ + public void updateCharacterStream(int arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateCharacterStream(java.lang.String, java.io.Reader, long) + */ + public void updateCharacterStream(String arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(int, java.io.Reader) + */ + public void updateClob(int arg0, Reader arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(java.lang.String, java.io.Reader) + */ + public void updateClob(String arg0, Reader arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(int, java.io.Reader, long) + */ + public void updateClob(int arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateClob(java.lang.String, java.io.Reader, long) + */ + public void updateClob(String arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNCharacterStream(int, java.io.Reader) + */ + public void updateNCharacterStream(int arg0, Reader arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNCharacterStream(java.lang.String, java.io.Reader) + */ + public void updateNCharacterStream(String arg0, Reader arg1) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNCharacterStream(int, java.io.Reader, long) + */ + public void updateNCharacterStream(int arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNCharacterStream(java.lang.String, java.io.Reader, long) + */ + public void updateNCharacterStream(String arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNClob(int, java.sql.NClob) + */ + public void updateNClob(int arg0, NClob arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNClob(java.lang.String, java.sql.NClob) + */ + public void updateNClob(String arg0, NClob arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNClob(int, java.io.Reader) + */ + public void updateNClob(int arg0, Reader arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNClob(java.lang.String, java.io.Reader) + */ + public void updateNClob(String arg0, Reader arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNClob(int, java.io.Reader, long) + */ + public void updateNClob(int arg0, Reader arg1, long arg2) + throws SQLException { + } + + public void updateNClob(String arg0, Reader arg1, long arg2) + throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNString(int, java.lang.String) + */ + public void updateNString(int arg0, String arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateNString(java.lang.String, java.lang.String) + */ + public void updateNString(String arg0, String arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateRowId(int, java.sql.RowId) + */ + public void updateRowId(int arg0, RowId arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateRowId(java.lang.String, java.sql.RowId) + */ + public void updateRowId(String arg0, RowId arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateSQLXML(int, java.sql.SQLXML) + */ + public void updateSQLXML(int arg0, SQLXML arg1) throws SQLException { + } + + /** + * @see java.sql.ResultSet#updateSQLXML(java.lang.String, java.sql.SQLXML) + */ + public void updateSQLXML(String arg0, SQLXML arg1) throws SQLException { + } + + /** + * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) + */ + public boolean isWrapperFor(Class arg0) throws SQLException { + return false; + } + + /** + * @see java.sql.Wrapper#unwrap(java.lang.Class) + */ + public T unwrap(Class arg0) throws SQLException { + return null; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/DatasourceException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/DatasourceException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.gnv.geobackend.sde.datasources.exception; + +/** + * A Class for encapsulating implementation specific datasource exceptions. + * This exception class can be used for all exceptions occuring in connection + * to "datasources actions". + * + * @author blume + * @author drewnak + * @author Tim Englich + */ +public class DatasourceException extends Exception { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 2593142889158383466L; + + /** + * Constructor + */ + public DatasourceException() { + super(); + } + + /** + * Constructor + * @param pMessage the Exceptionmessage + */ + public DatasourceException(String pMessage) { + super(pMessage); + } + + /** + * Constructor + * @param pMessage the Exceptionmessage + * @param pCause the Throwable which cause this exception + */ + public DatasourceException(String pMessage, Throwable pCause) { + super(pMessage, pCause); + } + + /** + * Constructor + * @param pCause the Throwable which cause this exception + */ + public DatasourceException(Throwable pCause) { + super(pCause); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/TechnicalException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/TechnicalException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,68 @@ +package de.intevation.gnv.geobackend.sde.datasources.exception; + +import org.apache.log4j.Logger; + +/** + * The class TechnicalException fulfills the following purposes: + * + * @author blume + * @author Tim Englich + */ +public class TechnicalException extends Exception{ + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -5296559414323169553L; + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(TechnicalException.class); + + /** + * Constructs a new exception with null as its detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + */ + public TechnicalException() { + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public TechnicalException(String message) { + super(message); + } + + /** + * Constructor + * @param pCause the Throwable which cause this exception + */ + public TechnicalException(Throwable pCause) { + super(pCause); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * cause is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public TechnicalException(String message, Throwable cause) { + super(message, cause); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Package that contains Exceptionclasses for it's Parentpackage. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,12 @@ + + + + + +This package contains Classes that Wrapps an ArcSDEConnection into a +java.sql.Connection. +All other required Wrapper-Classes +(e.g Statements,ResultSet, ResultSetMetadata) +are also available in the package. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package and it's subpackages contains Classes for the DataAccess to +the ArcSDE-Databasebackend. + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/util/DateUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,91 @@ +/** + * Title: DateUtisl, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/util/DateUtils.java,v 1.2 2008/08/18 14:50:33 drewnak Exp $ + * Source: $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/util/DateUtils.java,v $ + * created by: Stefan Blume (blume) + * erstellt am: 21.12.2007 + * Copyright: con terra GmbH, 2005 + * + * modified by: $Author: drewnak $ + * modified on: $Date: 2008/08/18 14:50:33 $ + * Version: $Revision: 1.2 $ + * TAG: $Name: $ + * locked from: $Locker: $ + * CVS State: $State: Exp $ + * Project: $ProjectName$ + */ +package de.intevation.gnv.geobackend.util; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.log4j.Logger; + +/** + * The class DateUtils fulfills the following purposes: + * @author blume + * @author Tim Englich + */ +public class DateUtils { + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(DateUtils.class); + + /** + * The Dateformat which will be used e.g for Querying the Database + */ + public static final String DATE_PATTERN = "yyyy.MM.dd HH:mm:ss"; + + private static final String DATE_PATTERN1 = "dd-MMM-yyyy HH:mm:ss"; + + /** + * The Method returns a Date using the given pattern as a String + * @param pDate The Date which should be formatted + * @param sPattern The Pattern which should be used. + * @return the Date formatted a a String + */ + public static String getPatternedDate(Date pDate, String sPattern) { + SimpleDateFormat fmt = new SimpleDateFormat(); + fmt.applyPattern(sPattern); + return fmt.format(pDate); + } + + /** + * Returns the Date as a String formated using the + * DateUtils.DATE_PATTERN format- + * @param pDate the Date which should be formatted + * @return the given Data as a String + */ + public static String getPatternedDateAmer(Date pDate) { + String sStr = getPatternedDate(pDate, DATE_PATTERN); + return sStr; + } + + /** + * This method decodes a Datevalue from the given String useing the + * DateUtils.DATE_PATTERN1 format- + * @param sStr The String which contains the encoded Datevalue + * @return the decoded Datevalue as an Date-object. + * @throws Exception throws all Expetion which occurs during the Process. + */ + public static Date getDateFromString (String sStr)throws Exception { + Date date = getDateFromString (sStr, DATE_PATTERN1); + return date; + } + + /** + * Formats a given Date encoded as a String using the given Pattern + * into a Date Object. + * @param sStr The String with the encoded DateValue + * @param sPattern The pattern which should be used to decode the Date + * @return the given Datevalue as an Date-Object. + * @throws Exception throws all Expetion which occurs during the Process. + */ + public static Date getDateFromString (String sStr, + String sPattern)throws Exception { + SimpleDateFormat fmt = new SimpleDateFormat(); + fmt.applyPattern(sPattern); + return fmt.parse(sStr); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/util/RedundancyRemover.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/util/RedundancyRemover.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,56 @@ +package de.intevation.gnv.geobackend.util; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Sascha L. Teichmann + */ +public final class RedundancyRemover +extends LinkedHashMap +{ + /** ceil(1029 * 1.75) = 1801, which is prime + * -> suitable for a hash map slot size. + */ + public static final int DEFAULT_LOOKBACK = + Integer.getInteger( + "de.intevation.gnv.geobackend.util.RedundancyRemover.lookback", + 1029); + + private int maxCapacity; + private int removed; + + public RedundancyRemover() { + this(DEFAULT_LOOKBACK); + } + + public RedundancyRemover(int maxCapacity) { + super((int)Math.ceil(maxCapacity * 1.75f)); + this.maxCapacity = maxCapacity; + } + + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > maxCapacity; + } + + public int numRemoved() { + return removed; + } + + public Object filter(Object object) { + if (object == null) { + return object; + } + Object old = get(object); + + if (old != null) { + if (old != object) { // count only identical + ++removed; + } + return old; + } + put(object, object); + return object; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/main/java/de/intevation/gnv/geobackend/util/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/util/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Package that contains utility-Classes for this Module + + diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/GroupBySample.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/GroupBySample.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,123 @@ +package de.intevation.gnv.geobackend.base.query; + +import com.esri.sde.sdk.client.SDEPoint; +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeFilter; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeQueryInfo; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeShape; +import com.esri.sde.sdk.client.SeShapeFilter; +import com.esri.sde.sdk.client.SeSqlConstruct; + +public class GroupBySample { + + + public void executeQuery(SeConnection con, String[] pLayername, + String pSpatialColumnName, String pWhere, + SDEPoint[] g, String[] pReturnFields, String byClause) { + + try { + // get the layer for querying + + SeShapeFilter[] filters = null; + if (g != null){ + SeLayer lLayer = new SeLayer(con, pLayername[0], pSpatialColumnName); + SeShape shape = new SeShape(); + shape.setCoordRef(lLayer.getCoordRef()); + + + + shape.generatePolygon(g.length, 1, null, g); + SeShapeFilter filter = new SeShapeFilter(pLayername[0], + pSpatialColumnName, shape, SeFilter.METHOD_AI); + filters = new SeShapeFilter[1]; + filters[0] = filter; + } + + SeQuery spatialQuery = null; + SeSqlConstruct sqlCons = new SeSqlConstruct(pLayername, pWhere); + spatialQuery = new SeQuery(con); + + SeQueryInfo queryInfo = new SeQueryInfo(); + queryInfo.setColumns(pReturnFields); + + if (byClause != null){ + queryInfo.setByClause(byClause); + } + + queryInfo.setConstruct(sqlCons); + spatialQuery.prepareQueryInfo(queryInfo); + + /* + * Set spatial constraints + */ + if (filters != null){ + spatialQuery.setSpatialConstraints(SeQuery.SE_OPTIMIZE, false, + filters); + } + spatialQuery.execute(); + + SeRow row; + int lCount; + for (lCount = 0; (row =spatialQuery.fetch()) != null; lCount++) { + // one time execution + if (lCount == 0) { + // analyze cols of result set + SeColumnDefinition[] lCols = row.getColumns(); + + } + short lNumCols = row.getNumColumns(); + + for (int i = 0; i < lNumCols; i++) { + System.out.println(row.getObject(i)); + } + + } + spatialQuery.close(); + + } catch (Exception e){ + e.printStackTrace(); + } + + } + + + /** + * @param args + */ + public static void main(String[] args) { + + try { + String[] layerNames = new String[] { "median.meshpoint", "median.mesh" }; + String spatialColumnName = "SHAPE"; + String where = "median.meshpoint.meshid = median.mesh.meshid"; + String[] returnFields = new String[] { "sourceid" }; + String byClause = "group by sourceid"; + SDEPoint[] g = new SDEPoint[5]; + g[0] = new SDEPoint(52, 8); + g[1] = new SDEPoint(52, 9); + g[2] = new SDEPoint(53, 9); + g[3] = new SDEPoint(53, 8); + g[4] = new SDEPoint(52, 8); + + String server = ""; + String port = ""; + String database = ""; + String username = ""; + String credentials = ""; + SeConnection con = new SeConnection(server, port, + database, username, + credentials); + new GroupBySample().executeQuery(con, layerNames, spatialColumnName, + where, g, returnFields, byClause); + + + } catch (SeException e) { + e.printStackTrace(); + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/QueryExecutorTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,190 @@ +package de.intevation.gnv.geobackend.base.query; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; + +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import java.io.FileInputStream; +import java.io.InputStream; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Properties; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +/** + * TestCase for the QueryExecutor interface + * @author Tim Englich + * + */ +public class QueryExecutorTestCase extends TestCase { + + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static{ + BasicConfigurator.configure(); + log = Logger.getLogger(QueryExecutorTestCase.class); + } + + /** + * Constructor + * @param name + */ + public QueryExecutorTestCase(String name) { + super(name); + } + + + public void testSpatialQuery(){ + try { + + this.testQuery(5, "spatial_query", null); + } catch (QueryException e) { + log.error(e,e); + fail(); + } + } + + public void testSpatialQueryWithoutIntersects(){ + try { +// this.testQuery(286, "spatial_query_without_intersects", null); + this.testQuery(0, "spatial_query_without_intersects2", null); + this.testQuery(2060, "spatial_query_without_intersects3", null); + this.testQuery(0, "spatial_query_without_intersects4", null); + this.testQuery(27031, "spatial_query_without_intersects5", null); + this.testQuery(8464, "spatial_query_without_intersects6", null); + } catch (QueryException e) { + log.error(e,e); + fail(); + } + } + + public void testSpatialQueryWithInnerSelect(){ + try { + this.testQuery(1998, "spatial_query_with_innerselect", null); + } catch (QueryException e) { + log.error(e,e); + fail(); + } + } + + + public void testChooseFis(){ + try { + this.testQuery(1, "choose_fis_query", null); + } catch (QueryException e) { + log.error(e, e); + fail(); + } + } + + + /** + * Tests if the Databaseconnection can be established and + * Data could be read from the Database + */ + public void testQueryExecutor(){ + + try { + + this.testQuery(6, "mesh", null); + + this.testQuery(1, "mesh_id", new String[]{"5"}); + + + + } catch (QueryException e) { + log.error(e,e); + fail(); + } + } + + public void testTimeSeriesQueries(){ + + try{ + // Test zum initialisieren der umgebung + this.testQuery(6, "mesh", null); + + + this.testQuery(11, "timeseries_stations", new String[]{"4"}); + this.testQuery(11, "timeseries_stations_op", new String[]{"4"}); + this.testQuery(1, "timeseries_interval", new String[]{"500042 ", "54"}); + + } catch (QueryException e) { + log.error(e,e); + fail(); + } + + } + + /** + * @param resultsize + * @param queryID + * @param filter + * @throws QueryException + */ + private void testQuery(int resultsize, String queryID, String[] filter) + throws QueryException { + long start = System.currentTimeMillis(); + QueryExecutor queryExecutor = QueryExecutorFactory.getInstance().getQueryExecutor(); + Collection results = queryExecutor.executeQuery(queryID, filter); +// if (results == null || results.size() == 0){ +// log.error("Keine Daten erhalten"); +// fail(); +// }else { + assertEquals(resultsize, results.size()); + log.debug(resultsize+" Datensätze erhalten"); + Iterator it = results.iterator(); + while (it.hasNext()){ + Result tmpResult = it.next(); + ResultDescriptor resultDescriptor = tmpResult.getResultDescriptor(); + int columns = resultDescriptor.getColumnCount(); + for (int i = 0; i < columns; i++){ + String columnName = resultDescriptor.getColumnName(i); + Object value = tmpResult.getString(columnName); + log.debug(columnName + " ==> "+value.toString()); + } + } +// } + log.debug("Query dauerte: "+(System.currentTimeMillis()-start) +"ms"); + } + + + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + + super.setUp(); + InputStream inputStream = new FileInputStream("src/test/ressources/ArcSDEConnectionPoolTestCase.properties"); + Properties properties = new Properties(); + properties.load(inputStream); + + ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance(); + cpf.initializeConnectionPool(properties); + + + inputStream = new FileInputStream("src/test/ressources/QueryExecutorTestCase.properties"); + properties = new Properties(); + properties.load(inputStream); + + QueryContainerFactory qcf = QueryContainerFactory.getInstance(); + qcf.initializeQueryContainer(properties); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/ToCharSample.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/ToCharSample.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,132 @@ +package de.intevation.gnv.geobackend.base.query; + +import com.esri.sde.sdk.client.SDEPoint; +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeFilter; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeQueryInfo; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeShape; +import com.esri.sde.sdk.client.SeShapeFilter; +import com.esri.sde.sdk.client.SeSqlConstruct; + +public class ToCharSample { + + + public boolean executeQuery(SeConnection con, String[] pLayername, + String pSpatialColumnName, String pWhere, + SDEPoint[] g, String[] pReturnFields, String byClause) { + + try { + // get the layer for querying + + SeShapeFilter[] filters = null; + if (g != null){ + SeLayer lLayer = new SeLayer(con, pLayername[0], pSpatialColumnName); + SeShape shape = new SeShape(); + shape.setCoordRef(lLayer.getCoordRef()); + + + + shape.generatePolygon(g.length, 1, null, g); + SeShapeFilter filter = new SeShapeFilter(pLayername[0], + pSpatialColumnName, shape, SeFilter.METHOD_AI); + filters = new SeShapeFilter[1]; + filters[0] = filter; + } + + SeQuery spatialQuery = null; + SeSqlConstruct sqlCons = new SeSqlConstruct(pLayername, pWhere); + spatialQuery = new SeQuery(con); + + SeQueryInfo queryInfo = new SeQueryInfo(); + queryInfo.setColumns(pReturnFields); + + if (byClause != null){ + queryInfo.setByClause(byClause); + } + + queryInfo.setConstruct(sqlCons); + spatialQuery.prepareQueryInfo(queryInfo); + + /* + * Set spatial constraints + */ + if (filters != null){ + spatialQuery.setSpatialConstraints(SeQuery.SE_OPTIMIZE, false, + filters); + } + spatialQuery.execute(); + + SeRow row; + int lCount; + for (lCount = 0; (row =spatialQuery.fetch()) != null; lCount++) { + // one time execution + if (lCount == 0) { + // analyze cols of result set + SeColumnDefinition[] lCols = row.getColumns(); + + } + short lNumCols = row.getNumColumns(); + + for (int i = 0; i < lNumCols; i++) { + System.out.println(row.getObject(i)); + } + + } + spatialQuery.close(); + return true; + } catch (Exception e){ + e.printStackTrace(); + return false; + } + + } + + + /** + * @param args + */ + public static void main(String[] args) { + + try { + + String[] layerNames = new String[] { "MEDIAN.TRACK" }; + String spatialColumnName = "SHAPE"; + String where = "MEDIAN.TRACK.CRUISEID = 47"; + String[] returnFields = new String[] { "MEDIAN.TRACK.TRACKID KEY", + "to_char(STARTDATE,'DD.MM.YYYY HH24:MI') || ' - '|| to_char(ENDDATE,'DD.MM.YYYY HH24:MI') || ' - '|| NAME VALUE", + "NAME" }; + String byClause = "ORDER BY STARTDATE, ENDDATE, NAME"; + SDEPoint[] g = new SDEPoint[5]; + g[0] = new SDEPoint(52, 8); + g[1] = new SDEPoint(52, 9); + g[2] = new SDEPoint(53, 9); + g[3] = new SDEPoint(53, 8); + g[4] = new SDEPoint(52, 8); + + String server = ""; + String port = ""; + String database = ""; + String username = ""; + String credentials = ""; + + SeConnection con = new SeConnection(server, port, + database, username, + credentials); + boolean success = new ToCharSample().executeQuery(con, layerNames, spatialColumnName, + where, g, returnFields, byClause); + + if (success){ + System.out.println("Terminated successful."); + }else{ + System.out.println("Terminated with an Exception."); + } + } catch (SeException e) { + e.printStackTrace(); + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleanerTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleanerTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,59 @@ +package de.intevation.gnv.geobackend.base.query.cache; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Properties; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; + +public class CacheCleanerTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static{ + BasicConfigurator.configure(); + log = Logger.getLogger(CacheCleanerTestCase.class); + } + + public void testCachCleaner(){ + log.debug("CacheCleanerTestCase.testCachCleaner"); + CacheCleaner cc = new CacheCleaner(); + boolean success = cc.test(); + if (!success){ + log.error("TestCase failed."); + fail(); + } + } + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + + super.setUp(); + InputStream inputStream = new FileInputStream("src/test/ressources/ArcSDEConnectionPoolTestCase.properties"); + Properties properties = new Properties(); + properties.load(inputStream); + + ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance(); + cpf.initializeConnectionPool(properties); + + + inputStream = new FileInputStream("src/test/ressources/QueryExecutorTestCase.properties"); + properties = new Properties(); + properties.load(inputStream); + + QueryContainerFactory qcf = QueryContainerFactory.getInstance(); + qcf.initializeQueryContainer(properties); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnectionPoolTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEConnectionPoolTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,124 @@ +package de.intevation.gnv.geobackend.sde.datasources; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPool; +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; + +import de.intevation.gnv.geobackend.base.connectionpool.exception.ConnectionException; + +import de.intevation.gnv.geobackend.sde.connectionpool.ArcSDEPoolableObjectFactory; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import java.util.Properties; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +/** + * TestCase for the usage of the ArcSDEConnectionPool. + * @author Tim Englich + * + */ +public class ArcSDEConnectionPoolTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(ArcSDEPoolableObjectFactory.class); + } + /** + * + */ + public ArcSDEConnectionPoolTestCase() { + super(); + } + + /** + * + * @param name + */ + public ArcSDEConnectionPoolTestCase(String name) { + super(name); + } + + /** + * Test if the ArcSDEConnectionPool can be established + * and if a Request could be done. + */ + public void testArcSDEConnectionPool(){ + log.debug("ArcSDEConnectionPoolTestCase.testArcSDEConnectionPool"); + try { + InputStream inputStream = new FileInputStream("src/test/ressources/ArcSDEConnectionPoolTestCase.properties"); + Properties properties = new Properties(); + properties.load(inputStream); + + ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance(); + cpf.initializeConnectionPool(properties); + + assertTrue(cpf.isInitialized()); + log.debug("ConnectionPoolFactory ist initialisiert."); + + ConnectionPool cp = cpf.getConnectionPool(); + assertNotNull(cp); + log.debug("ConnectionPool ist initialisiert."); + + Connection connection = null; + try{ + try { + connection = cp.getConnection("N/N"); + assertNotNull(connection); + log.debug("Connection ist initialisiert."); + } catch (ConnectionException e) { + log.error("Es traten Probleme bei der Verbinung zur Datenbank auf."); + fail(); + } + + + try { + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("Select MESHID, NAME from MEDIAN.MESH"); + + while (rs.next()){ + log.debug(rs.getInt(1)); + log.debug(rs.getString(2)); + + log.debug(rs.getInt("MESHID")); + log.debug(rs.getString("NAME")); + } + + } catch (SQLException e) { + log.error(e,e); + } + }finally{ + if (connection != null){ + try { + connection.close(); + } catch (SQLException e) { + log.error(e,e); + fail(); + } + } + } + } catch (FileNotFoundException e) { + log.error(e,e); + fail(); + } catch (IOException e) { + log.error(e,e); + fail(); + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/ressources/ArcSDEConnectionPoolTestCase.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/ressources/ArcSDEConnectionPoolTestCase.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ +maxActive=2 +testOnBorrow=true +testOnReturn=false +testWhileIdle=false +timeBetweenEvictionRunsMillis=360000 +server=localhost +username=gast +credentials=gast +port=22119 +database=esri_sde \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 geo-backend/src/test/ressources/QueryExecutorTestCase.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/test/ressources/QueryExecutorTestCase.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,104 @@ +mesh=Select MESHID, NAME from MEDIAN.MESH +mesh_id=Select MESHID, NAME from MEDIAN.MESH where MESHID = ? + + + +# Timeseries +timeseries_stations=SELECT tsp.FEATUREID, tsp.NAME FROM MEDIAN.TIMESERIESPOINT tsp WHERE tsp.FEATUREID IN (SELECT DISTINCT mmt.FEATUREID FROM MEDIAN.MEASUREMENT mmt WHERE mmt.SOURCEID IN ( 4 )) order by tsp.name +timeseries_stations_op=SELECT DISTINCT tsp.FEATUREID, tsp.NAME FROM MEDIAN.TIMESERIESPOINT tsp, MEDIAN.MEASUREMENT mmt WHERE tsp.FEATUREID = mmt.FEATUREID AND mmt.SOURCEID IN ( 4 ) order by tsp.name +timeseries_interval=select min(tv.TIMEVALUE) MIN, max(tv.TIMEVALUE) MAX from MEDIAN.TIMESERIES t , MEDIAN.TIMESERIESVALUE tv where tv.TIMESERIESID = t.TIMESERIESID and tv.MEASUREMENTID IN ( ? ) AND t.PARAMETERID IN ( ? ) + + + + spatial_query=SELECT FEATUREID, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.MESHPOINT \ + WHERE MESHID in \ + (SELECT DISTINCT m.MESHID \ + FROM MEDIAN.MESH m \ + WHERE M.OBJECTID = M.OBJECTID) AND \ + KPOSITION = 1 AND \ + INTERSECTS(SHAPE,"POLYGON((6.483333296817733 56.50000002211891,6.483012102287745 56.50981053688071,6.48205002744038 56.51957897448855,6.480451095589132 56.52926359306454,6.478222179894658 56.538822818368885,6.475372835726546 56.54821591435217,6.471915300663454 56.557402480241024,6.46786415921693 56.56634328872852,6.463237181021697 56.57500011833619,6.458053812093169 56.583335585775785,6.452336348293812 56.591314319415915,6.446109264780915 56.59890195345352,6.439399383644684 56.60606613374233,6.432235203355873 56.61277601487856,6.424647569318296 56.61900309839146,6.416668835678138 56.62472056219082,6.408333368238544 56.629903931119344,6.399676538630871 56.63453090931458,6.390735730143376 56.6385820507611,6.381549164254523 56.64203958582419,6.372156068271238 56.644888929992305,6.362596842966894 56.64711784568678,6.352912224390906 56.64871677753803,6.34314378678306 56.64967885238539,6.333333272021264 56.65000004691538,6.323522757259468 56.64967885238539,6.31375431965165 56.64871677753803,6.304069701075662 56.64711784568678,6.29451047577129 56.644888929992305,6.285117379788005 56.64203958582419,6.27593081389918 56.6385820507611,6.266990005411657 56.63453090931458,6.258333343442075 56.629903931119344,6.24999770836439 56.62472056219082,6.24201897472426 56.61900309839146,6.234431340686655 56.61277601487856,6.227267160397872 56.60606613374233,6.220557279261612 56.59890195345352,6.214330195748715 56.591314319415915,6.2086127319493585 56.583335585775785,6.203429363020831 56.57500011833619,6.198802384825626 56.56634328872852,6.194751243379102 56.557402480241024,6.19129370831601 56.54821591435217,6.188444364147898 56.538822818368885,6.186215448453396 56.52926359306454,6.184616516602176 56.51957897448855,6.183654441754783 56.50981053688071,6.183333247224795 56.50000002211891,6.183654441754783 56.490189507357115,6.184616516602176 56.4804210697493,6.186215448453396 56.47073645117331,6.188444364147898 56.46117722586894,6.19129370831601 56.45178412988565,6.194751243379102 56.44259756399683,6.198802384825626 56.433656755509304,6.203429363020831 56.42500009353972,6.2086127319493585 56.41666445846204,6.214330195748715 56.40868572482191,6.220557279261612 56.4010980907843,6.227267160397872 56.39393391049552,6.234431340686655 56.38722402935926,6.24201897472426 56.38099694584636,6.24999770836439 56.375279482047006,6.258333343442075 56.37009611311848,6.266990005411657 56.36546913492327,6.27593081389918 56.36141799347675,6.285117379788005 56.35796045841366,6.29451047577129 56.355111114245545,6.304069701075662 56.35288219855104,6.31375431965165 56.351283266699795,6.323522757259468 56.35032119185243,6.333333272021264 56.34999999732244,6.34314378678306 56.35032119185243,6.352912224390906 56.351283266699795,6.362596842966894 56.35288219855104,6.372156068271238 56.355111114245545,6.381549164254523 56.35796045841366,6.390735730143376 56.36141799347675,6.399676538630871 56.36546913492327,6.408333368238544 56.37009611311848,6.416668835678138 56.375279482047006,6.424647569318296 56.38099694584636,6.432235203355873 56.38722402935926,6.439399383644684 56.39393391049552,6.446109264780915 56.4010980907843,6.452336348293812 56.40868572482191,6.458053812093169 56.41666445846204,6.463237181021697 56.42500009353972,6.46786415921693 56.433656755509304,6.471915300663454 56.44259756399683,6.475372835726546 56.45178412988565,6.478222179894658 56.46117722586894,6.480451095589132 56.47073645117331,6.48205002744038 56.4804210697493,6.483012102287745 56.490189507357115,6.483333296817733 56.50000002211891))") + +spatial_query_without_intersects = SELECT ST_ASTEXT(SHAPE), \ + MSV.DATAVALUE YORDINATE , \ + MSV.PARAMETERID GROUP1 , \ + M.ZLOCATION GROUP2, \ + 1 GROUP3 \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE MEDIAN.INSTANTANEOUSPOINT.FEATUREID =m.FEATUREID AND \ + m.MEASUREMENTID = MSV.MEASUREMENTID AND \ + MEDIAN.INSTANTANEOUSPOINT.SURVEYID = 1895 AND \ + m.ZLOCATION IN (-16.843 , -15.852) AND \ + MSV.PARAMETERID in (2 , 1) \ + ORDER BY MSV.PARAMETERID, \ + m.ZLOCATION + +spatial_query_without_intersects2 = SELECT ST_ASTEXT(SHAPE), \ + msv.DATAVALUE YORDINATE, \ + msv.PARAMETERID GROUP1, \ + msv.TIMEVALUE GROUP2, \ + MEDIAN.MESHPOINT.KPOSITION GROUP3, \ + MEDIAN.MESHPOINT.JPOSITION , \ + MEDIAN.MESHPOINT.IPOSITION \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT , \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = MEDIAN.MESHPOINT.FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (2,1) AND \ + msv.TIMEVALUE in (to_date('2009.10.15 23:00:00', 'YYYY.MM.DD HH24:MI:SS')) AND \ + m.OBJECTID = 3 AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = 3 AND \ + mp.MESHID = m.MESHID AND \ + KPOSITION in ( 1 ) and \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = 2003771)) \ + order by MEDIAN.MESHPOINT.KPOSITION, \ + msv.TIMEVALUE, \ + msv.PARAMETERID, \ + MEDIAN.MESHPOINT.JPOSITION , \ + MEDIAN.MESHPOINT.IPOSITION + + +spatial_query_without_intersects3 = SELECT ST_ASTEXT(SHAPE), MSV.DATAVALUE YORDINATE, MEDIAN.MESHFACE.JPOSITION, MEDIAN.MESHFACE.IPOSITION, MEDIAN.MESHFACE.KPOSITION from MEDIAN.MESHLAYER ML, MEDIAN.MESHFACE, MEDIAN.MESH M, MEDIAN.MESHSCALARVALUE MSV where MSV.FEATUREID = MEDIAN.MESHFACE.FEATUREID AND ML.KPOSITION = MEDIAN.MESHFACE.KPOSITION and ML.MESHID = MEDIAN.MESHFACE.MESHID and M.MESHID = MEDIAN.MESHFACE.MESHID AND M.PARTIDMIN <= MSV.PARTID AND M.PARTIDMAX >= MSV.PARTID AND MSV.PARAMETERID = 1 AND MSV.TIMEVALUE = to_date('2007.01.03 00:00:00', 'YYYY.MM.DD HH24:MI:SS') AND M.OBJECTID = 2 AND MEDIAN.MESHFACE.KPOSITION = 1 order by MEDIAN.MESHFACE.JPOSITION , MEDIAN.MESHFACE.IPOSITION +spatial_query_without_intersects4 = SELECT ST_ASTEXT(SHAPE), MSV.DATAVALUE YORDINATE, MEDIAN.MESHFACE.JPOSITION, MEDIAN.MESHFACE.IPOSITION, MEDIAN.MESHFACE.KPOSITION from MEDIAN.MESHLAYER ML, MEDIAN.MESHFACE, MEDIAN.MESH M, MEDIAN.MESHSCALARVALUE MSV where MSV.FEATUREID = MEDIAN.MESHFACE.FEATUREID AND ML.KPOSITION = MEDIAN.MESHFACE.KPOSITION and ML.MESHID = MEDIAN.MESHFACE.MESHID and M.MESHID = MEDIAN.MESHFACE.MESHID AND M.PARTIDMIN <= MSV.PARTID AND M.PARTIDMAX >= MSV.PARTID AND MSV.PARAMETERID = 1 AND MSV.TIMEVALUE = to_date('2008.01.15 12:00:00', 'YYYY.MM.DD HH24:MI:SS') AND M.OBJECTID = 321 AND MEDIAN.MESHFACE.KPOSITION = 1 order by MEDIAN.MESHFACE.JPOSITION , MEDIAN.MESHFACE.IPOSITION +spatial_query_without_intersects5 = SELECT ST_ASTEXT(SHAPE), MSV.DATAVALUE YORDINATE, MEDIAN.MESHFACE.JPOSITION, MEDIAN.MESHFACE.IPOSITION, MEDIAN.MESHFACE.KPOSITION from MEDIAN.MESHLAYER ML, MEDIAN.MESHFACE, MEDIAN.MESH M, MEDIAN.MESHSCALARVALUE MSV where MSV.FEATUREID = MEDIAN.MESHFACE.FEATUREID AND ML.KPOSITION = MEDIAN.MESHFACE.KPOSITION and ML.MESHID = MEDIAN.MESHFACE.MESHID and M.MESHID = MEDIAN.MESHFACE.MESHID AND M.PARTIDMIN <= MSV.PARTID AND M.PARTIDMAX >= MSV.PARTID AND MSV.PARAMETERID = 2 AND MSV.TIMEVALUE = to_date('2009.10.23 01:00:00', 'YYYY.MM.DD HH24:MI:SS') AND M.OBJECTID = 1 AND MEDIAN.MESHFACE.KPOSITION = 1 order by MEDIAN.MESHFACE.JPOSITION , MEDIAN.MESHFACE.IPOSITION +spatial_query_without_intersects6 = SELECT ST_ASTEXT(SHAPE), MSV.DATAVALUE YORDINATE, MEDIAN.MESHFACE.JPOSITION, MEDIAN.MESHFACE.IPOSITION, MEDIAN.MESHFACE.KPOSITION from MEDIAN.MESHLAYER ML, MEDIAN.MESHFACE, MEDIAN.MESH M, MEDIAN.MESHSCALARVALUE MSV where MSV.FEATUREID = MEDIAN.MESHFACE.FEATUREID AND ML.KPOSITION = MEDIAN.MESHFACE.KPOSITION and ML.MESHID = MEDIAN.MESHFACE.MESHID and M.MESHID = MEDIAN.MESHFACE.MESHID AND M.PARTIDMIN <= MSV.PARTID AND M.PARTIDMAX >= MSV.PARTID AND MSV.PARAMETERID = 2 AND MSV.TIMEVALUE = to_date('2009.10.23 01:00:00', 'YYYY.MM.DD HH24:MI:SS') AND M.OBJECTID = 3 AND MEDIAN.MESHFACE.KPOSITION = 1 order by MEDIAN.MESHFACE.JPOSITION , MEDIAN.MESHFACE.IPOSITION + + + +choose_fis_query = select m.sourceid, \ + from median.meshpoint ,\ + median.mesh \ + where median.meshpoint.meshid = median.mesh.meshid and \ + INTERSECTS(SHAPE,"POLYGON((6.483333296817733 56.50000002211891,6.483012102287745 56.50981053688071,6.48205002744038 56.51957897448855,6.480451095589132 56.52926359306454,6.478222179894658 56.538822818368885,6.475372835726546 56.54821591435217,6.471915300663454 56.557402480241024,6.46786415921693 56.56634328872852,6.463237181021697 56.57500011833619,6.458053812093169 56.583335585775785,6.452336348293812 56.591314319415915,6.446109264780915 56.59890195345352,6.439399383644684 56.60606613374233,6.432235203355873 56.61277601487856,6.424647569318296 56.61900309839146,6.416668835678138 56.62472056219082,6.408333368238544 56.629903931119344,6.399676538630871 56.63453090931458,6.390735730143376 56.6385820507611,6.381549164254523 56.64203958582419,6.372156068271238 56.644888929992305,6.362596842966894 56.64711784568678,6.352912224390906 56.64871677753803,6.34314378678306 56.64967885238539,6.333333272021264 56.65000004691538,6.323522757259468 56.64967885238539,6.31375431965165 56.64871677753803,6.304069701075662 56.64711784568678,6.29451047577129 56.644888929992305,6.285117379788005 56.64203958582419,6.27593081389918 56.6385820507611,6.266990005411657 56.63453090931458,6.258333343442075 56.629903931119344,6.24999770836439 56.62472056219082,6.24201897472426 56.61900309839146,6.234431340686655 56.61277601487856,6.227267160397872 56.60606613374233,6.220557279261612 56.59890195345352,6.214330195748715 56.591314319415915,6.2086127319493585 56.583335585775785,6.203429363020831 56.57500011833619,6.198802384825626 56.56634328872852,6.194751243379102 56.557402480241024,6.19129370831601 56.54821591435217,6.188444364147898 56.538822818368885,6.186215448453396 56.52926359306454,6.184616516602176 56.51957897448855,6.183654441754783 56.50981053688071,6.183333247224795 56.50000002211891,6.183654441754783 56.490189507357115,6.184616516602176 56.4804210697493,6.186215448453396 56.47073645117331,6.188444364147898 56.46117722586894,6.19129370831601 56.45178412988565,6.194751243379102 56.44259756399683,6.198802384825626 56.433656755509304,6.203429363020831 56.42500009353972,6.2086127319493585 56.41666445846204,6.214330195748715 56.40868572482191,6.220557279261612 56.4010980907843,6.227267160397872 56.39393391049552,6.234431340686655 56.38722402935926,6.24201897472426 56.38099694584636,6.24999770836439 56.375279482047006,6.258333343442075 56.37009611311848,6.266990005411657 56.36546913492327,6.27593081389918 56.36141799347675,6.285117379788005 56.35796045841366,6.29451047577129 56.355111114245545,6.304069701075662 56.35288219855104,6.31375431965165 56.351283266699795,6.323522757259468 56.35032119185243,6.333333272021264 56.34999999732244,6.34314378678306 56.35032119185243,6.352912224390906 56.351283266699795,6.362596842966894 56.35288219855104,6.372156068271238 56.355111114245545,6.381549164254523 56.35796045841366,6.390735730143376 56.36141799347675,6.399676538630871 56.36546913492327,6.408333368238544 56.37009611311848,6.416668835678138 56.375279482047006,6.424647569318296 56.38099694584636,6.432235203355873 56.38722402935926,6.439399383644684 56.39393391049552,6.446109264780915 56.4010980907843,6.452336348293812 56.40868572482191,6.458053812093169 56.41666445846204,6.463237181021697 56.42500009353972,6.46786415921693 56.433656755509304,6.471915300663454 56.44259756399683,6.475372835726546 56.45178412988565,6.478222179894658 56.46117722586894,6.480451095589132 56.47073645117331,6.48205002744038 56.4804210697493,6.483012102287745 56.490189507357115,6.483333296817733 56.50000002211891))") \ + group by sourceid + + +spatial_query_with_innerselect = SELECT M.OBJECTID KEY, \ + M.NAME VALUE \ + FROM MEDIAN.MESHPOINT, \ + MEDIAN.MESH M \ + WHERE M.SOURCEID IN (2) AND \ + M.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) FROM MEDIAN.FEATUREAREA WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND FEATURECODE = 41 )\ + ) \ + order by M.NAME +test_regionfilter = SELECT M.OBJECTID KEY, M.NAME VALUE FROM MEDIAN.MESHPOINT, MEDIAN.MESH M WHERE M.SOURCEID IN (2) AND M.MESHID = MEDIAN.MESHPOINT.MESHID AND INTERSECTS(SHAPE, (SELECT st_astext(SHAPE) FROM MEDIAN.FEATUREAREA WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND FEATURECODE = ? )) order by M.NAME + + +updated_tables = SELECT FULLTABLENAME \ + FROM MEDIAN.LASTUPDATED \ + WHERE LASTUPDATE >= to_date('?', 'YYYY.MM.DD HH24:MI:SS') diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/ChangeLog Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7135 @@ +2010-04-28 Ingo Weinzierl + + * doc/conf/maptemplates/layer_polygon.vm: Do not use point symbols to draw + polygons. + +2010-04-28 Ingo Weinzierl + + * NEWS, Changes: Summarized changes. + +2010-04-28 Ingo Weinzierl + + Issue260 + + * doc/conf/products/horizontalprofile/conf_mesh_cross.xml: Deactivated odv + export for 'Horizontale Schnittprofile'. + +2010-04-28 Ingo Weinzierl + + * doc/conf/maptemplates/mapfile.vm: Defined a point symbol. + + * doc/conf/maptemplates/layer_linestring.vm, + doc/conf/maptemplates/layer_polygon.vm: Use point symbol for lines with a + yellow color. + + * doc/conf/maptemplates/layer_point.vm: Use point symbol with a yellow + color. + +2010-04-28 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/cache/ThematicDataCacheCleaner.java, + src/main/java/de/intevation/gnv/state/layer/LayerMetaData.java, + src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java, + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java, + src/main/java/de/intevation/gnv/statistics/Statistic.java, + src/main/java/de/intevation/gnv/statistics/Statistics.java, + src/main/java/de/intevation/gnv/utils/MetaWriter.java, + src/main/java/de/intevation/gnv/chart/ChartLabels.java, + src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java: + Removed trailing whitespace. + +2010-04-28 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java: + Removed duplicated and unused imports. + +2010-04-27 Ingo Weinzierl + + * doc/conf/conf.xml: Replaced the path to the artifact database with a + relative path since the artifact-server is able to read relative pathes + for the database configuration. + +2010-04-27 Ingo Weinzierl + + * doc/conf/conf.xml: Changed the default directory of the artifact database. + +2010-04-27 Tim Englich + + * contrib/visualize-transitions.xsl: + Added XSL-Transformation to create an Graphic for the TransitionModels of + the Configuration. + +2010-04-27 Tim Englich + + * doc/conf/conf.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml: + Added missing Namespace declarations to Configurationfiles. + +2010-04-27 Tim Englich + + ISSUE262 + + * doc/conf/products/horizontalprofile/conf_mesh_cross.xml: + Renamed StateIds because they were similar to the StateIds of + the product Horrizontal Profile. + This was done to prevent possible trouble using the Cachemechanism + which use the StateId as part of the Key. + +2010-04-27 Ingo Weinzierl + + Issue218 & Issue220 + + * doc/conf/conf.xml: Removed duplicated mapfile path configurations and + replaced absolute path definitions with relative ones. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Changed XPath expression regarding the changes in conf.xml. + +2010-04-27 Ingo Weinzierl + + Issue6 + + * doc/conf/log.conf: Removed, because this file is not used. + +2010-04-27 Ingo Weinzierl + + Issue246 (Added missing units to the legend text.) + + * contrib/palette2polygonVM.xsl: Use description attribute from palette xml + file to create the legend text instead of from/to attributes. + + * doc/conf/maptemplates/flow-velocity_polygons.class.vm, + doc/conf/maptemplates/water-temperature_polygons.class.vm, + doc/conf/maptemplates/salinity_polygons.class.vm: Added units to the + legend text. + +2010-04-26 Ingo Weinzierl + + Issue251 + + * src/main/java/de/intevation/gnv/state/SingleInputState.java: Override feed + method for input validation. + + * src/main/java/de/intevation/gnv/utils/InputValidator.java: New case: an + empty string is invalid. + +2010-04-26 Tim Englich + + ISSUE252 + + * doc/conf/queries.properties: + Modified Query for selecting metadata for creating ZipFiles or publish + Layer as WMS so that it is possible to handle more than one Layer in one + request. + * doc/conf/products/layer/conf.xml: + Modified workflow so that it is possible to select more than one Layer + to download them as Shapefile or publish them as WMS. + * src/main/java/de/intevation/gnv/utils/MetaWriter.java + (writeLayerMeta), (writeLayerMeta), writeMetaFile): + modified Methods so that it is possible to generate a Metafile containing + more than one Layer in it. + * src/main/java/de/intevation/gnv/state/layer/LayerMetaData.java: + Added Beanclass for temporal storing the Metadata which is required to + generate a Shapafile or an WMS-Layer. + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java: + Modified the workflow so that it is possible to export multiple Layer + in one Zip-File or publish multiple Layers in one WMS. + +2010-04-23 Ingo Weinzierl + + Issue235 + + * doc/conf/conf.xml: Adapted the MapServer path in the configuration to call + the wrapper that exports the mapfile path (see below). + +2010-04-23 Ingo Weinzierl + + Issue220 + + * contrib/mapserv: Added a very simple wrapper script to export the + mapfile path for MapServer. + +2010-04-23 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Inherit from HorizontalProfileMeshOutputState - both are used on meshes. + Subtitle creation for charts is the same here + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshOutputState.java: + Add newline strings after each point in the chart subtitle. + +2010-04-23 Ingo Weinzierl + + Issue138 + + * doc/conf/products/horizontalprofile/conf_mesh.xml: Splitted the + outputstates of horizontalprofiles into meshes and non-meshes to handle + the chart subtitle creation. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Outputstates for horizontal profiles. + +2010-04-23 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (getWMS): + Fixed Bug Renaming Layer. Now the Title is set and the correct method + is called. + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java (writeLayerMeta): + Put Node Title into XML-Fragment of an Layer so that it is + possible to change the name of an Layer. + + * doc/conf/maptemplates/layer_polygon.vm, + doc/conf/maptemplates/layer_point.vm, + doc/conf/maptemplates/layer_linestring.vm: + Modified Templates so that the Name of an layer is fetched from the Title + of the Layerbean. This is the same way as used in any other Templates. + +2010-04-22 Ingo Weinzierl + + Issue217 + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Added the cell width of the interpolation to the constructor call of the + odv export. + + * src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java: + Corrected the depth calculation. + +2010-04-21 Ingo Weinzierl + + Issue228 + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + The presentation of values contained in the statistic are language + specific, now. + +2010-04-21 Ingo Weinzierl + + Issue217 + + * src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java: The + first column (cruise) in an odv export is filled with a static "GNVExport" + string. The second column (station) is filled with a generated string + "Station" concartinated with the index of the current coordinate + (e.g. "Station_1"). Both columns are written to odv only if the coordinate + changes - otherwise these strings are replaced by tabs. + +2010-04-21 Ingo Weinzierl + + Issue233 + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Expand + the range of the range axis (y-axis) manually if there is only one data + point or more data points with the same value. + +2010-04-21 Ingo Weinzierl + + Issue243 + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Added an y-axis label for histogram creation. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added the string + used as y-axis label in histograms. + +2010-04-21 Ingo Weinzierl + + Issue231 + + * doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Switched + histogram parameter type 'binwidth' from integer to double. + +2010-04-21 Ingo Weinzierl + + Issue229 + JFreeChart needs at least a lower and a different upper bounds to + calculate the range of the domain axis automatically. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java: Override + method that adjusts the range of domain and range axes. + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: + Override method that adjusts the range of domain and range axes. If there + are more changes to be done in the future, caused by inheritance from + VerticalProfileChart, we should stop that and derive this class from + AbstractXYLineChart! + +2010-04-20 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/cache/CacheFactory.java (initializeCache): + Initialize the CacheCline after the initialization of the ThematicDataCache. + + * src/main/java/de/intevation/gnv/state/StateBase.java (setHash): + Integrate an '#' as separator in the Hashvalue of an State to separate the + StateId unambiguously. This is required because a StateId can be a + Substring of an other StateId. + + * src/main/java/de/intevation/gnv/state/cache/QueryObject.java: + Bean for representing all database-Queries which are used for fetching + Data which is stoted in the ThematicDataCache. + + * src/main/java/de/intevation/gnv/state/cache/ThematicDataCacheCleaner.java: + Specific CacheCleaner for cleaning the ThematicData-Cache. It extend the + CacheCleaner of the geo-backand and has the same configuration + possibilities. + +2010-04-20 Tim Englich + + * doc/conf/queries.properties: + Added Query for the CacheCleaner that it use to determin which Tables has + been updated. + +2010-04-20 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Removed a TODO from code -> TODO already implemented. + +2010-04-20 Ingo Weinzierl + + Issue163: Workaround improved. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Removed the bottom and left space between data area and plot border and + set a padding of 10px between each border of the whole area (containing + plot area, legend, chart title, etc). + +2010-04-20 Ingo Weinzierl + + Issue163: Workaround implemented. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Added a gap between data area and the plot border to avoid an amount of + cut axes labels (small labels aren't cut anymore, large labels will still + be cut). + + * src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java: Added some + necessary methods to set the first domain and range axis. + +2010-04-20 Ingo Weinzierl + + Issue235 + + * doc/conf/maptemplates/mapfile.vm: Added a metadata section into the + mapfile template. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Read the URL + of the MapServer from configuration and feed the template with this + information. The URL is used in the metadata section for filling the 'wms + onlineresource' field. + +2010-04-19 Ingo Weinzierl + + Issue152 + + * src/main/java/de/intevation/gnv/state/StateBase.java: + Added a date formatter for parsing dates from internal data objects. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Added the time interval of timeseries charts into the subtitle of this + charts. + +2010-04-19 Ingo Weinzierl + + Issue226 + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Iterate through former states when searching for an input collections - + searching in the current state is not enough because it stores the current + input values only. + +2010-04-19 Ingo Weinzierl + + Issue217 + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: Added odv as + possible export format. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Collect the necessary data for an odv export and trigger + VerticalCrossODVExport that writes this data as odv to an output stream. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: Store + coordinates for each colum in a class variable. + + * src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java: + Write data used in 'Profilschnitten' to an odv file. + + TODO: The implementation is not finished yet. There are no cruises and + stations for 'Profilschnitte', so we need to clarify if this columns can + be skipped. + +2010-04-18 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Using unix line endings only. + +2010-04-17 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Removed trailing whitespace. + +2010-04-16 Tim Englich + + ISSUE232 + + * doc/conf/meshwidth.xml: + Added missing Meshes to the Configuration and added more detailed + descriptions to the entries so they can be refred easier to the Meshes in + the System. + +2010-04-16 Tim Englich + + ISSUE200 + + * doc/conf/queries.properties: + Modified Query for selecting available Layer for product Layer. + The table has an Column named Items which contains the Number of Items + that are in the Layer. Only Layer which are not empty should be + displayed. + +2010-04-15 Ingo Weinzierl + + Issue175 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java: Read + percentage that defines the gap size in charts from system property + "chart.gap.percentage". The default value is 5 (percent) if this property + is not existing. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java (createODV), + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java (createODV): + Extract ODV-Generation into its own method that it is possible to override + it in subclasses. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java (getWMS): + Bugfix: Put some Code that is responsible for Synchonization into the + final-block to prevent that the lock is not released. + +2010-04-13 Tim Englich + + * doc/conf/products/layer/conf.xml, + src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java : + Integrated the possibility to change the Title of an Layer in Product Layer. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java: + Removed obsolet SuppressWarnings-Annotations. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Layer.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/MapService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Parameter.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/package.html: + Added more Javadoc. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/transition/package.html, + src/main/java/de/intevation/gnv/transition/ValueCompareTransition.java, + src/main/java/de/intevation/gnv/transition/TransitionFactory.java, + src/main/java/de/intevation/gnv/transition/PresettingsValueCompareTransition.java: + Added more Javadoc. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/transition/package.html: + Added more Javadoc. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java, + src/main/java/de/intevation/gnv/state/MinMaxDateState.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java, + src/main/java/de/intevation/gnv/state/OutputStateBase.java, + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java : + Removed obsolet SuppressWarnings-Annotations. + +2010-04-12 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/package.html: + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java : + Added more Javadoc. + Removed obsolet TODO-Flags. + +2010-04-12 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java: + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataServiceException.java (MetaDataServiceException): + * src/main/java/de/intevation/gnv/artifacts/services/package.html: + Added more Javadoc. + +2010-04-12 Tim Englich + + * src/main/java/de/intevation/gnv/layer/package.html, + src/main/java/de/intevation/gnv/layer/LayerArtifact.java: + Added more Javadoc. + +2010-04-12 Tim Englich + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java (putInputData): + BUGFIX: Chartresults where stored in Cache using null-Value as Key. + This happend because the setHash-method was not called in Method + putInputData of this Class. + This causes that the Data was fetched every time from the Database when + out was called and twice during the intialisationprocess of the State. + +2010-04-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/fis/product/package.html, + src/main/java/de/intevation/gnv/artifacts/fis/package.html, + src/main/java/de/intevation/gnv/artifacts/cache/package.html, + src/main/java/de/intevation/gnv/artifacts/context/package.html, + src/main/java/de/intevation/gnv/artifacts/ressource/package.html, + src/main/java/de/intevation/gnv/artifacts/package.html, + src/main/java/de/intevation/gnv/state/exception/package.html, + src/main/java/de/intevation/gnv/state/package.html, + src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/package.html, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/package.html, + src/main/java/de/intevation/gnv/state/profile/horizontal/package.html, + src/main/java/de/intevation/gnv/state/profile/vertical/package.html, + src/main/java/de/intevation/gnv/state/timeseries/package.html, + src/main/java/de/intevation/gnv/state/describedata/package.html, + src/main/java/de/intevation/gnv/statistics/exception/package.html, + src/main/java/de/intevation/gnv/statistics/package.html, + src/main/java/de/intevation/gnv/histogram/package.html, + src/main/java/de/intevation/gnv/profile/horizontalcrosssection/package.html, + src/main/java/de/intevation/gnv/profile/verticalcrosssection/package.html, + src/main/java/de/intevation/gnv/profile/horizontal/package.html, + src/main/java/de/intevation/gnv/profile/vertical/package.html, + src/main/java/de/intevation/gnv/utils/exception/package.html, + src/main/java/de/intevation/gnv/utils/package.html, + src/main/java/de/intevation/gnv/chart/exception/package.html + src/main/java/de/intevation/gnv/chart/package.html, + src/main/java/de/intevation/gnv/exports/package.html, + src/main/java/de/intevation/gnv/wms/package.html, + src/main/java/de/intevation/gnv/timeseries/gap/package.html, + src/main/java/de/intevation/gnv/timeseries/package.html, + src/main/java/de/intevation/gnv/jfreechart/package.html: Added package + descriptions for the different packages. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java, + src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java, + src/main/java/de/intevation/gnv/chart/ChartLabels.java: Added missing + class descriptions. + +2010-04-12 Tim Englich + + ISSUE 215 msg1189 + + * src/main/java/de/intevation/gnv/exports/ODVExport.java (writeData): + Switched Values between columns yyyy-mm-dd hh:mm and time_ISO8601 and + manipulate the Values that they are in the correct Format. + This is nessessary because of the definitions of Timeseries in ODV-Exports. + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java (getStartTime): + Modified Format of the TimeStamp of the Starttime of TimeSeries in that + case that it does not contains the values for the seconds. + +2010-04-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/DefaultAutoResumeState.java, + src/main/java/de/intevation/gnv/state/DefaultInputValue.java, + src/main/java/de/intevation/gnv/state/SingleInputState.java, + src/main/java/de/intevation/gnv/state/StateFactory.java, + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/MeasurementState.java, + src/main/java/de/intevation/gnv/state/InputData.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/state/DefaultExportMode.java, + src/main/java/de/intevation/gnv/state/OutputStateBase.java, + src/main/java/de/intevation/gnv/state/DefaultInputData.java, + src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java, + src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java, + src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java, + src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/math/AreaInterpolation.java, + src/main/java/de/intevation/gnv/math/GridCell.java, + src/main/java/de/intevation/gnv/transition/Transition.java, + src/main/java/de/intevation/gnv/utils/ExclusiveExec.java, + src/main/java/de/intevation/gnv/chart/DefaultHistogram.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java, + src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java, + src/main/java/de/intevation/gnv/exports/ChartExportHelper.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java, + src/main/java/de/intevation/gnv/exports/ODVExport.java, + src/main/java/de/intevation/gnv/jfreechart/LevelOrderIndices.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java, + src/main/java/de/intevation/gnv/jfreechart/CompactXYItems.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: Removed + JavaDoc compiler warnings caused by broken references and fields without + content. + +2010-04-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/statistics/StatisticSet.java, + src/main/java/de/intevation/gnv/statistics/VerticalCrossSectionStatistics.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java, + src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java, + src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java, + src/main/java/de/intevation/gnv/statistics/Statistic.java, + src/main/java/de/intevation/gnv/statistics/Statistics.java, + src/main/java/de/intevation/gnv/statistics/AbstractStatistics.java: Added + more Javadoc. + +2010-04-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/exception/StateException.java, + src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java, + src/main/java/de/intevation/gnv/transition/DefaultTransition.java, + src/main/java/de/intevation/gnv/transition/TransitionFactory.java, + src/main/java/de/intevation/gnv/transition/TransitionBase.java, + src/main/java/de/intevation/gnv/transition/PresettingsValueCompareTransition.java, + src/main/java/de/intevation/gnv/transition/Transition.java, + src/main/java/de/intevation/gnv/transition/ValueCompareTransition.java: + Added Javadoc. + +2010-04-09 Tim Englich + + ISSUE 215 msg1170 + + * src/main/java/de/intevation/gnv/exports/ODVExport.java : + Modified ODV-Export that it is possible to integrate an Timestamp which + identifies a TimeSeries. + The additional Column will only be integrated if the given Timestamp has + an value and is not null. + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java (getStartTime): + Integrated Method for lookup the Starttimevalue of an TimeSeries to use it + in ODV-Exports. If no Startdate is stored (e.g. if this Methos is called + by an verticalProfileOutputstate) null will be returned an put into the + ODV-Export. + * doc/conf/products/timeseries/conf_mesh.xml: + Added valuename for the Timeinterval to fetch the Starttime of an TimeSeries + from the inputData to integrate it into the ODV-Export. + +2010-04-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java: + Added more Javadoc. + +2010-04-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesMeshArtifact.java, + src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java, + src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java: Added + more Javadoc. + +2010-04-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/describedata/NamedArrayList.java, + src/main/java/de/intevation/gnv/state/describedata/NamedCollection.java, + src/main/java/de/intevation/gnv/state/describedata/ExtendedKeyValueData.java, + src/main/java/de/intevation/gnv/state/describedata/MinMaxDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DefaultKeyValueDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DefaultMinMaxDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/SingleValueDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DefaultSingleValueDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/KeyValueDescibeData.java: + More Javadoc. + +2010-04-08 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java, + src/main/java/de/intevation/gnv/math/package.html, + src/main/java/de/intevation/gnv/math/AreaInterpolation.java, + src/main/java/de/intevation/gnv/math/AttributedXYColumns.java, + src/main/java/de/intevation/gnv/math/AttributedPoint2ds.java: + Finished the javadoc of the math package. + +2010-04-08 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/ConstantFunction.java, + src/main/java/de/intevation/gnv/math/L1Comparator.java, + src/main/java/de/intevation/gnv/math/HeightValue.java, + src/main/java/de/intevation/gnv/math/Interpolation2D.java, + src/main/java/de/intevation/gnv/math/XYColumn.java, + src/main/java/de/intevation/gnv/math/LinearFunction.java, + src/main/java/de/intevation/gnv/math/GridCell.java, + src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: + Added more javadoc. + + * src/main/java/de/intevation/gnv/utils/FileUtils.java, + src/main/java/de/intevation/gnv/utils/MetaWriter.java, + src/main/java/de/intevation/gnv/utils/DistanceCalculator.java, + src/main/java/de/intevation/gnv/utils/MapfileGenerator.java, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java, + src/main/java/de/intevation/gnv/utils/Pair.java: + Removed trailing whitespace + +2010-04-08 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/utils/FileUtils.java, + src/main/java/de/intevation/gnv/utils/DistanceCalculator.java, + src/main/java/de/intevation/gnv/utils/InputValidator.java, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java, + src/main/java/de/intevation/gnv/utils/ExclusiveExec.java, + src/main/java/de/intevation/gnv/utils/MetaWriter.java, + src/main/java/de/intevation/gnv/utils/MapfileGenerator.java, + src/main/java/de/intevation/gnv/utils/WKTUtils.java, + src/main/java/de/intevation/gnv/utils/StringUtils.java, + src/main/java/de/intevation/gnv/utils/Pair.java, + src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java: Added Javadoc. + + * src/main/java/de/intevation/gnv/utils/ArtifactFactoryUtilities.java: + Removed. + +2010-04-08 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Removed trailing whitespace. + + * src/main/java/de/intevation/gnv/math/ConstantXYDepth.java, + src/main/java/de/intevation/gnv/math/LinearMetrics.java, + src/main/java/de/intevation/gnv/math/QueriedXYDepth.java, + src/main/java/de/intevation/gnv/math/L1Comparator.java, + src/main/java/de/intevation/gnv/math/Metrics.java, + src/main/java/de/intevation/gnv/math/LinearToMap.java, + src/main/java/de/intevation/gnv/math/LinearFunction.java, + src/main/java/de/intevation/gnv/math/Interpolator.java: + Added more javadoc. + +2010-04-08 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/OutputHelper.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Added Javadoc. + +2010-04-07 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Removed trailing whitespace. + +2010-04-07 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/ExternalIndexConverter.java, + src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java, + src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java, + src/main/java/de/intevation/gnv/raster/DemuxRingsHandler.java, + src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java, + src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java, + src/main/java/de/intevation/gnv/raster/IsoProducer.java: + Finished Javadoc of the raster package. + +2010-04-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: More javadoc. + +2010-04-06 Tim Englich + + ISSUE215: Rows will not be merged to one Single Row if their values are identical. + + * src/main/java/de/intevation/gnv/exports/ODVExport.java (writeData): + Replaced the StringArray using as Key against the new Class StringArrayKey. + This was nessesarry tp detect Rows with same Values joining them to one + Row. + * src/main/java/de/intevation/gnv/exports/StringArrayKey.java (StringArrayKey): + Added new Class for representing the Key of an StringArray not using the + Hash of the Array but using the hash of the values which are stored in + the Array. + +2010-04-06 Tim Englich + ISSUE213: Wrong Geometrytype used for the generation of an Layer with + Multipolygon-Geometries + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (getWMS): + Integrated lookup of the Geometrytypes using a separat SQL-Statement. + Also added a separat Function for determining the Defaulttemplate for the + Mapfile-Generation. + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java (writeDataToFile): + Changed Methodsignature. Now it's possible to put the Geometrytype which + is required to generate the Layer and not use the Geometrytype of the + first Geometry of the Resultvalues. + This was nessessary because we can have several kinds of geometrytypes + (e.g. MultiPolygons and Polygons) in one Layer. In that case we have to + use the Multi* (e.g. MultiPolygon) as Geometrytype. + * doc/conf/queries.properties: + Added Query for determining the geometryType of a Layer. + +2010-04-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: Fixed vim modeline. + + * src/main/java/de/intevation/gnv/math/L1Comparator.java: Moved + L1 code here. + + * src/main/java/de/intevation/gnv/math/Point2d.java: Removed dead + inverse L1 code. Added Javadoc. + + * src/main/java/de/intevation/gnv/math/IJKey.java: Added Javadoc. + +2010-04-06 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java, + src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java: + Fix to let the test mockups implement their interfaces. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/jfreechart/LevelOrderIndices.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java, + src/main/java/de/intevation/gnv/jfreechart/CompactXYItems.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonSeriesLabelGenerator.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java, + src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: Added + JavaDoc. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/ChartExportHelper.java, + src/main/java/de/intevation/gnv/exports/ODVExport.java: Repaired JavaDoc. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/Chart.java, + src/main/java/de/intevation/gnv/chart/XMLChartTheme.java, + src/main/java/de/intevation/gnv/chart/exception/TechnicalChartException.java: + Added missing vim control comments. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java, + src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java, + src/main/java/de/intevation/gnv/artifacts/services/MetaDataServiceException.java, + src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Parameter.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Layer.java, + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/MapService.java, + src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java: + Added and repaired JavaDoc. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/cache/CacheFactory.java: Added + and repaired JavaDoc. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java, + src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java, + src/main/java/de/intevation/gnv/artifacts/PreSettingArtifact.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java: Added + JavaDoc for this package. + +2010-03-31 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/XMLChartTheme.java, + src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java, + src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Corrected + JavaDoc errors. + +2010-03-30 Ingo Weinzierl + + Issue214 + + * src/main/java/de/intevation/gnv/utils/InputValidator.java: Added code for + validating polygons and linestrings. The input type needs to be 'polygon' + or 'linestring'. + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: Changed the input + type of the wkt string from 'string' to 'polygon'. + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: Changed the input + type of the wkt string from 'string' to 'linestring'. + +2010-03-30 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/ExtendedInputData.java: Added a + method splitParameter() to retrieve the parameter ids as array (analog to + splitValue() in DefaultInputData). + +2010-03-30 Ingo Weinzierl + + Issue210 (First work for saving relation between selected measurement and + the parameter it belongs to completed) + + * src/main/java/de/intevation/gnv/state/DefaultInputData.java: Added a + further constructor and changed the visibility of the separator character + used by this class to public. + + * src/main/java/de/intevation/gnv/state/ExtendedInputData.java: This class + enhances DefaultInputData and has a further field storing a string + parameter. This is necessary to save the information about the + relation between selected measurement and the parameter it belongs to. + + * src/main/java/de/intevation/gnv/state/MeasurementState.java: Little + changes in the data of the describe document. The value for the checkboxes + are composed of the measurement id and the parameter id separated by a + semicolon. Furthermore the incoming document of a feed call is parsed in + this class to save the relation between selected measurement and the + parameter it belongs to. ExtendedInputData class is used as storage. + + * src/main/java/de/intevation/gnv/utils/InputValidator.java: Changed the + method signatures of all methods to static for using it without + instantiating an object of this class. + +2010-03-30 Ingo Weinzierl + + Issue212 (Improved input validation) + + * src/main/java/de/intevation/gnv/state/MinMaxDateState.java: Improved date + input validation. The chosen date needs to be in range between upper and + lower date, otherwise an error message is displayed and the user needs to + correct his choice. + + * src/main/java/de/intevation/gnv/utils/InputValidator.java: Added a new + method to validate a given date being in range between an upper and a + lower date bound. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.propertie: Added error + messages for failures while date validation. + +2010-03-29 Ingo Weinzierl + + Issue192 + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Added an + offset of 15px between the right data area and the right axis. Long axes + labels near the right border aren't cut on this way. + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/package.html: New + Added package description with text 'DOCUMENT ME!'. + +2010-03-29 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Each TimeSeriesArtifacts stores information about its TimeGapDefinitions, + otherwise we are not able to continue with an artifact after a restart of + the artifact server. + + TODO: The information about TimeGapDefinitions are equal for each type of + artifacts. It would be better to store these definitions on a central + place (i.e. see ChartTheme configuration). + + * src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java: Implements + Serializable. + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Bring @author javadoc tags in form '@author John Doe' + + find -name \*.java | \ + xargs sed -i \ + -e 's/@author[ ]\+\([^(<]\+\)[<(]\([^>)]\+\)[>)]/@author \1<\/a>/g' \ + -e 's@[ ]\+@@g' + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java, + src/main/java/de/intevation/gnv/**/*.java: + Ordered imports. Removed needless imports. Removed empty headers. + +2010-03-29 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/**/*.java, + src/main/java/de/intevation/gnv/**/*.java: + Removed trailing whitespace. + find -name \*.java | xargs sed -i 's/[ \t]\+$// + +2010-03-26 Tim Englich + + * doc/conf/queries.properties: + Added Query for fetching the Series and Instantaneouspoints of Series using + an WKT as the Geometryvalue or using the Values set by the Regionfilter + to define the Region of Interest. + + * doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: + Modified the Workflow for Verticalprofiles on Instantaneouspoints so + that the Inputvalues of the Mapviewer-Interface take effect. E.g. + The Regionfilter will not be displaied if an Polygon was send by the + Mapviewer. Also integrated the Regionfilter to the Workflow. + +2010-03-26 Ingo Weinzierl + + Issue164 + + * src/main/java/de/intevation/gnv/utils/ExclusiveExec.java: New. This class + can be used to synchronize threads with a given key. To use this + synchronization, you just have to do something like the following: + UniqueKey token = ExclusiveExec.INSTANCE.acquire(key); + // your code to be synchronized + ExclusiveExec.INSTANCE.release(token); + A thread needs to wait if there is already a thread with the given key + which has acquired a token. Threads with a different key don't need to + wait for this thread. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Synchronize shapefile writing of artifacts which have the same uuid. + + * src/main/java/de/intevation/gnv/utils/FileUtils.java: Added a function to + delete the content of a directory. + +2010-03-26 Ingo Weinzierl + + Issue211 (Applied patch) + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Removed + race-condition when trying to access the index of the next line color used + in chart. + +2010-03-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java: Avoid danger to get + a NullPointerException if no time to live is served by CallContext. + +2010-03-26 Ingo Weinzierl + + Issue197 + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java: Fetch time to live + of an artifact from CallContext and put it into meta document. + +2010-03-25 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java, + src/main/java/de/intevation/gnv/exports/ChartExportHelper.java, + src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java, + src/main/java/de/intevation/gnv/exports/DefaultDataCollector.java, + src/main/java/de/intevation/gnv/exports/DefaultProfile.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java, + src/main/java/de/intevation/gnv/exports/ODVExport.java: Added javadoc and + turned javadoc author tag into a 'mailto' form. + +2010-03-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/histogram/HistogramHelper.java: Removed a + method which was commented out, added javadocs and turned javadoc author + tag into a 'mailto' form. + +2010-03-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/layer/LayerArtifact.java: Removed empty + comment lines at the beginning of the class and turned javadoc author tag + into a form which displays a mailto link in html. + +2010-03-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/wms/LayerInfo.java: Added javadoc in wms + package. + +2010-03-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/Chart.java, + src/main/java/de/intevation/gnv/chart/DefaultHistogram.java, + src/main/java/de/intevation/gnv/chart/XMLChartTheme.java, + src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/exception/TechnicalChartException.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java, + src/main/java/de/intevation/gnv/chart/AbstractHistogram.java, + src/main/java/de/intevation/gnv/chart/ChartLabels.java, + src/main/java/de/intevation/gnv/chart/AbstractChart.java, + src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Added + and repaired javadoc in chart package. + + * src/main/java/de/intevation/gnv/chart/Insets.java, + src/main/java/de/intevation/gnv/chart/ChartStyle.java: Removed these + classes, because they aren't used anymore. + +2010-03-23 Tim Englich + + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_feed.xml, + src/test/ressources/timeseries_mesh/timeseries_step_08_feed.xml: + Switched to valid Timestamps to enable testing ODV-Output. + +2010-03-23 Tim Englich + + * src/main/java/de/intevation/gnv/exports/ODVExport.java: + Added new Export-Class which will generate the special ODV-Format. + This one is required because we have to switch the Format from a Rowbased + Representation to a Columnbased. + This meas that for each Parameter which was requested two additonal Columns, + one for the Parametervalue and one for the Quality, has to be added to the + Export. This differs to the "normal" CSV-Export. + + * src/main/java/de/intevation/gnv/exports/DefaultExport.java (collector): + Switched Member from private to protected to make it available from + extending Classes. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Modified the Colums and the Column-headers and Columns-names for the ODV-Export + that all required Data is put into the Document in the right order and the + right nameing. + Switche to the NEW ODVExport-Class to use it for all ODV-Exports. + + * doc/conf/queries.properties: + Modified the Queries for the ODV-Export that all required Informations are + fetched from the Database. + +2010-03-22 Tim Englich + + * src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_feed.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_feed.xml: + Switched to valid Timestamps to enable testing CSV-Output. + +2010-03-22 Tim Englich + + * src/main/java/de/intevation/gnv/state/StateBase.java (feed): + Bugfix: The Description of an InputData-Object will now only be fetched if + the Name of the data of the Current State is equal to the Name of the + InputData-Object. This Fix prevent some Exceptions that happen if the + Query need som Inputdata which was not set at that moment. + +2010-03-22 Tim Englich + + ISSUE 122 + + * src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Added all required Columns for the CSV-Export. Integrated own + Columnspecifications for the different Kinds of Profiles (TimeSeriesPoints, + Mesh, InstantaneousPoint). + + * doc/conf/queries.properties: + Manipulated the Queries for fetching the Data for generating the CSV-Output + for all kinds of Vertical- and Horizontalprofiles in that way that now all + required Columns were included. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Removed deprecated TODO-Flags. + +2010-03-22 Ingo Weinzierl + + Issue209 + + * doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_flow-velocity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-levels_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-temperature_isolines.vm: + Improved the template configuration for the given changes in rev814. + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java: Moved the + settings of the format used to write floating point numbers into the + shapefile description column into a static block of this class to avoid + doing this each time converting a double value to a description. + +2010-03-22 Ingo Weinzierl + + Issue209 + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java: Added a + further column in the isolines shapefile to store a description for each + line. This description column contains the double value with three maximum + fraction digits. This is a workaround to adjust the rendering of double + values which cannot be adjusted in MapServer at the moment. MapServer + would display all fraction digits contained in the shapefile causing very + long labels. + +2010-03-22 Ingo Weinzierl + + Issue208 (Added a cleanup mechanism to do some things before exporting an + artifact) + + * src/main/java/de/intevation/gnv/state/State.java: Added a cleanup method + to remove special data stored at this state while processing an + 'out'-target. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Default + implementation of this cleanup method - nothing is done here so far. + Override this method in states which should remove data before being + exported. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Overrides this cleanup method to remove the current shapefile path. + + * src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java: + Call cleanup method of the current state if the cleanup method of this + artifact itself is called. + +2010-03-19 Tim Englich + + * doc/conf/products/horizontalprofile/conf_mesh_cross.xml: + Modified the Workflow for "Horizontales Schnittprofil" so that the Inputvalues + of the Mapviewer-Interface take effect. E.g. The Regionfilter will not be + displaied if an Polygon was send by the Mapviewer. Also the Input of an + LineString will be skipped if a LineString was send by the MapViewer. + +2010-03-19 Tim Englich + + * src/main/resources/lang/artifactMessages_de*.properties: + Added new German resources for fis_marinefeatures according to msg1067 + of Issue2005. + +2010-03-19 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java: + Added Support of Layers which are Joined from two Tables. + Only the Columns of the first Table will be inserted to prevent Namecollisions + of Attributenames. + + * doc/conf/queries.properties: + Added full qualified Columnname to prevent Namecolliosions in SQL-Statement + for querying Layer-Data if two Tables are Joined to one Layer. + +2010-03-19 Tim Englich + + * src/main/resources/lang/artifactMessages*.properties: + Added Ressources for new FIS Marine Features. + + * doc/conf/conf.xml: + + ISSUE 205 + + Integrated FIS Marine Features with Product Layer into the System. + +2010-03-19 Tim Englich + + * doc/conf/queries.properties: + + ISSUE92 + + Integrated Column BAND for Query of Layers which belong to a FIS. + The Displayname of an Layer is now TITLE - LAYER_NAME - BAND + +2010-03-19 Tim Englich + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: + Modified the Workflow of the verticalcrosssection that the Geometry is now + copied to the Inpuvalues if it comes from the Mapviewer-Interfacecall. + +2010-03-19 Tim Englich + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Modified the Workflow for Horizontalcrosssections so that the Inputvalues + of the Mapviewer-Interface take effect. E.g. The Regionfilter will not be + displaied if an Polygon was send by the Mapviewer. Also the Input of an + Polygon will be skipped if a Polygon was send by the MapViewer. + +2010-03-19 Tim Englich + + * doc/conf/products/horizontalprofile/conf_mesh.xml: + Modified the Workflow for Horizontalprofiles so that the Inputvalues + of the Mapviewer-Interface take effect. E.g. The Regionfilter will not be + displaied if an Polygon was send by the Mapviewer. Also the Input of an + Point will be skipped if a Point was send by the MapViewer. + +2010-03-16 Tim Englich + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. Also the Input of an LineString will be skipped + if a LineString was send by the MapViewer. + +2010-03-16 Tim Englich + + * doc/conf/queries.properties: + Bugfixes: Fixed the Query for Parameters in Timeseries and + VerticalProfiles in Meshes. Now all Parts of an Mesh will be used and not + only the last one. + +2010-03-16 Tim Englich + + * doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_mesh.xml: + Modified the Workflow for Verticalprofiles and Timeseries on Meshes in + that case that the Inputvalues of the Mapviewer-Interface take effect. + E.g. The Regionfilter will not be displaied if an Polygon was send by + the Mapviewer. + +2010-03-16 Tim Englich + + * src/main/java/de/intevation/gnv/state/PreSettingsTransferCoordinateSelectionState.java: + Added an new State wich will handle the Display of Coordinatevalues and + fetch given Inputparameters from the Presettings and copy them to + the InputValues. + This new Class is necessary because we can have Pointobjects given in + the Presettings which should be used to fetch all MeshPoints within a + given Distance aroud the Coordinate and display its Coordindatevalues. + +2010-03-16 Tim Englich + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (getPointValue): + Integrated handling of WKT-Strings for Points to extract Points from + a given Inputstring. + +2010-03-16 Tim Englich + + * src/main/java/de/intevation/gnv/state/StateBase.java (generateFilterValuesFromInputData): + Improvement: Values of Type Geometry which are Points will be + prepared as Regions for DB-Query. + +2010-03-16 Ingo Weinzierl + + Issue199 + + * src/main/java/de/intevation/gnv/state/MeasurementState.java: Changed the + describe document creation a bit. The describe document will now have a + section for measurement/parameter with each parameter in an own + xform:select node which contains different xform:item nodes for each + measurement for this parameter. + +2010-03-16 Tim Englich + + * doc/conf/products/layer/conf.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. + +2010-03-16 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (fetchData): + BugFix: Fixed NPE using the Presettings-Object without given Presettings. + +2010-03-15 Tim Englich + + * doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. + +2010-03-15 Tim Englich + + * doc/conf/queries.properties: + Added Query for fetching the TimeSeriespoint using an WKT as the + Geometryvalue to define the Region of Interest. + + * doc/conf/products/timeseries/conf_timeseriespoint.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. + +2010-03-15 Ingo Weinzierl + + Issue120 + + * src/main/java/de/intevation/gnv/state/StateBase.java: New method + implemented which searches for a specific parameter by its name in the + current state and in all parent states. Null is returned if no parameter + could be found with this name, otherwise the InputData object. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Display that point in chart subtitle which have been entered by the user. + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java: Added a new method + to transform a Point object to a user-friendly formatted string. + +2010-03-15 Tim Englich + + * doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. + +2010-03-15 Tim Englich + + * doc/conf/queries.properties: + Added Query for fetching the TimeSeriespoint using an WKT as the + Geometryvalue to define the Region of Interest. + + * doc/conf/products/timeseries/conf_timeseriespoint.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-Interface + take effect. E.g. The Regionfilter will not be displaied if an Polygon + was send by the Mapviewer. + +2010-03-15 Tim Englich + + * doc/conf/queries.properties: + Integrated and modified Queries for Timeseries on Meshes. + + * doc/conf/products/timeseries/conf_mesh.xml: + Modified the Workflow so that the Inputvalues of the Mapviewer-interface + take effect. E.g. The regionfilter will not be displaied if an Polygon + was send by the Mapviewer. Also the State for typing an Point will be + skipped an the Geometry of the Mapviewercall will be used. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/DefaultAutoResumeState.java: + Revoke Changes of r771. The Switch if the QueryId is null has several + Effects which causes NPEs in other Parts of this Module. + So I removed the Changes of r771 and override the effected Methods in + DefaultAutoResumeState. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + Integrated the handling of AutoResumeStates into the initialization + Process of an Artifact. After an Initialization of an Artifact it will be + proved if the Current State is an AutoResumeState. If it is the next valid + state in the sequence will be set to the current State. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/state/DefaultAutoResumeState.java, + src/main/java/de/intevation/gnv/state/AutoResumeState.java: + Added new Interface and its DefaultImplementation to the Project. + This Interface will mark States which can be handled automatically without + any interaction from the User. + So it is possible to fork a Sequence e.g. by given Constructorparameters + of an Artifact. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/state/StateBase.java (feed): + Bugfix: We have States which don't have tor Query Data from a Database + for its Description. So now the Description will only be determined if a + Query was configured to this State. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/state/PreSettingsTransferState.java (setup): + Bugfix: Corrected C&P-Error in the Setup-Method of the PreSettingsTransferState + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid): + Added Objecttype Geometry for the Validation of Inputdata. Geometry will + be validated in the same way as Pointobjects. + +2010-03-15 Ingo Weinzierl + + Issue198 + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Read the layer title which might have been adjusted by the user and store + it in the CallContext object to be available in MetaWriter. + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java: Write the layer + title stored in the CallContext object into meta.xml file. + + * src/main/java/de/intevation/gnv/wms/LayerInfo.java: Added a further + attribute named 'title' to adjust the layer name. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Read layer + title from meta.xml file. The uuid is used as layer title if no title is + given. + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: Added a string + input parameter in wms output mode to adjust a wms layer's title. + + * doc/conf/maptemplates/horizontalcrosssection_salinity.vm, + doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_flow-velocity.vm, + doc/conf/maptemplates/horizontalcrosssection_flow-velocity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-levels.vm, + doc/conf/maptemplates/horizontalcrosssection_water-levels_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-temperature.vm, + doc/conf/maptemplates/horizontalcrosssection_water-temperature_isolines.vm: + Read title attribute from LayerInfo object for filling the layer name in + template files. The title can be adjusted by the user himself, but the + shapefiles are stored in the path {shapefile_path}/{uuid}/xxx.shp. + +2010-03-15 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (fetchData): + Integrated lookup of the Geometry which was put to the Artifact during + the Instantiation (e.g. was send from the MapViewer to the GNV). + +2010-03-12 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (fetchColumns): + Integrated an Method for fetching all required Columns for an given Layer + and put them into the Query witch will load the Layerdata from the + Database. + + * doc/conf/products/layer/conf.xml: + Added an Configuration-Element to determine the Query which should be used + to Query the Columns of a choosen Layer. + + * doc/conf/queries.properties: + Manipulated the Queries for fetching the Layerdata in that way that it is + possible to put the requested-Columns into it using the ?-Syntax. + +2010-03-12 Tim Englich + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java (writeDataToFile): + Added generic Export for all Columns which are in an ResultValue. + The first Column must be the Geometryvalue. all other Columns will be added + to the Shapefile using the defined Attribute-Class. + +2010-03-10 Ingo Weinzierl + + Issue201 + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Use a better key - hash served by getHash() from StateBase - to put + chart results into cache. + +2010-03-10 Ingo Weinzierl + + * doc/conf/products/timeseries/conf_timeseriespoint.xml: Use MinMaxDateState + to handle date input instead of MinMaxState. + + * src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java: Added + EXCEPTION_NO_INPUT key used for a lookup in resource bundles. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java + src/main/java/de/intevation/gnv/state/OutputStateBase.java + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/state/State.java: Return localized + error messages as xml documents if something failed while feeding the + current artifact/state. These error messages are used to be displayed in + the user interface. There are two different error messages at the moment - + for general error messages related to server errors and a message invalid + user input. The difference between these messages is their location in the + xml document. Each message type is created with a separate method in + ArtifactXMLUtilities (createExceptionReport() and createInputException()). + The intention to separate these message types is to display them on + different places in the user interface. + + * src/main/java/de/intevation/gnv/state/MinMaxDateState.java: New state to + handle date input. + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java: Converted + some class methods into static methods and added a new method to create an + xml document which contains an error message for invalid user input. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added text for + error messages. + +2010-03-09 Tim Englich + + * doc/conf/queries.properties: + Modified the Query for the lookup of the Tablename and the Whereclaus to + a choosen Layer. Now also the Templateid containing the Mapservice-ID and + the Layer-Id was added to the Query. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java (templateExists): + Add a method which will return if a given Template exists. + this could be used for determining if a specialized Template for a Layer + is given or the Default one should be used. + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (getWMS): + Integrate lookup for MapFileTemplate for the different Layer. + If a special Template should be used it must be storde according to the + following Syntax in the Folder which contain all other Mapfile-Templates. + + layer_{ID_MAPSERVICE}_${ID_LAYER} e.g. layer_BSH_IMS_CONTIS_Resources_2 + + If there is no Template matching the given Name the Defaulttemplates + layer_point, + layer_polygon or + layer_linestring + will be used. + +2010-03-09 Tim Englich + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (out): + Integrated ExceptionHandling if no Data was found for the given Layer. + If no data couuld be retrieved from the Database an XMl-Exceptionreport + will be generated which must be analized by the Clients. + +2010-03-08 Ingo Weinzierl + + Issue186 + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Adjusted + signature of method to store min/max ranges in x and y direction in + charts. + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Adjusted + method call to signature which has been changed in AbstractXYLineChart. + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Added + some empty methods which overrides methods from parent which should not be + called on this class. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java: Added + methods to store vertical min/max ranges in charts. After adding a new + series to this chart, we call prepareRangeAxis() to add an offset (5 + percent) between values and chart border. + +2010-03-08 Tim Englich + + * doc/conf/maptemplates/layer*.vm: + Added some basetemplates for Lines, Points and Polygons that will be used + if an WMS-layer of the Product Layer will be created. + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java (writeDataToFile): + Changed Method in taht way that it now will return the geometrytype of + this Layer instead of an boolean-value. + Null will determine that an Exception occured during the + Shapefilegeneration. + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java (writeLayerMeta): + Added a new Method for writing the Metadatafile for WMS published by + the Product Layer. + Done som Refactoring work for reusing som Code-Snippets. + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (getWMS): + Added the Basic-Support for publishing an WMS-Layer. + The Lookup of the Attributes which has to be put into the Shapefile and + the lookup of the Template which schould be used to symbolize the Layer + has to be implemented. + +2010-03-08 Ingo Weinzierl + + Issue195 + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Use InputData stored at the current state to create chart titles. + +2010-03-08 Ingo Weinzierl + + Issue189 + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Changed insufficient key to store results for chart generation in cache. + Use 'getHash()' method for this now, which have been implemented while + refactoring the cache mechanism. + +2010-03-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/MeasurementState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Cleaned up imports. + +2010-03-05 Ingo Weinzierl + + * doc/conf/conf.xml: Set ttl to a better value. It has been set to 2min by + mistaken while working on mapfile generation. + +2010-03-05 Ingo Weinzierl + + Issue185 + + * src/main/java/de/intevation/gnv/state/MeasurementState.java: Added missing + parameter name in describe document. + +2010-03-05 Tim Englich + + * doc/conf/queries.properties: + Added some more Queries which are required to serve the Requests of the + Product Layer. + + * doc/conf/conf.xml: + Changed the Sourceid of the FIS Contis because of Changes in the Database. + + * doc/conf/products/layer/conf.xml: + Completed the Configuration for the Product Layer. + Added more Configurationdetails to the OutputStates. + * src/main/resources/lang/artifactMessages*.properties: + Added the required ressources for the Product Layer and the FIS Contis and + Nauthis into the Propertiesfiles. + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java (writeDataToFile): + Added an Method for writing g an Shapefile using an Collection of Results. + this Method must be extended that it could use the Result-object in an + generic Way. + At this Moment it is only be Possible to write the Geometry into the + Shapefile if it is given at the first Position of an Result. + All other Attributevalues will be ignored and not written into the Shapefile. + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java: + Added Support for writing Shapefiles and Export them as an Zipfile. + +2010-03-05 Tim Englich + * doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: + ISSUE 191: Pdf, svg and png are now available. + +2010-03-04 Ingo Weinzierl + + * doc/conf/conf.xml: Added a section to configure MapServer relevant stuff. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Store mapserver path in CallContext object to have access everywhere we + have a CallContext object (avoids reading config.xml all the time we want + to write mapfile). + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java: + Added key to store MapServer information into CallContext and fetch it + from it. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Removed code to write meta information files (sourced out to MetaWriter). + This has been done with the intend to write meta information of CONTIS and + NAUTHIS using that class as well. + + * src/main/java/de/intevation/gnv/utils/MetaWriter.java: Helper class to + write meta information files used for mapfile generation. Write general + information about our wms service (MapServer) into meta information file. + This is used to give the user information about the place where he can + find the wms service and his generated wms layer. + +2010-03-04 Ingo Weinzierl + + * doc/conf/maptemplates/flow-velocity_polygons.class.vm, + doc/conf/maptemplates/water-levels_polygons.class.vm, + doc/conf/maptemplates/water-temperature_polygons.class.vm, + doc/conf/maptemplates/horizontalcrosssection_flow-velocity.vm, + doc/conf/maptemplates/flow-velocity_isolines.class.vm, + doc/conf/maptemplates/horizontalcrosssection_flow-velocity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-levels.vm, + doc/conf/maptemplates/water-levels_isolines.class.vm, + doc/conf/maptemplates/horizontalcrosssection_water-temperature.vm, + doc/conf/maptemplates/water-temperature_isolines.class.vm, + doc/conf/maptemplates/horizontalcrosssection_water-levels_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_water-temperature_isolines.vm: + Added template files for water-levels, water-temperature and + flow-velocity. + +2010-03-04 Ingo Weinzierl + + Issue171 + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Changed + the way to calculate the current distance from startpoint. We do not + calculate the distance between the current point and the last point and + add this value to a variable storing the total distance anymore, but + we take the distance between the current point and the start point. On + this way, we do not need a variable to store the total distance, because + current point - first point == total distance. And there is no + impreciseness in gaps of different layers (see issue171 for this). + +2010-03-04 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java: Added + some more debug information for gap detection on grids. + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Added + some more debug information for gap detection on grids. + +2010-03-03 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Log important + values used for gap detection if debug level is enabled. + +2010-03-03 Ingo Weinzierl + + Issue146 + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Removed workaround to send a fake document if statistic is requested, + which is not available for this product type. + +2010-03-03 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Trigger pdf creation for histograms when an 'out' call arrives with output + mode 'histogram' and export mode 'pdf'. + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: + Implemented a method to export histograms as multipage pdf file. + + * doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added pdf + support for histogram charts. + +2010-03-02 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: Added an xpath + expression for export modes. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Refactoring of 'out' to be able to add pdf and svg exports to histogram. + Now, there are just four output modes left (chart, histogram, csv, odv). + Export modes (pdf, svg, img) are part of these output modes. + Implemented svg export for histogram charts. + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: Helper + method to export histograms as svg via output stream. + + * doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added svg + as export mode to histogram output in configuration files. + +2010-03-02 Ingo Weinzierl + + Issue180 + + * src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java: + Removed CallMeta object from state which should not be serialized. + Implemented a little workarround to save localized strings on this state. + +2010-03-01 Ingo Weinzierl + + Issue182 + + * src/main/java/de/intevation/gnv/state/StateBase.java: Display the selected + value if there is no description available. WKT-strings will be displayed + in the static ui part again. + +2010-03-01 Ingo Weinzierl + + Issue179 + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Removed + code former used to append product select box. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Just use all parent + states to render the static part of the user interfact - not the current + state itself! + +2010-03-01 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Removed + methods which aren't used anymore (used before changing the caching + mechanism). + +2010-02-26 Ingo Weinzierl + + * doc/conf/products/timeseries/conf_timeseriespoint.xml: Changed the + configured state class from DefaultState to MeasurementState. + + * doc/conf/queries.properties: Select parameterid from db as well, when + fetching all measurement ids. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Improved the way of + searching for descriptions in selected values (used in describe document). + + * src/main/java/de/intevation/gnv/state/MeasurementState.java: New state + object to create a describe document which can be used to render a + measurement-parameter-matrix. + + * src/main/java/de/intevation/gnv/state/InputData.java, + src/main/java/de/intevation/gnv/state/DefaultInputData.java: Added a new + method to fetch a description by key. + + * src/main/java/de/intevation/gnv/state/describedata/ExtendedKeyValueData.java: + This class extends DefaultKeyValueDescibeData. It is used by + MeasurementState to create a mapping between measurements and parameters. + Each key/value-pair has an extra attribute storing its parameter value. + +2010-02-25 Ingo Weinzierl + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Adapted + configuration. Pdf, svg, image exports got an own section in the + outputmodes node. Exports belong to an output mode, now. There are no + outputmodes 'pdf', 'svg', 'png' existing anymore. + +2010-02-25 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Changed the way of using cache to store verticalcrosssection chart data. + Now, this type of chart is working without cache, as well. + +2010-02-25 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: Changed the + way of using the cache to store chart / histogram data. Now, output modes + 'chart' and 'histogram' are working without cache. + +2010-02-25 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Better exception handling while cache configuration. The cache is not + initialized, if no cache is configured in conf.xml. There would have been + an exception without having a cache section in conf.xml. Now, it's + possible to use GNV without using a cache. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Changed logger name + from irritating 'GNVArtifactBase' to 'StateBase'. + +2010-02-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Store request parameter in a map and put that map into other + classes/methods instead of putting each request parameter into an own + variable. + + * src/main/java/de/intevation/gnv/chart/DefaultHistogram.java: Implemented + logic to adjust number of bins in histogram charts. The user is able to + choose between the number of bins or the size of a single bin. + +2010-02-23 Ingo Weinzierl + + * contrib/palette2polygonVM.xsl: New. XSLT transformation to transform a + palette file into a style definition template used for mapfile creation. + Usage: + + $ xsltproc contrib/palette2polygonVM.xsl \ + doc/conf/palette/water-temperature.xml \ + > water-temperature.vm + +2010-02-23 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Removed a bug in pdf and svg creation. No data were drawn into chart. + +2010-02-23 Ingo Weinzierl + + * doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/timeseries/conf_mesh.xml: Added an export mode section + in output modes and added an export mode 'pdf' for showcase. This work is + necessary to split up output modes (chart, histogram, ...) from export + modes (pdf, svg, png, ...). GUI components are now able to distinguish + between these modes and render each mode in an own section. + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: Read export + modes from configuration node. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Write + export modes into describe document. + + * src/main/java/de/intevation/gnv/state/DefaultOutputMode.java, + src/main/java/de/intevation/gnv/state/OutputMode.java: Added export modes + as java.util.List. 'getExportModes()' will deliver this list. + + * src/main/java/de/intevation/gnv/state/DefaultExportMode.java, + src/main/java/de/intevation/gnv/state/ExportMode.java: Object storing + necessary information for export mode. + +2010-02-22 Ingo Weinzierl + + * doc/conf/conf.xml: Restructured configuration of shapfile and template + directories. Moved map-generator part into gnv section. + Moved shapefile-directory configuration to an own section and removed + duplicated shapefile-directory config from map-generator. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Adjusted + xpath expressions regarding the changes in conf.xml. MapfileGenerator got + some instance variables to store information about mapfile location, + velocity log file and shapefile and template directories. This avoids + reading conf.xml every single time while updating the mapfile. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Adjusted xpath expression regaring the changes of shapefile-directory in + conf.xml. + +2010-02-22 Ingo Weinzierl + + * doc/conf/conf.xml: Added path for velocity logfile. + + * doc/conf/maptemplates/horizontalcrosssection_salinity.vm, + doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm: Removed + absolute path in style includes. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Improved + velocity configuration regarding absolute pathes and logfile. + +2010-02-21 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Fixed file handle leak when writing meta data. + + * src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/utils/MapfileGenerator.java, + src/main/java/de/intevation/gnv/chart/DefaultHistogram.java, + src/main/java/de/intevation/gnv/chart/AbstractHistogram.java, + src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: + Clean up imports. + +2010-02-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Write a meta information file after shapefile writing is finished. These + meta information are used to map the type of shapefiles to a specific + template and fill these layer-templates with data. + + * src/main/java/de/intevation/gnv/wms/LayerInfo.java: Class for storing meta + information for mapfile creation. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Implemented + method stubs. The MapfileGenerator starts searching for meta information + in filesystem after update() is called. These information are used to to + fill templates for the supported layers and a mapfile will be created out + of this. + + TODO: Configure Velocity. + + * pom.xml: Added Apache Velocity 1.6.1 for templating mapfiles. + + * doc/conf/conf.xml: Adapted a section to configure necessary directories + and filenames for mapfile generation. + + * doc/conf/maptemplates/mapfile.vm: Base template for mapfile. All required + layers will be included into this template. + + * doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm, + doc/conf/maptemplates/horizontalcrosssection_salinity.vm, + doc/conf/maptemplates/salinity_isolines.class.vm, + doc/conf/maptemplates/salinity_polygons.class.vm: Template support for + salinity in horizontal crosssection wms. + +2010-02-17 Ingo Weinzierl + + * doc/conf/conf.xml: Added configuration section for writing mapfiles. + + * src/main/java/de/intevation/gnv/utils/MapfileGenerator.java: Singleton + generator for writing mapfiles. It runs in an own thread and has an + 'update' method which triggers the generator to search the filesystem for + shapefiles and meta information and update mapfiles out of these + information. A 'main' method can be invoked to update the mapfile without + an running artifact server. + + TODO: Implement method stubs. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Call MapfileGenerator when writing or removing shapefiles (endOfLife). + +2010-02-15 Ingo Weinzierl + + * doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added + histogram as output mode. + + * doc/conf/charttemplate.xml: Added color of bars in histograms. + +2010-02-15 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Added code path to create and return histograms. + + * src/main/java/de/intevation/gnv/chart/AbstractHistogram.java, + src/main/java/de/intevation/gnv/chart/DefaultHistogram.java: New. Classes + for creating histograms. Each histogram contains exactly one parameter. + + * src/main/java/de/intevation/gnv/chart/XMLChartTheme.java: Added parsing + of histogram bar color. + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: Added a + new funcion to copy all histograms into a single image and send it to + output stream. + + * src/main/java/de/intevation/gnv/histogram/HistogramHelper.java: New. Added + helper function to split the result collections for each parameter and for + each measurement into pieces. + +2010-02-12 Tim Englich + + * doc/conf/queries.properties: + Integrated Queries for the Product Layer. + + * doc/conf/conf.xml: + Integrated the new FIS Nauthis and Contis and the required Link to the + Configuration for the new Product Layer. + + * doc/conf/products/layer/conf.xml: + Added Configuration for the new Product Layer. + * src/main/java/de/intevation/gnv/state/OutputStateBase.java (getData): + Changed Methodsignature from private to protected ro make it available + for extended Classes. + + * src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java (LayerOutputState): + Added new State for generating the Output for the Product Layer. + This Class is not jet completly implemented and will not return any + result at this Moment. + + * src/main/java/de/intevation/gnv/layer/LayerArtifact.java: + Added new Artifactclass for the Product Layer. + +2010-02-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/InputData.java, + src/main/java/de/intevation/gnv/state/DefaultInputData.java: Descriptions + of values are stored in an array, because one InputData object can contain + many data. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Get a description + for each input parameter and use an array to store all descriptions in an + InputData object. Result of this is, that all user selected parameters are + displayed and charts are well drawn again. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Split up data values stored in InputData objects in search mechanism for + specific parameters and put them all as KeyValueDescibeData objects into a + collection. + +2010-02-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Removed + useless method calls which removed elements from cache, because each state + puts its own elements into cache - not in one big piece. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Adapted 'reset' + method. It removes the former user selection for this state, only. + +2010-02-12 Tim Englich + + * doc/conf/products/timeseries/conf_mesh.xml: + Added new Transitions so that the State for entering a CoordinateValue will + only be shown if no Point was inserted during the Instantiation of an Artifact. + (MapViewer-Interface) + The could be used in the FIS Modeldata using the Product TimeSeries. You also have + to use a Region in the RegionFilter. + +2010-02-12 Tim Englich + + * src/main/java/de/intevation/gnv/state/PreSettingsTransferState.java: + This new State ist Implemented for the Case that Values of the PreSettings + has to be used instead of InputValues. This States will look into the + Presettings and put Values identified by the configurable Names into the + InputData-Collection. + For the Configuration you can insert the following XML-Element into the + Configuration of a State. + + + * src/main/java/de/intevation/gnv/state/StateBase.java (getPreSettings), + src/main/java/de/intevation/gnv/state/State.java (getPreSettings): + Added a getter-method for the PreSettings that are set at the State. + Using this way e.g the PresettingsValueCompareTransition can reach the + Settings an can evaluate them. + + * src/main/java/de/intevation/gnv/transition/PresettingsValueCompareTransition.java (operator): + This transition will have a look at the Values which where ste during the + instantiation of an Artifact. If a defined Value is given an the Value is + Equal to the configured Value using the configured Operator the Transition + to the configured State could be used. Otherwise the Transition could not + be used. + +2010-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Replaced method call which removes non selected parameters from parameter + list. At this time, there are only selected parameters in the list, so + there is no need to clean it. The result: Charts are drawn. + +2010-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/StateBase.java: Declared method as + 'protected' to be allowed to use it in derived classes. + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: Changed the + key to store into cache and restore data from it. Added a workarround to + find min and max value fields in InputData. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Adapted the search mechanism for specific parameter collections. This is + required, because the the former mechanism searched in the big cache blob + - which doesn't exist anymore. + + TODO: Repair chart generation. Although there are results existing for + chart generation, no chart in drawn. + +2010-02-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/StateBase.java: Improved hash + creation of each state. The hash is created using the uuid, state-id and + the hash code of the input data required for the sql statement. + +2010-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/StateBase.java: Append description + to InputData objects and use it while creating the describe document. The + description is displayed in the static GUI part. A nice side effect of + this is, that the subarea selection re-appears in the static GUI part. + Even if no subarea has been selected. Furthermore, removed some methods + which became useless after refactoring the caching and rendering + mechanism. + + * src/main/java/de/intevation/gnv/state/MinMaxState.java: Adapted method + signature regarding changes in upper class. + +2010-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/State.java: New method 'feed' in + this interface. It should be used to feed this state with new data + selected by the user. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Use new + method 'feed' instead of 'putInputData' to feed the state with new data. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java, + src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java, + src/main/java/de/intevation/gnv/state/SingleInputState.java: Method + 'purifyResult' just cleans values from database and returns it. DO NOT + put these results into cache at this place! + + * src/main/java/de/intevation/gnv/state/InputData.java, + src/main/java/de/intevation/gnv/state/DefaultInputData.java: Some new + methods to store objects in such an InputData object. Objects are used to + store MinMaxDescribeData objects for example. And further new methods to + store a description for each InputData object. This is used to render the + static GUI part. Until now, this object stored the id's of the + selected parameter, only - which are useless to show in GUI. The + description should be the string shown in the GUI, later. + + * src/main/java/de/intevation/gnv/state/MinMaxState.java: This type of state + overrides 'feed' and 'appendToStaticNode'. 'feed' takes user input and + parses min and max values from it (used for time periods for example). + 'appendToStaticNode' will append these fields to the static GUI part. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Removed the big + cache blob and parted it into pieces. Each state will now put its + database data into cache. In this way, we are able to reuse these data + when the user steps back in history. Data, inserted by the user, will be + stored via 'feed'. Special input fields like multi selection or ranges + need to override this method to parse the input data and store them in + special objects. + + TODOs: + - The output modes are based on this big cache blob and search for + parameterid, measurementid and dateid in it. + TimeSeriesOutputState.getCollection() needs to be adapted! + +2010-02-09 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java (addParameter), + src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java (addParameter): + Added the possibility to add Parameters to an existing FIS. + + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java (getFIS): + Added the support of the usecase that one FIS can be identified by different + MapServices. In that case the parameters will be merged into the existing + FIS. + +2010-02-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/StateBase.java: Do not query the + cache / database for rendering the static part of the describe document - + just take the input data stored at each state. + + TODOs: + - Store 'description' of each chosen value. At the moment we are able to + render an id of value, only. + - Take care of input elements with multi selection. + - The subarea node disappears if we don't select any. + +2010-02-09 Tim Englich + + * doc/conf/conf.xml: + Switched the usage of DummyMetaDataService to MetaDataService because + the Service is now able to work properly. + * doc/conf/queries.properties: + Added the required SQL-Statements for fetching the Metadata from the + Database. + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java: + Added the Database-Lookup of FIS and Parameters. + Now the Metadata will be looked up using the specified Databaseschema as + defined in doc/schema/externalinterface_schema.sql + * src/main/java/de/intevation/gnv/artifacts/services/DummyMetaDataService.java + Removed Dummyservice because it is not required any more. + +2010-02-05 Ingo Weinzierl + + Issue170 + + * pom.xml: Changed log4j version to 1.2.14 (later version + causes errors and breaks maven build process). + +2010-02-05 Tim Englich + + * pom.xml: + Changed from ArcSDE version 9.2.5 to Version 9.3 + You have to Install the required Libraries as described in + https://bsh-intern.intevation.de/Mavenbuildprozess + +2010-02-05 Tim Englich + * doc/schema/externalinterface_testdata.sql: + Changed the Testdata for layerhasparameter according to the the changes of + the Tablestructure. + * doc/schema/externalinterface_schema.sql: + Changed id_layer Column in Table layerhasparameter from literal to number. + And added Column Layername to this Table. + This is nessessary because the Identifcation of an Layer is not the name + but the ID. + +2010-02-05 Tim Englich + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + ISSUE167 + Fixed Bug in Konfiguration. Now Regionfilters can be used without running + in an Exception. + +2010-02-02 Tim Englich + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Added the possibility to use the Informations (PreSettings) which are + send using the MapViewer-Interface in all States which are responsible to + manage the choice of Parameters during the Workflows of GNV-Artifacts. + +2010-02-02 Tim Englich + + * src/main/java/de/intevation/gnv/state/DefaultInputData.java (splitValue), + src/main/java/de/intevation/gnv/state/InputData.java (splitValue): + Added Method which spilts the Values using the same Separator which is + used to concart the Values. + + * src/main/java/de/intevation/gnv/state/StateBase.java: + Added the usage of the Presettings during the Loading of the Data + which is nessesary to describe the current State. + If Values are given in the Presettings which are identified by the + name wwhich is specified in the Configurationelement presettings-name + only the Intersection of the fetched Objects and the PresettingsObjects + are used. + + * src/main/java/de/intevation/gnv/state/State.java (setPreSettings): + Added new Method setPreSettings to be Able to put the Presettings from the + current Artifact to the different States. + + * src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java (setup): + The Method Setup now extracts the given PreSettingsparameter from the + XML-Document and put them to the ProductArtifacts which are instantiated in + the advance()-Method using the Methods of the PreSettingArtifact-Interface. + + * src/main/java/de/intevation/gnv/artifacts/PreSettingArtifact.java (setPreSettings): + New interfacedefinition. Artifacts which are implementing this Interface + are able to exchange the given Presettings using the given getter and + setter methods of this Interface. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + The GNVArtifactBase now implements the Interface PreSettingsArtifacts. + So it is able to manage Data which is set during the construction of an + new ArtifactInstance. + It also put the PreSettings-data to the different States. So that they are + able to use it during their livecycle. + +2010-02-01 Tim Englich + + * doc/conf/conf.xml: + Added the Configuration-node for the MetaDataService into the Configuration + of the GNV-Artifact-Restserver. + At tis Moment it is only useful to use the DummyMetaDataService. + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java: + Defaultimplementation of the Interface Layer. + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Layer.java: + Interfacedefinition for Objects that represents Layer and GroupLayer that + where parsed from the XML-Document which was sent to the MetaDataService + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java: + Defaultimplementation of the Interface MapService. + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/MapService.java: + Interfacedefinition for Objects that represents Mapservices that where + parsed from the XML-Document which was sent to the MetaDataService. + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java: + Defaultimplementation of the Interface Parameter. + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Parameter.java: + Interfacedefinition for representing an Parameter which belongs to an FIS. + + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java: + Defaultimplementation of the Interface FIS. + * src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java: + Interfacedefinition for representing an FIS which will be used as an + ResultValue of the MetaDataService-Processing. + + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataServiceException.java: + Exceptionclass for classifiing Exception which occurs during the processing + of an MetaDataService-Call. + + * src/main/java/de/intevation/gnv/artifacts/services/DummyMetaDataService.java: + DummyClass of an MetaDataService. This Class can be use to simulate an + MetaDataService-Call until the required Metadata for the prossessing are + available in the Database-Backend. + This Class only returns the given Mapservices as an FIS and the Layer + as an Parameter to a given FIS. + + * src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java: + This Class is an Implementation of the de.intevation.artifacts.Service + Interface. This Service should provide Informations which FIS are available + for given Mapservices an which FIS are intersecting a given Region + These Informations are required according to definition of the MapViewer + Interface. + +2010-02-01 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java (createArtifactWithFactory): + Fixed Compilance-Errors triggered by Interface-Modifications in the + Artifact-Module. + + * src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshTimeSeriesTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointHorizontalProfileTestCase.java (testArtifact): + Refactored Artifact-Instantiation using the new createArtifact()-Method of the super-Class. + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java (createArtifact) + Added Method for instantiating an new Artifact using the given Artifactfactory. + Also fixed the Compilance-Errors triggered by Interface-Modifications in the + Artifact-Module. + +2010-02-01 Tim Englich + + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java (setup), + src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java (setup), + src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java (setup), + src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java (setup), + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java (setup), + src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java (setup), + src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java (createArtifact), + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (setup): + Changed Method signatures because of Interfacemodifications in the + Artifact-Module. Now it is possible to retrieve the XML-Document which was + send by an Client during the create-Call. So it is possible to get further + Informations which could be used during the livecycle of an Artifact. + + +2010-01-31 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java, + doc/conf/conf.xml: Added configuration for extrapolation in "Horizontalschnitte". + + Use gnv/horizontal-cross-section/extrapolation/@rounds with + integer rounds > 0 to turn extrapolation on (default: 0). + Rounds is a number of successive point extrapolations which means that + the grid is successively filled with missing points based on prior rounds. + The larger 'rounds' get more gaps are filled synthetic generated points. + + Set this to 2 to get good results for the model data FIS. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Foward configuration to area interpolation. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + Foward configuration to GridCell. + + * src/main/java/de/intevation/gnv/math/Point2d.java: Added method to extrapolate + point along a line spanned by two points. + Calculate Inverse Distance Weighting (IDW) for a given set of points on + z components. Added method to check if set of points are near a given + point. + + * src/main/java/de/intevation/gnv/math/GridCell.java: Before building the + i/j cells the grid is filled with synthetic generated points. The + position is estimated from the neighboring points. The parameter values + are calculated by IDW. Some care is taken to avoid invalid grid topologies. + + TODO: Implement this for the "Profillschnitt" too to keep the inner + symmetry. + +2010-01-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java (testArtifact), + * src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java (testArtifact), + * src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java (testArtifact), + * src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java (testArtifact): + Increases the number of steps that has to be done for the different products plus one. + + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_statistics.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_odv.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_csv.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_chart.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_feed.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_advance.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_feed.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_advance.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_09_advance.xml: + Added Advance and Feed-Document for the State Year. + Changed the Advance to the State Year. + Moves the Last state to *11*.xml Documents. + + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_odv.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_csv.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_chart.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_feed.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_advance.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_feed.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_advance.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_05_advance.xml: + Added Advance and Feed-Document for the State Year. + Changed the Advance to the State Year. + Moves the Last state to *07*.xml Documents. + + * src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_statistics.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_odv.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_csv.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_chart.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_advance.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_feed.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_advance.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_09_advance.xml: + Added Advance and Feed-Document for the State Year. + Changed the Advance to the State Year. + Moves the Last state to *11*.xml Documents. + + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_zip.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_wms.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_feed.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_advance.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_feed.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_advance.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_advance.xml: + Added Advance and Feed-Document for the State Year. + Changed the Advance to the State Year. + Moves the Last state to *08*.xml Documents. + +2010-01-27 Hans Plum + + RELEASE 0.4 + + * Changes, NEWS, ChangeLog: Summarized activities + +2010-01-27 Sascha L. Teichmann + + * Changes: Reordered items a bit + +2010-01-27 Ingo Weinzierl + + Issue164 + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Applied patch of SLT to remove shape files and directories of out-dated + artifacts. Therefor we need to store the artifact after an 'out' operation + - which is actually a read only operation - explicitly into the artifact + database to keep the directory path. + +2010-01-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Calculate results after reaching the final state and store them in cache. + This avoids long latencies for chart creation or exports. + +2010-01-26 Ingo Weinzierl + + Issue158 + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Replaced old way to create ChartLabel objects with a method call + 'createChartLabels()'. + +2010-01-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Set white border (border arround drawing area) as default for + 'Profilschnitte'. + +2010-01-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Calculate results after reaching the final state and store them in cache. + This avoids long latencies for chart creation or exports. + +2010-01-26 Ingo Weinzierl + + Issue162 + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml, + doc/conf/queries.properties: Adapted transition model. Splitted date + selection of 'Horizontalschnitte' into two steps. + +2010-01-26 Ingo Weinzierl + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: Removed csv export + from product 'Profilschnitt'. + +2010-01-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java: Fixed an + ArrayIndexOutOfBounds-exception which occured if there are less than two + data points. + +2010-01-26 Ingo Weinzierl + + Issue161 + + * doc/conf/products/verticalprofile/conf_mesh.xml: Adapted transition model. + Splitted date selection into two steps. + +2010-01-25 Sascha L. Teichmann + + Fix/Workaround for gnv/issue159 + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Deactivated the index buffer by default because applying it gives to + less data points in some circumstances. When processing the + "horizontalen Schnittprofile", the "Profilschnitte" and the + "Horizontalschnitte" the whole set of mesh cells for + the given parameters are retrieved. This results in much + more traffic from database (~ 10x) but seems not to be much slower. + The memory consumption increases accordingly. + + To turn the index buffer on again use the boolean system properties: + + "gnv.horizontal.profile.mesh.cross.index.buffer" + "gnv.vertical.cross.section.index.buffer" + "gnv.horizontal.profile.mesh.cross.index.buffer" + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: Because much + more data is processed a more sophisticated point culling strategy is + implemented now. + + If the number of points are higher than a given threshold (system property + "gnv.interpolation2d.cull.point.threshold", default: 1000) a culling is + performed. Two cases: + + a) given a path P ("horizontales Schnittprofil", "Profilschnitt") + Calculates a bounding box B for P and continues with (b). + + b) a bounding box B ("Horizontalschnitt", and above after (a)) + Calculates a bounding box C for the input points. If the + area of B is greater than 80% of the area of C no culling is + performed. Else B is extended by 10% in each direction. + If the new area of B is smaller than 10% of the area of C + B is adjusted to have at least 10% the size of C. + + All input points that are not inside B are culled. Afterwards the + i/j grid cell units are created and pushed into a spatial index + as described below. + +2010-01-25 Ingo Weinzierl + + Issue157 + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Added method to adjust background color of this chart. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Set white background as all other charts have. + +2010-01-25 Ingo Weinzierl + + Issue160 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Copied a + method from JFreeChart and adapted date formats. + +2010-01-25 Sascha L. Teichmann + + * doc/conf/arcsdeconnectionpool.properties: Set serverRoundtripInterval + to 5 seconds and serverInactiveInterval to 5 minutes. + +2010-01-25 Ingo Weinzierl + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/queries.properties: Splitted date selection into two steps - year + and concreate date in this year. Removed useless option to + disable/enable data points of chart and export output, because points + make no sense in such products. + +2010-01-25 Ingo Weinzierl + + * doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml: Added new state for + splitting the date selection into two parts - selection of year and + selection of a concrete date of this year. + + * doc/conf/queries.properties: Added new sql statement for querying years + and adapted statement to query concrete dates. + +2010-01-25 Ingo Weinzierl + + Issue156 + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added some + parameter (width, height, and shapes) to output modes svg and pdf. Now, + these parameter will have an effect on svg and pdf exports. + +2010-01-24 Sascha L. Teichmann + + * doc/conf/conf.xml: Added attribute "fill-color" to + /artifact-database/gnv/vertical-cross-section/ground/ configure + the color of the seabed polygon. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Adjusted column depth to the deepest interpolated position to + prevent gaps. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Add ground polygon to the chart. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/OutputHelper.java: + New. Contains code to create the ground polygon. + + * src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java, + src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java: + Handle temporary vertices more efficiently. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Added configuration to set the color of the seabed polygon. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Handle the seabad polygon color. + +2010-01-24 Sascha L. Teichmann + + * contrib/palette2qgis.xsl: Cosmetic cleanups. + +2010-01-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Fixed bug when accessing i and j columns of SQL dataset. This + prevented gap detection in "horizontale Schnittprofile" from working. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: + "horizontale Schnittprofile" are now using the grid cell mechanism + too. This should fix all remaining problems to solve gnv/issue153. + The culling of too much points is controlled with the system property + "gnv.interpolation2d.cull.point.threshold" with the same semantics + as in 'Profilschnitt' and 'Horizontalschnitt'. + The spatial buffer size estimation code is removed because it is + not needed any longer. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: Moved some + code to Interpolation2D. + + * src/main/java/de/intevation/gnv/math/GridCell.java: Added some + debug information about the number of found cells. + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java: + Cleanup imports. + +2010-01-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Apply same logic about the number of points to "Profilschnitte" + too. If there are more "gnv.interpolation3d.cull.point.threshold" + points they are culled against a 5% extended bounding box around + the path. Default threshold: 1000. + +2010-01-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + - The lastest refactoring removed the evaluation of the + depth. Now its back in again. + + - If the number of incoming points is greater than + a given threshold (default: 1000) than the bounding box + of the interpolation is extend about 5% for a test + if the points are in this area. Points outside this + area are culled because its unlikely that they have + any influence on the result. Use the system property + "gnv.areainterpolation.cull.point.threshold" to modify + the threshold value. + + * src/main/java/de/intevation/gnv/math/GridCell.java: When + build the interpolation areas the points are culled against + extented bounding box. + +2010-01-23 Sascha L. Teichmann + + * contrib/palette2qgis.xsl: New. XSLT transformation to turn a + palette XML file into a style definition suitable to be used + in QGIS. Tested with QGIS 1.4.0-Enceladus. Usage: + + $ xsltproc contrib/palette2qgis.xsl \ + doc/conf/palette/water-temperature.xml \ + > water-temperature.qml + + Do similar to process salinity.xml et al. + + When you've loaded the "Horizontalschnitt" polygon layer + in QGIS, class it via the "CLASS" attribute, load the + according style and apply it. Voila! + +2010-01-22 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Make "Profilschnitte" work the same way like "Horzontalschnitte" + again. + +2010-01-22 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/GridCell.java: New. + A 4-tupel of neighbored points in the mesh. It is valid + to interpolate in this area. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + The algorithm how neighbored points in the mesh are determined + has changed. Now all incoming points are tiled into GridCells. + If there are gaps in i,j the corresponding tile is omited. + These tiles are stored in an R tree. To lookup a point in + world coordinates the spatial index is queried. If no result + is found the point is ignore as a gap. If a fitting grid cell + is found the interpolation in done between the four points + of that cell is performed. Special gap checking is not needed any + longer. This fixes gnv/issue153 because there are no assumptions + about axis aligned points any more. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: Used + euclid distance to estimate spatial buffer size. TODO: Remove + this code when adjusting the "Profilschnitte" to the same logic + as used in "Horzontalschnitte" now. + + * src/main/java/de/intevation/gnv/math/LinearFunction.java: Added + author's email. + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Cleanup imports. + +2010-01-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Removed + debug output which has been checked in by mistake. + +2010-01-22 Tim Englich + + * doc/conf/meshwidth.xml: + Added Description of the sense of the different Attributes. + +2010-01-22 Tim Englich + + Issue93 + + * doc/conf/meshwidth.xml: + Added file for the global Configuration of MeshWidths to the Project. + This file has to be edited if the mean Distance between two MeshPoints has + changed or a new Mesh will be introduced. + + * doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml: + Added Elemet with Link to the MeshWidth-Document to Configurations + for CoordinateSelectionStates. + + * src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java : + Added the possibility to configure the different width of the Meshes. + +2010-01-22 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java (serviceNamesAndDescriptions),(process): + Fixed Compiler-Error after adding further Methods to the Interface ArtifactDatabase. + +2010-01-22 Tim Englich + * src/test/java/de/intevation/gnv/artifacts/util/ShapeFileWriterTestCase.java (testMultiLineStringWriter): + Fixed Compiler-Error after changes in the Method-Signature. + +2010-01-21 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Repaired revision. Removed try-catch of a never thrown exception. + +2010-01-21 Ingo Weinzierl + + Issue136 & Issue137 + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added templates + to format coordinates to a human readable output. + + * src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java, + src/main/java/de/intevation/gnv/utils/WKTUtils.java: Moved function to + format coordinates from wkt string to human readalbe output to WKTUtils. + Modified the method: Read template out of the i18n files and use a Java + MessageFormatter to fill this template with string objects. A result of + this is a proper encoding (issue137). + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Use the method described above to format coordinate output and display + this as chart subtitle (issue136). + +2010-01-21 Ingo Weinzierl + + Issue100 + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: If there + are more than one axis, each dataset is mapped to its own dataset after + adding it to the plot (one dataset for each parameter). In this way, we + get a well scaled axis for each parameter which is independent from other + axes (see range of salinity and air-pressure for example). + +2010-01-20 Ingo Weinzierl + + Issue152 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Removed date + formatting from timeseries charts. Set locale of DateAxis instead to + localize chart axis. Advantage: JFreeChart defines intervals of axis + labels automatically. + +2010-01-20 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Trigger the calculation when the state is initialized. + +2010-01-20 Ingo Weinzierl + + Issue129 + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Renamed I-axis to + 'West-East-axis' and J-axis to 'North-South-axis'. + +2010-01-20 Ingo Weinzierl + + Issue105 The option to enable/disable data points in charts is now + available in gui. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Parse optional chart parameter 'points' to adjust rendering of shapes. + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added an + option to enable/disable data points in charts. + +2010-01-20 Sascha L. Teichmann + + * doc/conf/conf.xml: Set number of per axis samples to 1024 + because generation of "Horizontalschnitte" is much faster + now (60x). + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: + Added some kind of outlier test when guessing the buffer size + of the spatial index. The speed problem arose from the fact + that to much points are assumed to be neighbors of a given + point. Long distances which differ more than 40% from the + standard derivation are assumed to be outliers. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: Uses + the outlier aware buffer size guessing now. + + * src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java, + src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java: + Removed needless imports. + +2010-01-20 Ingo Weinzierl + + Issue148 + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Removed + mistakes in description and mimetype of svg export nodes. + +2010-01-20 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java, + src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java: + Clip against given polygon. BTW: Geotools has problems with + writing clipped polygons in packed 2-tuple form, too. Therefore + polygons are also stores in the packed 3-tuple form. :-/ + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Forward clipping polygon to isoline and polygon generator. + +2010-01-19 Sascha L. Teichmann + + * trunk/pom.xml: Upgraded Geotools to 2.5.8 + + * trunk/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java: + Ported to Geotools 2.5.8 API. Write parameter id, date and layer + to shape files, too. + + * trunk/src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + Flip upside down again because its not necessary. + + * trunk/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java: + XXX: There is a Geotools bug when writing multi lines strings + to shape files when the internal data representation are + packed 2-tuples. 2-tuples are enough in our use case but we + use 3-tuples for multi line line strings. multi polygons work + fine with 2-tuples. + Removed needless bug output. + + * src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java: + Use packed 3-tuples as the internal representation. + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Removed needless imports. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: Write polygons and lines strings to shape files. + +2010-01-19 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + Removed import to make it compilable again. + +2010-01-19 Ingo Weinzierl + + Issue142 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Fixed an issue + in timeseries chart caused by parameters with no value. Paid attention on + array length. + +2010-01-19 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/RasterToPPM.java: New. + Class to write rasters with palettes to portable pixmaps. + Handy to debug raster outputs. + + * src/main/java/de/intevation/gnv/raster/Raster.java: Added + getValues() to access the backing data. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Read parameter from input data correctly. + + * src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java: Walk + rings of polygons in reversed order to produce correct JTS polygons. + Its not entierly clear why this is necessary. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: Clipp the + input points against an buffered version of the bounding box of + the given polygon to reduce the number of data. TODO: figure out why + upside down rendering in necessary. + +2010-01-19 Tim Englich + + * doc/schema/externalinterface_testdata.sql, + doc/schema/externalinterface_schema.sql: + Do some Bugfixes after testing the Schema and Testdata against an Oracle 10.2 DBMS. + +2010-01-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/State.java, + src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java, + src/main/java/de/intevation/gnv/state/OutputStateBase.java: Changed some + method signatures. Use CallContext objects in some methods of the State + interface instead of CallMeta objects, which are a subset of CallContext. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Adapted + method calls on State objects to the changes in the interface. + +2010-01-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Sourced creation of a ChartLabel object out to an own method which can be + overwritten in subclasses to adjust the labels in each chart type. + + * src/main/java/de/intevation/gnv/chart/ChartLabels.java: Added string for + labeling y axis and a parameter used in 'Profilschnitten'. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: Read + labels from ChartLabel object and set chart and axes titles according to + these labels. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added labels for + x and y axes of 'Profilschnitt' charts. + +2010-01-18 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java: Add an + attribute 'fis' to the fis select node. If this attribute is found in + XSLT, a link to step back and select a new fis will be created. + +2010-01-18 Tim Englich + + * doc/schema/externalinterface_schema.sql: + Added Comments and further Informations. + +2010-01-18 Tim Englich + + * doc/schema/externalinterface_testdata.sql: + Added Testdata to demonstrate how the different Tables has to be filled. + + * doc/schema/externalinterface_schema.sql: + Added Schema for the DB-Schemaextention for providing the Data that is + required for the external Interface to the Mapviewer + + +2010-01-18 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java: + Implements a single method to append the selected fis to ui's static part. + + * src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Inherit + from GNVDefaultArtifact to append the selected fis to static part of the + describe document. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Do not create static + and dynamic nodes of the user interface any longer - fetch these nodes via + xpath expression. The creation of these nodes takes place in the artifact + itself. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.propertie: Added label for + fis. + +2010-01-18 Sascha L. Teichmann + + * ChangeLog: Fixed indention. + +2010-01-18 Tim Englich + + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_out_chart.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_out_odv.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_out_csv.xml: + Removed Files, because they are not required any more. + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_out_zip.xml: + Added new RequestFile for calling for retrieving a Zip-File from the Server. + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_out_wms.xml: + Added new RequestFile for calling for an WMS-Result. + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_04_feed.xml: + Added Polygon as WKT into the feed-Request. + +2010-01-18 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java (TestArtifactDatabase): + New: Added an Testimplementation of the ArtifactDatabase to the Tests to use it inside the + TestCallcontext to prevent NPEs during the Testzenarios. + + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java (TestCallContext): + Added Artifactfactory to the Methodsignature of the Context to use it inside the Context. + Added the Method getDatabase to resolve Compilationerrors. + + * src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshTimeSeriesTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointVerticalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointHorizontalProfileTestCase.java (testArtifact), + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java (createCallContext): + Changed Methodsignature of createCallContext. Add the Artifactfactory to use it for creating + the CallContext. + +2010-01-18 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/ExternalIndexConverter.java: + New. Helper to convert the internal palette indices + to the explicit configured external ones. + + * src/main/java/de/intevation/gnv/math/AttributedPoint2ds.java: + Store the JTS geometries too. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Generate JTS multi polygons for parameter regions and multi line strings + for iso lines. TODO: Clip against incoming polygon. + +2010-01-18 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/Palette.java: + load attribute "index" as external index. This + is useful to match color classes with external sources. + If no explicit index is given the order of ranges is + used as external index. + + * doc/conf/palette/flow-velocity.xml, + doc/conf/palette/water-levels.xml, + doc/conf/palette/salinity.xml, + doc/conf/palette/water-temperature.xml: Set explicit + external color class indices. + + * doc/conf/conf.xml: Set ground interpolation of "Horizontalschnitte" + to bilinear. + +2010-01-17 Sascha L. Teichmann + + * doc/conf/conf.xml: Reduced number of "Horizontalschnitt" + samples to 256 because its much too slow with higher resolutions. + This has to be improved. + + * doc/conf/queries.properties: Use point data to generate + "Horizontalschnitte". Added parameter id and date to results. + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java: Made + reading to points more fault tolerant. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Call the area interpolation. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + Fixed bug with calculating points inside bounding box of polygon. + +2010-01-17 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/State.java: Added + support for end of life. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Implemented + end of life trivial. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + call end of life when leaving state. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Used XMLUtils.toStream() instead of own tranformer code. Removed + dead code. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Implemented end of life. Remove shapefile directory from + file system belonging to concrete artifact. + Implemented download as ZIP file. Offer some link for + WMS integration. TODO: implement the real WMS publishing here. + +2010-01-17 Sascha L. Teichmann + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Only offer WMS layers and download ZIPs in output state. + + * src/main/java/de/intevation/gnv/utils/FileUtils.java: + New. Helper class to recursively delete files and directories + and create ZIP archives from files and directories. + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java: Simpilied + signature of worldEnvelopeCoordinatesToIndex(). + + * src/main/java/de/intevation/gnv/state/OutputState.java: Cleanup + imports. Made source more readable. + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java: + Cleanup imports. Made source more readable. Moved some + XPath stuff from TimeSeriesOutputState up into this base class. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Move some XPath stuff into base class. Made source more readable. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Directly inherit from OutputStateBase now to break the implicit + constraints (chart styles, statisctics, etc.) of the + TimeSeriesOutputStates which not hold for this kind of state. + XXX: Added Workaround to circumvent gnv-intern/issue146 + + * src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: Added + e-mail addresses for authors. Made querying for attributes more + robust. + + * src/main/java/de/intevation/gnv/math/AttributedPoint2ds.java: + New. Data carrier for the "Horizontalschnitte". Used for generation + of results and caching + +2010-01-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java, + src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java, + src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/math/AreaInterpolation.java: + Cleaned up imports. + +2010-01-15 Ingo Weinzierl + + Added support to step back to the point where the user is able to choose + the product of a FIS. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java, + src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java: + Cleaned up factories regarding their tasks. GNVArtifactFactory creates + concrete products. GNVProductArtifactFactory handles all FIS and knows + the products of a FIS. + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java: Removed, + because it is not used anymore. + + * src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java: + A Product does no longer save its factory but the name of its factory as + string. + + * src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java: + This artifact will no longer read the config file to get information about + the products of a fis. The products are set via setter method out of the + ArtifactFactory where this artifact is build. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Added the + possibility to step back to the point where the user can choose a product. + If the target of advance is 'product' we fetch the + GNVProductArtifactFactory from ArtifactDatabase and create a new + SelectProductArtifact, put it into the ProxyArtifact and clean up the ugly + cache. + + * doc/conf/conf.xml: Create top level FIS artifacts with + GNVProductArtifactFactory instead of GNVArtifactFactory. + +2010-01-15 Tim Englich + + * doc/conf/arcsdeconnectionpool.properties: + Added the Property serverRoundtripInterval to the Configuration an + set its Value to 15 Minutes. + +2010-01-15 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java (testArtifact): + Added new Step for querying the Years where measurements has been done into the + Testcase. + + * src/test/ressources/verticalprofile/verticalprofile_step_07_out_statistics.xml, + src/test/ressources/verticalprofile/verticalprofile_step_07_out_odv.xml, + src/test/ressources/verticalprofile/verticalprofile_step_07_out_csv.xml, + src/test/ressources/verticalprofile/verticalprofile_step_07_out_chart.xml, + src/test/ressources/verticalprofile/verticalprofile_step_07_feed.xml, + src/test/ressources/verticalprofile/verticalprofile_step_07_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_06_feed.xml, + src/test/ressources/verticalprofile/verticalprofile_step_06_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_05_feed.xml, + src/test/ressources/verticalprofile/verticalprofile_step_04_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_05_advance.xml: + Added State-Ressource for the new step Year and modified the other Ressource-Files + so that the new Step is queued in the right direction. + +2010-01-13 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/fis/FISSelectArtifact.java, + src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java: + Renamed FISSelectArtifact to SelectProductArtifact which fits better, + because the intent of this artifact is to choose a product - not a FIS. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java: + Replaced FISSelectArtifact with SelectProductArtifact. + +2010-01-13 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/artifacts/util/ShapeFileWriterTestCase.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Removed needless imports. + + * src/main/java/de/intevation/gnv/math/AreaInterpolation.java: New. Interpolates + area for a given bounding box, taking gaps and DEM into account. + Not very fast. Use bilinear interpolation to match the "Profilschnitt". + Possible TODOs: + - speed up by assuming the grid is not sparse. + - use higher interpolation methods. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Added configuration for ground interpolation. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Add helper functions to access configuration. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: Simplified Code. + + * src/main/java/de/intevation/gnv/math/L1Comparator.java: add setReference() + method. + +2010-01-13 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: 'advance' + method will now consider old states. We reset input data of target state + and clean cache from 'future data' before steping back to previous + states. + + TODO: Refactor caching mechanism which should take care of different + states' hash values to be able to use the cache more efficiently. + + * src/main/java/de/intevation/gnv/state/State.java: Added method to return + map which stores input data of the current state. + + * src/main/java/de/intevation/gnv/state/describedata/MinMaxDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/SingleValueDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/KeyValueDescibeData.java + src/main/java/de/intevation/gnv/state/describedata/DefaultSingleValueDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DefaultMinMaxDescribeData.java, + src/main/java/de/intevation/gnv/state/describedata/DefaultKeyValueDescribeData.java: + Add current state's name when initializing new objects of these classes. + The name of a state is added as attribute to a node when creating the + describe-document. The xsl transformer will read this attribute and create + a link which allows the user to step back to previous states. + + * src/main/java/de/intevation/gnv/state/SingleInputState.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/state/StateBase.java: + - Add state name when creating objects to store input data. + - Use XMLUtils.ElementCreator to write namespace aware xml elements. + - Add state names as attributes to xform elements. + - Append old states to list of reachable targets in describe-document. + - Remove data from cache which belong to future states after stepping + back to a previous state. + - Remove input data of current state after stepping back. + +2010-01-12 Sascha L. Teichmann + + * doc/conf/conf.xml, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Added configuration od file system directory of generate "Horizontalschnitt" + shape files. + +2010-01-12 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java, + src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Code cleanup + +2010-01-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/SingleInputState.java, + src/main/java/de/intevation/gnv/state/MinMaxState.java, + src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java: + Data, describing the user interface, is stored in a list instead of a + collection, now. This makes it easier to remove the last element if we + advance back. + + * src/main/java/de/intevation/gnv/state/State.java, + src/main/java/de/intevation/gnv/state/StateBase.java: Added a 'reset' + method to clear data which has been inserted before returning to an old + state. This is called when we try to advance into the past. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Now, it's + possible to advance to an earlier state. The 'advance' method first + searches for a given target name in the list of reachable targets. If no + future target has been found, the method looks for an old state with this + target name. The last option is to return to the initial step for choosing + the FIS, if the target name is 'start'. + +2010-01-12 Tim Englich + + * doc/conf/queries.properties: + Added Query for Years in VerticalProfiles in TimeSeriesPoints. + Modified the Query for Dates in VerticalProfiles in TimeSeriesPoints. + + * doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Added State for choosing the year and than it will only display + the Dates which are within the coosen year. + + * src/main/resources/lang/artifactMessages*.properties: + Added Ressource for diaplaying year. + +2010-01-12 Tim Englich + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java (configureHorizontalCrossSection): + Added the Method to load the Configurationsettings for horizontal-cross-sections + from the global Configuartion and put it into the Context. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java: + Added static variables to define the Keys used for horizontal-cross-sections + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java (getChartResult): + Integrated the Possibility to determin the required Snipped of an Mesh + using the ij-Index determined by the given Polygon. + Added the process-method which must still be implemented. + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java (worldEnvelopeCoordinatesToIndex): + Added worldEnvelopeCoordinatesToIndex-Method for determining the ij-Coodinates + for a given Envelope. + Some refactoring-Work done for reuse some existing Code of this Class. + + * doc/conf/conf.xml: + Added the Configuration-Node for horizontal-cross-sections in this + File. + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Added ij-Query Node to OutputState to make the Querystring + available to this Product. + +2010-01-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Use XMLUtils to read evaluate xpath expressions. Adapted xpath + expressions regarding namespace and prefix. + +2010-01-11 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java (readDocument): + Set NameSpaceAware to true to get the Unittests work again. + The Out-Calls doesn't work yet!!! + + +2010-01-11 Sascha L. Teichmann + + * pom.xml: Introduced dependency to GeoTools 2.4.5 (maybe a bit too old) + Needed to write traced polygons and line strings to shape files. + + * src/main/java/de/intevation/gnv/utils/Pair.java: New + simple pair tuple for type safety. + + * src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java: + New. Writes multi polygons and multi line strings to + shapefiles. Writing the multi polygons works. + + !! Writing the multi line strings fails! + !! Its not clear by now if its a geotool bug or a + !! misunderstanding of the API. The polygon and + !! the line string export are coded symmetrically + !! but the line string export complains about invalid + !! FIDs states. + + * src/main/java/de/intevation/gnv/raster/AbstractProducer.java: + New. Abstract base class for multi line string/polygons producers + as backends of the vectorizer. + + * src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java: + Inherits from AbstractProducer now. + + * src/main/java/de/intevation/gnv/raster/IsoProducer.java: + New. Common base class for the iso line producers, inherits + from AbstractProducer. + + * src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java: + Moved some code to new base class IsoProducer. + + * src/main/java/de/intevation/gnv/raster/DemuxRingsHandler.java: + New. Little helper class to demultiplex many ring handlers on + one single vectorizer. + + * src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java: + The implemented AttributeGenerator interface is defined in IsoProducer + now. + + * src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java: + New. Traces regions directly to JTS multi polygons. + + * src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java: + New. Traces iso lines directly to JTS multi line strings. + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java, + src/main/java/de/intevation/gnv/statistics/AbstractStatistics.java: + Removed needless imports. + +2010-01-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/fis/FISSelectArtifact.java: + Artifact used for the initial steps when no product is chosen. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java: Factory + to create artifacts. It is used to put a new FISSelectArtifact into the + ProxyArtifact for the initial steps when no product is chosen. + + * doc/conf/conf.xml: Use the ProxyArtifact instead of FISArtifact and + GNVArtifactFactory to create it. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + - Defined XPath expressions at the top of the class instead of directly in + code. + - Use XMLUtils.ElementCreator to create new namespace aware nodes and + attributes. + - Defined 'describe' method to create user interface for initial steps. + + * src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java, + src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java, + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java, + src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java: + Moved 'describe' methods which had no special code to super class. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Use + XMLUtils.ElementCreator to create new elements in xml documents. + +2010-01-09 Sascha L. Teichmann + + * doc/conf/conf.xml: Added configuration for vertical cross + section ground interpolation. + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java: Uses configured + interpolation method now. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Read configuration for vertical cross section ground interpolation. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java: + Added key and default for vertical cross section ground interpolation. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Forwards vertical cross section ground interpolation to QueriedXYDepth. + +2010-01-09 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Prevent NPE if no results are produced by vertical cross sections. + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java: Replaced + envelope checking by direct coordinate checking in tile cache. + Store the last used tile explicitly to save it from being collected + by the garbage collector. + +2010-01-08 Tim Englich + + Issue 137 + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (getPointValue), + src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java (key), + src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java (getStatisticsGenerator), + src/main/java/de/intevation/gnv/state/StateBase.java (extractKVP), + src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java (prepareInputData4RegionDBQuery), + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (advance): + Removed Encodingerrors from listed Files. All Files are now UTF-8 compliant. + +2010-01-08 Tim Englich + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestSuite.java (suite): + Added a Testsuit for executing all Testcases at once. + + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_feed.xml, + src/test/ressources/timeseries_mesh/timeseries_step_08_feed.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_feed.xml: + Changed the feeded Datevalues because the Values in the Database + have changed. TODO: Does it have an effect on the IDs? + + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_03_advance.xml, + src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java (testArtifact): + Switched Testcase to the new Condition that an LineString has to be entered. + + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_*.xml, + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java (testArtifact): + Switched Testcase to the new Condition that an Polygon has to be entered. + +2010-01-08 Tim Englich + + * src/main/resources/lang/artifactMessages.properties: + Added Ressources for the GUI for visualizing the Inputstate for + Polygons. + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Added State for the possibility to enter a Polygon which should clip + the data that will be visualized. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java (getChart): + Integrated the access to the Polygon which should be used to trim the Data which + should be visualized. + +2010-01-05 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java: + - Simplified code + - Search tile cache in reversed order because its more likely + that last loaded tile is used more than once. + - Stores cached tiles under soft references to prevent the + possible case to flood the memory with hires tiles. + +2010-01-05 Tim Englich + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java (depth): + Added the usage of the new RasterObject integrated in the geo-backend. + Now the Performance is much better accessing the depth to an coordinate. + +2010-01-04 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java: Declared + method to create a new xforms element as static to be able to use it + without instantiating an object of this class. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Splitted code pathes + of static and dynamic nodes. Static nodes contain the selected value + only instead of transfering the complete stack of possible values again. + +2010-01-04 Tim Englich + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java (process): + Changed the XYDepth-Interface-Implementation to QueriedXYDepth + + * doc/conf/queries.properties: + Added the Query for Rasterdataaccess. + + * src/main/java/de/intevation/gnv/math/QueriedXYDepth.java (QueriedXYDepth): + Added Implementation of the XYDepth-Interface for Querying the height + of an Position using the geo-backend interface. + It is only nessesary to add a Query with the id rasterQuery to the query-Properties. + +2010-01-04 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/statistics/Statistics.java: + Changed interface to allow general object results as + input for statistic calculation. This is needed because + the vertical cross section produces no SQL like resultsets. + + * src/main/java/de/intevation/gnv/statistics/AbstractStatistics.java: + New. Added common base class for different kind of statistics. + TODO: Move more common code into this class. + + * src/main/java/de/intevation/gnv/statistics/VerticalCrossSectionStatistics.java: + New. Statistics for vertical cross sections. Does nothing + by now. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Creates a VerticalCrossSectionStatistics object as statistics + generator now. + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java: + Inherits from AbstractStatistics now. Some code moved to new + base class. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Cleaned up the usage of statistics. + +2010-01-04 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Fixed problem with running to max depth on every column. + +2010-01-04 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Fix class cast exception to enable PDF export of + vertical cross section charts. + + * ChangeLog: Typo fixes. + +2010-01-04 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: + Uses ValueAxis.valueToJava2D() to transform data values into chart + space. This is slower than doing it via the Java2D matrix stack + but its more the JFreeChart way and prevents transforming of + graphical attributes too. TODO: Speed this up again! + + * src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java: + Forward plot to polygon renderer to make domain and range + axis accessible. + + * src/main/java/de/intevation/gnv/math/XYColumn.java: Moved code a bit. + +2010-01-04 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/jfreechart/PolygonSeriesLabelGenerator.java: + New. Interface to generate labels for polygon series. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: + Added logic to generate and render labels of polygons. + The implemented layout algorithm is greedy. For all + polygons with labels the label is placed on the center of + the ring, which center in terms of the indices of the vertices. + If the bounding box of the label intersects the bounding box + of a an already placed one alternative places are tried. + In level order positions at 1/4, 3/4, 1/8, 3/8, 5/8, 7/8 and + so on are evaluated for non intersections with former placed labels. + This terminates if a free place is found or all index positions + are exhausted. If no free position is found the label is omitted. + + The visual result is okay but could be improved by a more clever + algorithm e.g. tension reduction in the graph of labels. + + TODO: Improve clipping against chart borders. + + * src/main/java/de/intevation/gnv/jfreechart/LevelOrderIndices.java: + New. Little helper class to generate the level order index + traversal used in the label layout. Placed in the jfreechart + package to keep it clean from gnv dependencies. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java: + Added some methods to access the domain and range axis and + there edge position. Mainly C&P from JFreeCahrts XYPlot + to ease the coordinate transformation between Java2D and + the value spaces of the chart. Call the label generation + of the polygon renderer. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Added an implementation of PolygonSeriesLabelGenerator to + generate localized labels for the iso lines. + +2010-01-03 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + Only add colors to scale which are in the chart. + + * src/main/java/de/intevation/gnv/raster/Palette.java: Added + getter for 'color' field of palette entry. + +2010-01-03 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Generate iso line classes according gnv-issues/issue108: + + - If there are more than nine colors used in the chart + only the borders of the regions are traced. + - If there are less than ten colors each color region + is devided into two sub regions. + - If there are less than five colors each color region + is devided into five sub regions. + + Generate attribute per iso line class with the parameter value + of the iso line. + + * src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java: + Renamed inner interface from LabelGenerator to AttributeGenerator to + reflect the fact that the concrete label generation is a matter + of i18n too. The concrete label generation should be done when + the final chart is going to be created. TODO: Add + a JFreeChart style label generator to PolygonRenderer + + * src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java: + New. Implements the AttributeGenerator interface. It takes + the indices of the neighboring regions, uses these values + to look into the iso palette and averages the parameter values + at the touching borders. This should help in cases where + two regions are neighbored in the chart which are not neighbored + in the palette which may happen by quantification artifacts. + + * src/main/java/de/intevation/gnv/raster/Palette.java: Added + getters to 'from' and 'to' fields. + + * src/main/java/de/intevation/gnv/math/XYColumn.java: Fixed + another silly bug with adding values at surface and ground. + + * ChangeLog: Typo fixes + +2010-01-01 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Generate iso lines by dividing palette ranges in two + parts each and trace them. This shows that the ideas described + by K. Jancke in gnv-issues/issue108 are probably not the + right way to go. Applying this strategy there would be + locally too many isolines if there is a steep gradient. + On the other hand large areas are splitted in too less sections + by too less iso lines. A better way may be a splitting with + a look at the areas and shapes of the regions. Large, round + regions need more splits. Long, thin regions need less. + + * src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java: + Stabilized iso line hashing a bit. Added line width to + give iso lines a more appealing presentation in the chart. + The according value is stored in "line.width". + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: Fixed silly + bug when simplifying lines. This prevented iso lines + from rendering. + + * src/main/java/de/intevation/gnv/raster/Palette.java: Fixed index issue + when generating a divided palette. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java: + Do not crash with NPE any more when not having any series. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java: + Added method to add a whole collection of series. Useful to add + iso lines to dataset. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: + Set the "line.width" attribute when rendering lines. + +2010-01-01 Sascha L. Teichmann + + * doc/conf/conf.xml: Deactivated gauss filter because + it blurs no data areas too. Moreover gauss filtering does not + seem to be necessary at all. Possible TODO: Mask the no data + areas while filtering. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Added generation of polygon data suitable for PolygonPlot. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Some hacks to display the new Chart. XXX: This class is + a real mess ... but I've said that before. + + * src/main/java/de/intevation/gnv/chart/Chart.java: Made it + serializable. + + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java: + New. Chart for vertical cross sections. Mainly a copy of + Ingo's prototype implementation. TODO: parameter based i18n. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: Code + simplification. Made it Serializable to be cachable persistently. + + * src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: + Added fields for the interpolation and the generated PolygonDataset. + Its used as the data carrying object in cache now. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java: + Removed println debug code. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: + Added a little hack to draw the polygons of the interpolation. + The values are in y-direction all below zero (depth is given + by negative values) so the drawing is mirrored along y axis. + This special behavior is determined by the position of data + bounding box. At first I suspected a ccw issue here but some + initial tests falsified this hypothesis. We need to have a + deeper look at this but till than it works. + + * ChangeLog: Fixed some typos. + +2009-12-30 Sascha L. Teichmann + + * doc/conf/conf.xml: Fixed defect XML + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Use configuration to generate JFreeChart compatible polygons. + + * src/main/java/de/intevation/gnv/raster/PaletteManager.java: + Add method to access base palette. + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: + Added logging and new constructor. + + * src/main/java/de/intevation/gnv/math/ConstantXYDepth.java: + "Simulates" DEM with a constant depth. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: + Fixed bug with construction of buffer size. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Some clean ups. New method to calculate max depth. + + * src/main/java/de/intevation/gnv/math/XYColumn.java: + Fixed bug with extrapolation. + +2009-12-30 Sascha L. Teichmann + + * doc/conf/conf.xml: Added section gnv/vertical-cross-section + to configure the "Profilschnitte". + configures the size of + the sample area. Defaults to 1024x768. + ... configures the + list of post processing filters applied to the sample area + after the interpolation is done. Defaults to empty list. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java: + Added keys for vertical cross section samples and filters. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Parse the configuration for the new parameters. + +2009-12-29 Sascha L. Teichmann + + * doc/conf/conf.xml: Added a gnv/horizontal-cross-section-profile + section to configure the "horizontalen Schnittprofile". + gives the number of samples the + interpolation track is divided into. Defaults to 250 + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java: + The names of the keys for fetching informations from the + configuration context are stored here now instead of the factory. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Removed the lookup keys. Configure the "horizontalen Schnittprofile". + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Fetch number of samples from config now instead of no longer supported + system property. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + The key from chart template config is now in GNVArtifactContext, too. + +2009-12-29 Sascha L. Teichmann + + * doc/conf/conf.xml: Moved chart template and palette config + into new section 'gnv'. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Adjusted to new 'gnv' section in config. + Stores chat template under 'gnv.chart.template' and palettes + under 'gnv.color.palettes'. + Added authors. + + * src/main/java/de/intevation/gnv/utils/StringUtils.java: Fixed + index out of bounds issue. + +2009-12-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/Filter.java: New. + General filter mechanism raster in -> raster out. Useful + to chain processing. The Filter.Factory takes an + DOM element to configure itself. + + * src/main/java/de/intevation/gnv/raster/KernelFilter.java: + New. Implements raster filters based on kernel folding. Has + an inner class GaussFactory which acts as a factory to create + Gauss filters. The attributes "sigma" and "radius" are read + from the configuring DOM element to set up the parameters + of the kernel. + +2009-12-28 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/utils/WKTUtils.java: Refactored most + silly code like inefficent access to input data and redundant + WKT line string parsing. + + * src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java, + src/main/java/de/intevation/gnv/math/XYColumn.java: + Removed needless imports. + +2009-12-28 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/OutputStateBase.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Bring CallContext down to the chart generation. This is necessary to + access the configuration. BTW: this a much cleaner way than + the omnipresent singletons all around in the code! + + Observation: All the stuff derived from OutputStateBase is coded very messy + ... even if your demands are not high about aesthetic :-/ + + * src/main/java/de/intevation/gnv/utils/StringUtils.java: New. + Some functions to ease working with strings. + +2009-12-28 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/PaletteManager.java: New. + Used to manage several levels of palette subdivsions derived from + base palette. Contains name and description of palette, too. + + * src/main/java/de/intevation/gnv/raster/Palette.java: Removed + palette description because it is hold by the PaletteManager now. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + The palettes are not stored under the name of the palette any longer. + Instead the new attribute 'parameter-id' is splitted (comma separated) + into integers which are use as keys now. The values are PaletteManagers. + This should ease the access to an adequate PaletteManager when + generating a chart for a certain parameter. + + * doc/conf/conf.xml: Added the 'parameter-ids' for the four palettes. + The values are extracted from the gdiintern wiki. + + !!! This have to be in sync with the database parameter ids !!! + +2009-12-27 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java: + New. Vectorizer rings callback which produces iso lines in + form of PolygonSeries. These series can be added to PolygonDatasets. + If a IsoPolygonSeriesProducer.LabelGenerator is given + each of the series has an attribute "label" which could be used + to label text on the plot. TODO: Add label rendering to plot. + + Iso line generation is a bit more sophisticated than pure + region tracing. Along a border of a region there could + be more than one type of neighborhood. This is due to quantification + errors introduced by the fact that steep value gradients + are sampled to less points. The only ways out would be an + increase of the sample resolution or an other algorithm + working directly on the interpolated floating point samples. + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: Made + line simplification work with open polygons, too. + + * src/main/java/de/intevation/gnv/math/IJKey.java: Added method + to sort (i, j) in place. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: + Do not close line shapes because iso lines are not closed shapes + in general. + + * src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java: + Added author. Some reformatting. + +2009-12-26 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java: + New. Vectorizer rings callback which produces PolygonDatasets suitable + to be fed into PolygonPlot. + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: + Forward height to rings callback. + Made simplification of chains an option (default: true). + This should be turn off if generating iso lines. + Made edges hashable (handy to find neighbored edges in + iso line scanning). + + * src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java: + Added default constructor. Generate unique comparable long id + in thos constructor. + Added method to add a single ring. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java: + Added constructor to construct with a collection of polygon + series. + +2009-12-25 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/Palette.java: Added + method subdive(N) to Palette class which creates a new + palette in which each interval is splitted into N + equal sized intervals. Infinity sized intervals are not + splitted. This is useful to fulfill the conditions of + gnv/issue108. + +2009-12-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: + Use local variable debug instead of asking log.isDebugEnabled() + more than once. + + * src/main/java/de/intevation/gnv/math/XYColumn.java: extrapolate + with boundary values. + + * src/main/java/de/intevation/gnv/math/Interpolation3D.java: + Implements a 3D interpolation called 'Profilschnitt' along a + track similiar to the 'Horizontaler Schnittprofil' which takes + all k layers into account. + + At the interpolated (x, y) points columns of parameter values + from surface to ground are interpolated. To do so the four + next neighbor of that columns are figured out. Four + cubic splines are fitted through these parameter values + of these neighbors. Now its possible to continuous eval + the parameter on each. Every entry in the interpolated column + is interpolated bilinear from the four cubic spline interpolated + neighbor values at the respective depth. + + The result is stored into a double valued raster. NaN values + indicate interpolation gaps. + +2009-12-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/XYColumn.java: Added a method + prepare() which generates an continues interpolator for the + given z values. if only one value is given a constant function + is assumed. If the larger z-value is below zero the + next lower value is supplemented at zero. Symmetrically + if the lowest z-value is above the depth at the given point + the lowest value is repeated at depth. This should guarantee + that the gradient is vansihing towards the surface and the + bottom of the ocean. + + If after the supplementation there are less than three points + a linear interpolation is performed. If there are more than three + points a higher degree interpolation is used instead. This defaults + to a cubic spline interpolation. Overwrite the getInterpolator() + function to replace this behavior. + + * src/main/java/de/intevation/gnv/math/ConstantFunction.java: New. + Constant function used in interpolation. + + * src/main/java/de/intevation/gnv/math/LinearFunction.java: Added + an inner class Univariate which fits into the interpolation + framework. + + * src/main/java/de/intevation/gnv/math/HeightValue.java: Sort + z-Values in descending order because we are below zero. + + * src/main/java/de/intevation/gnv/math/XYDepth.java: New. Interface + to figure out the depth (negative values below surface) for + a given coordinate. TODO: Implement this by query the DEM grid + of the ocean. + + * src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: Added + authors. + +2009-12-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + When preprocessing database data only dissemble WKT points if we + have to. + Read z values as double value now. + Commented out CSV export because it takes the database data + as data which is not correct here. TODO: We need to implement some output + based on the interpolated data. + Added some type safety to better match the 2D code. + + * src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: Stores + XYColumns in ArrayList for better reused of the 2D code. + + * src/main/java/de/intevation/gnv/math/XYColumn.java: Removed toArray() + method because its not needed any longer. + +2009-12-23 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/XYColumn.java: Extends from + Point2d now to make some of the code (x/y sorting, envelope, etc.) + reusable in 3D from 2D code. + + * src/main/java/de/intevation/gnv/math/IJKey.java: New: The (i, j) hashing + is now moved to this class because of the new inheritance of XYColumn. + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Adjusted the (i, j) hashing. + + * src/main/java/de/intevation/gnv/math/Point2d.java: Added a new constructor + to make it easier to extend from it. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: Made the buffer + extend calculation a static method to be reusable in 3D case. + +2009-12-22 Sascha L. Teichmann + + * doc/conf/conf.xml: Load salinity palette correctly. + +2009-12-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Preprocessing of data used for interpolation. + + * src/main/java/de/intevation/gnv/math/AttributedXYColumns.java: Data + wrapper. Contains preprocessed data used for interpolation and some + metadata used for chart creation. + + * src/main/java/de/intevation/gnv/math/XYColumn.java, + src/main/java/de/intevation/gnv/math/HeightValue.java: Made them + serializable and added hashCode() and equals() to XYColumn to use it as + key in HashMaps. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java, + src/main/java/de/intevation/gnv/state/OutputStateBase.java: Changed some + method signatures. + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java: + Improved error handling. Return empty statistic set if there are no input + data. + +2009-12-22 Ingo Weinzierl + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: Adjusted + configuration for verticalcrosssection ('Profilschnitt') products. + + * doc/conf/queries.properties: Adjusted sql query for chart generation of + verticalcrosssection products. + + * src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java: Code + refactoring and better error handling. + +2009-12-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/math/HeightValue.java, + src/main/java/de/intevation/gnv/math/XYColumn.java: Added model classes to + store information for interpolation. + +2009-12-22 Sascha L. Teichmann + + * doc/conf/conf.xml: Added config section for palettes. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + load palettes at start up. + They are stored in a hash map under the key 'color.palettes'. The keys of + the map are the names from the configuration, the values are + de.intevation.gnv.raster.Palette objects. + Put configuration of chart template into own method. + + * src/main/java/de/intevation/gnv/raster/Palette.java: Added a palette + description. + +2009-12-21 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Ignore invalid interpolations correctly. + +2009-12-21 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/Raster.java: New. Models 2D double + rasters. Has some support for filtering with gauss kernels, building + iso classes, etc. + + * src/main/java/de/intevation/gnv/raster/Palette.java: New. Maps double + values to integer indices and colors. + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: New. Simple + vectorizer which traces regions in integer rasters. + + * pom.xml: Added dependency to GNU Trove 2.1.1 which is needed by the + vectorizer. + +2009-12-21 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/utils/WKTUtils.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Moved some methods back to old place. + +2009-12-21 Sascha L. Teichmann + + Added Ingo Weinzierl's special JFreeChart classes. + + * src/main/java/de/intevation/gnv/jfreechart: New package. + Should contain general JFreeChart stuff. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java: New. + New type of plot to display multi-polygons with holes. + + * src/main/java/de/intevation/gnv/jfreechart/CompactXYItems.java: New. + Basic vertex data model: a ring of a polygon. ccw = shell, cw = hole. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java: New. + Attributes a set of rings with key/value pairs. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java: New + List of PolygonSeries which makes it a multi-polygon. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java: New + A renderer to draw PolygonDatasets into a PolygonPlot. + +2009-12-21 Ingo Weinzierl + + * doc/conf/products/verticalcrosssection/conf_mesh.xml: Prepared states and + transitions of verticalcrosssection (german 'Profilschnitt'). + +2009-12-21 Ingo Weinzierl +a + * src/main/java/de/intevation/gnv/utils/WKTUtils.java + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Outsourcing of some methods to prepare results for chart creation. + +2009-12-21 Sascha L. Teichmann + + * doc/conf/palette/flow-velocity.xml: + color palette for flow velocity "Fliessgeschwindigkeit". + * doc/conf/palette/water-levels.xml: + color palette for water levels "Wasserstaende". + * doc/conf/palette/salinity.xml: + color palette for salinity "Salzgehalt". + * doc/conf/palette/water-temperature.xml: + color palette for water temperature "Wassertemperatur". + +2009-12-21 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Added some code to prevent needless null inserts if interpolating + over large gaps. + +2009-12-21 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java: + Removed warning, which told the user that gap detection is not implemented + yet. + +2009-12-21 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java, + src/main/java/de/intevation/gnv/math/Interpolation2D.java: Add 'null' + values for gap detection to result collection instead of omitting them. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.jav: + Handle null values - don't throw an exception. + +2009-12-17 Sascha L. Teichmann + + RELEASE 0.3 + + * Changes, NEWS, ChangeLog: Summarized activities + +2009-12-17 Sascha L. Teichmann + + * doc/conf/conf.xml: Bind REST server to localhost. + +2009-12-17 Sascha L. Teichmann + + * src/test/ressources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_de.properties: + s/Modeldaten/Modelldaten + +2009-12-17 Sascha L. Teichmann + + * src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_de.properties: Removed + wkt line strings. + +2009-12-17 Ingo Weinzierl + + * doc/conf/queries.properties: Added K-position to sql statement for + verticalprofile charts on meshes. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Changed + the depending axis for gap detection on meshes for verticalprofile charts. + +2009-12-17 Ingo Weinzierl + + Issue 106 + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Fixed a file-leak bug while reading chart template. Sourced parsing of xml + file out to XMLUtils of de.intevation.artifactdatabase.XMLUtils. + +009-12-17 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Added column labels for csv export. + +2009-12-17 Hans Plum + + Issue 129: Release 0.2: Verbesserung der �bersetzungen + + * src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_de.properties: + Fixed i18n strings for german language + +2009-12-16 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: + Fixed index error in i-gab detection between neighbors. + +2009-12-16 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Override method to create chart. Fixed some bugs for interpolation. + + * src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java: + Chart class for generating horizontal crossprofile charts. Horizontal + crossprofile charts are a subclass of horizontal profile charts. + + * src/main/java/de/intevation/gnv/math/Point2d.java: Changed epsilon value. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: Fixed some bugs + regarding buffer size to limit data for interpolation. + + TODO: At the moment, there is no gap detection for horizontal crossprofile + charts. + +2009-12-16 Ingo Weinzierl + + Issue100 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: + Workarround: Store information about max range of data for each parameter + while iterating over all data values. Set the max range at the end of + chart generation. + + NOTE: NumberAxis.setAutoRange(true) doesn't seem to work properly. + +2009-12-16 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java: + Removed useless import of VerticalCrossSectionChartFactory. + + * src/main/java/de/intevation/gnv/chart/HorizontalCrossSectionChartFactory.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java, + src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChartFactory.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java, + src/main/java/de/intevation/gnv/chart/ChartFactory.java: Removed useless + chart factory classes. + +2009-12-16 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/utils/DistanceCalculator.java: + Added method to calculate distance of path. + TODO: Move this class into math package and and add + an slerp interpolator so it can be used as a metric inside + the interpolation code. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Added code to disassemble the incoming result set, interpolate + along a given path and returns an adjusted result set. + The (i, j) got lost on this track because we don't travel along + the main axis of the grid any more. The test for gaps has to be + adjusted because, because the dx/dy on the path depends on how + many steps are made on the way [*]. This is controlled by the system + property 'interpolation.step.width'. It is set in meters + and defaults to 100m. TODO: This should be configurable + in the conf.xml file. + + [*] I opt strongly for integration of the outlier test based gap + detection to overcome this problem. + +2009-12-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/LinearToMap.java: + Uses JTS Coordinate as geometry model now. + + * src/main/java/de/intevation/gnv/math/Metrics.java, + src/main/java/de/intevation/gnv/math/Interpolator.java: New. + Moved from inner class of LinearToMap to top level class + to be more reusable. Uses JTS Coordinate as geometry model now. + + * src/main/java/de/intevation/gnv/math/Point2d.java: New. + Extends JTS Coordinate to have an additional (i, j) + to model the topological neighborhood within the mesh, too. + + * src/main/java/de/intevation/gnv/math/Interpolation2D.java: New. + Has a method interpolate() which takes a path line string in form + of a list of JTS Coordinates, a list of grid points (Point2d + to carry the topology, too), a linear range in diagram coordinate + space, a metric to cope with the projection. It reports + interpolated points to an implementor of the new inner interface + Consumer as a JTS Coordinate. (x, y) of this coordinate is the + postion on the map, the z value is the interpolated attribute. + + To speed up the search for the neighbors the input points are + sorted into a quadtree and are queried first level with a buffer of + size (max(abs(p[i].x - p[i+1].x)), max(abs(p[i].y - p[i+1].y))) + around the point to be interpolated. The second level filter + is performed by an inverse L1-ordering with region coding, so + that only the nearest four neighbors are taken into acount. + Only if all four neighbors are present and no + i- or j-gaps exist the interpolation is performed. TODO: Create + a better extrapolation strategy in these cases were these conditions + are not fulfilled. + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + Added a process() method to perform the interpolation. It does + nothing by now. TODO: bring it to life. + +2009-12-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/math/LinearToMap.java: Map linear + coordinates (from, to) to world coordinates (x, y) along a line string + given by a set of java.awt.geom.Point2D points. + + * src/main/java/de/intevation/gnv/math/LinearMetrics.java: Implements + Euclidean metric used by LinearToMap. TODO: Do same for WGS84 to + be more precise. + +2009-12-15 Tim Englich + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java (calculateStatistics): + Issue96 Resloved big that one entry is missiing in the Statitic. + The last row of the ResultSet was never used. + +2009-12-15 Ingo Weinzierl + + Issue106 + + * doc/conf/conf.xml: Added charttemplate to global configuration. + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java: Made + method static to call it without initiating an object of its class. + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Create ChartTheme at startup of artifact server and put it into global + context. The theme is created one time on this way. + + * src/main/java/de/intevation/gnv/state/OutputState.jav, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Changed + signature of 'out'-method. Call 'out' with CallContext instead of + CallMeta, which is contained in CallContext. CallContext is needed to + fetch the ChartTheme out of it. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java: + Changed signature of 'getChart'-method which now gets the CallContext + containing the ChartTheme. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Get ChartTheme from CallContext instead of reading the XML file here. + +2009-12-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java: + If a few (i, j) values are not available (gaps in the grid) try + to fill the holes with guessing the values by the ones which could + be fetched. We are using a componentwise linear function here. + This is surely slightly wrong because world coordinates are + in WGS84 which is ellipsoid in nature. TODO: Look at the errors + and if needed compensate them by using cubic polynonial or ellipsoid + function terms. + + * src/main/java/de/intevation/gnv/math/LinearFunction.java: New. + Linear function to be used in curve fitting process. + +2009-12-15 Tim Englich + + * doc/conf/queries.properties: + Added the Unit of the Parameter to the Query for Parameters in + all Parameterqueries where it was still missing. Now the Unit will + be displaied in the Combobox and in the Diagramm-Axis-Description. + +2009-12-15 Sascha L. Teichmann + + * pom.xml: Upgraded to Apache Commons Math 2.0. Needed for + curve fitting (splines e.g) + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java: + Use 'new DescriptiveStatistics()' instead of + 'DescriptiveStatistics().newInstance()' to be compatible with new + math api. + +2009-12-15 Tim Englich + + Added the Unit of the Parameter to the Query for Parameters in + TimeSeries. Now teh Unit will be displaied in the Combobox and + in the Diagramm-Axis-Description. + + * src/main/resources/lang/artifactMessages*.properties: + Added the name Productname for "horizontale Schnittprofile". to the + Resources so that it could be displaied properly in the GUI + +2009-12-15 Tim Englich + + * src/main/resources/lang/artifactMessages*.properties: + Added the required Resources for the Outputelements of "horizontale Schnittprofile". + * doc/conf/queries.properties: + Added the specialized Queries for getting the Data and the depths for + generating "horizontale Schnittprofile". + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java (log): + Added an new OutputTransition to handle the special Way to d detremine the required + Data for generating "horizontale Schnittprofile". + * doc/conf/conf.xml, + doc/conf/products/horizontalprofile/conf_mesh_cross.xml, + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshCrossArtifact.java: + Added Support for "Horizontales Schnittprofil"-Artifacts to the Project + +2009-12-15 Ingo Weinzierl + + Issue102 + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: + Reset 'nextColor' at the beginning of chart creation. Now, color of lines + in charts are stable, which means, that an export will look like the chart + in the gui itself. + +2009-12-14 Ingo Weinzierl + + Issue101 + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Changed date + representation in timeseries charts. Date format is sourced out to + ressource files. German date representation is now 'dd-MMM-yyyy' (eg + 31-12-2009) and the english date representation is 'yyyy-MMM-dd' (eg + 2009-12-31). + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added date format + strings for timeseries charts. + +2009-12-14 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/utils/IndexBuffer.java: + Creates SQL-WHERE clauses for buffers around a list of + line segments in index (i, j) space. + +2009-12-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: + Exception handling while creating subtitle of horizontalprofile charts. + Included the case, that there is no start and no end date. + +2009-12-11 Sascha L. Teichmann + + * src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: + Removed needless imports. + +2009-12-11 Tim Englich + + * doc/conf/queries.properties: + Added Z-Value to verticalcrosssection_mesh_chart_data. + +2009-12-11 Tim Englich + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java, + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointHorizontalProfileTestCase.java, + src/test/java/de/intevation/gnv/artifacts/InstantaneousPointVerticalProfileTestCase.java, + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java, + src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java, + src/test/java/de/intevation/gnv/artifacts/MeshTimeSeriesTestCase.java, + src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java, + src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java, + src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java, + src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java: + Split all Unittestcases in separat Classes. Now it is easier to uses the UnitTests with Maven. + +2009-12-11 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Fade out + gridlines of range axis in charts if there are more than one axis. + +2009-12-11 Ingo Weinzierl + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added axis labels + for horizontalprofile, verticalprofile, horizontalcrosssection and + verticalcrosssection charts. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java, + src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java, + src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java, + src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java: + Read axis labels from ressources instead of hard coded strings in code. + +2009-12-11 Ingo Weinzierl + + Cleared Issue104. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added axis label + for timeseries charts. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Removed hard coded axis label of timeseries charts. Read label from + ressources. + +2009-12-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Added + gap detection for horizontal and vertical profile charts. + +2009-12-09 Sascha L. Teichmann + + * doc/conf/conf.xml: Expanded the time to live of inactive artifacts + to 3600000ms (= 1h). Dead artifacts are removed from databasse + only every 15mins now. Improved the description on the artifact + factories. + +2009-12-08 Tim Englich + + * doc/conf/queries.properties: + Added the Unit of the Parameter to the Query for Parameters in + TimeSeries. Now teh Unit will be displaied in the Combobox and + in the Diagramm-Axis-Description. + +2009-12-08 Tim Englich + * src/main/java/de/intevation/gnv/transition/profile: + Removed empty needless package. + * src/main/java/de/intevation/gnv/transition/TransitionFactory.java: + src/main/java/de/intevation/gnv/transition/ValueCompareTransition.java, + src/main/java/de/intevation/gnv/transition/TransitionBase.java, + src/main/java/de/intevation/gnv/transition/Transition.java, + src/main/java/de/intevation/gnv/transition/DefaultTransition.java: + The new Transitions which has the only job to provide the connectios between + the different States and look if it is Possible to go the different Ways. + * src/main/java/de/intevation/gnv/state/StateBase.java, + src/main/java/de/intevation/gnv/state/State.java: + Removed the Logic to descide which State is be reacable as next. + Now the Transition configured in the Artifacts will do that according + to the modified TransitionModel. + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (transitions): + Added the Transitions to the Artifact and changed the Logic. + Now the Transition is able to decide if it could be uses or not. + * doc/conf/products/verticalprofile/*.xml: + Modified the Configuration. Splitted States and Transitions into + different XML-Fragments according to the modified Transitionmodel. + +2009-12-08 Ingo Weinzierl + + * doc/conf/queries.properties: Added marker ('DATAID') for different data + sources. + +2009-12-08 Tim Englich + + * doc/conf/products/*.xml: + Switched all Package and Classnames to the new Names. + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + Switched Imports from de.intevation.gnv.transition to de.intevation.gnv.state + and renamed all Mebers and local Variables from *transition* to *state* + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java: + Changed the Class for the loggeer from TimeseriesoutputTransition + to ArtifactXMLUtilities because it was wrong. + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java, + src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java, + src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java, + src/main/java/de/intevation/gnv/statistics/Statistics.java, + src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java, + src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java, + src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java, + src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java, + src/main/java/de/intevation/gnv/exports/DefaultDataCollector.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChartFactory.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java, + src/main/java/de/intevation/gnv/chart/HorizontalCrossSectionChartFactory.java, + src/main/java/de/intevation/gnv/chart/ChartFactory.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: + Changed import from de.intevation.gnv.transition.* to de.intevation.gnv.state.* + according to refactoring Work in the Transitionsmodel. + * de.intevation.gnv.transition.* + Moved to de.intevation.gnv.state.* + and renamed all Mebers, local Variables, and Methodsignatures from *transition* to *state* + +2009-12-07 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Remove unselected parameters from parameters list before initiating + charts. Parameter names are used as axis labels. + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Changed + the way of adding data to charts: same parameters are stored in the same + dataset. Now, each parameter has only one axis. Axes and renderer are + adjusted one time after collecting data - not after creating every + single series. + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Added some + more colors to distinguish between different parameters/attributes. + Changed method to adjust rendering options regarding the changes of + datasets described above. + +2009-12-07 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Changed method + generateChart to initChart, which just created a new timeseries chart. + General chart stuff is done in AbstractXYLineChart. + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Sourced + ChartFactory call out to a new initChart method. This has been done, + because TimeSeriesCharts needs to initiate another type of chart than + horizontal or vertical charts. + +2009-12-04 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java: + Added method to fetch a string from ressource bundle with a specified + locale. Before, there just have been existing a method to fetch string + from ressource bundle on basis of the first locale in a list of locales. + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java: + Added method to fetch strings from ressource bundle from RessourceFactory + with a specified locale, a key and a default value, if there is no string + matching key in bundle. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Added methods for creating title and subtitle of charts. FIS name is + fetched from ressource bundle with best locale (regarding supported server + and client locales) instead of first locale in list of supported locales + of the server. + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java: + Changed title of charts. The main title contains FIS and station name. The + subtitle contains the time period, the cruise, the depth and the position + of a chart. + + * src/main/java/de/intevation/gnv/chart/ChartLabels.java: Added subtitle as + parameter in class and constructor. + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Added a + subtitle to charts. Titles and subtitles are stored in a ChartLabels + object. + + * src/main/resources/lang/artifactMessages.properties, + src/main/resources/lang/artifactMessages_de_DE.properties, + src/main/resources/lang/artifactMessages_en.properties, + src/main/resources/lang/artifactMessages_de.properties: Added strings for + chart title. + +2009-12-04 Sascha L. Teichmann + + * ChangeLog: Cleaned up a bit. + +2009-12-02 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Added time gap + detection. If a time gap is detected, a null value will be inserted to + break the current line. + +2009-12-02 Ingo Weinzierl + + * pom.xml: Added JBoss repository for JFreeChart 1.0.13 and removed explicit + JCommon dependency which is now needless. Now, it is no more necessary to + install JFreeChart into the local maven repository on your own. + +2009-12-02 Ingo Weinzierl + + * doc/conf/charttemplate.xml: Added lines to configure rendering of lines + and points in charts (visibility of lines/points and size of points). + + * src/main/java/de/intevation/gnv/chart/XMLChartTheme.java: Added method + parsing the rendering options for lines and points in charts. + + * src/main/java/de/intevation/gnv/chart/AbstractChart.java: Added boolean + member attributes which are used to control the visibility of lines and + points in charts. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: + Constructor needs two further boolean parameter to control the visibility + of lines and points in charts. + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: The + renderer controlling the style of a series is adjusted after adding a + new series to the chart. + + * src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.jav, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Adjusted method calls regarding the constructor changes in *Chart classes. + + TODO: Lines and points in charts will both always be rendered at the + moment. This needs to be changed as soon as a new gui option is + implemented to control the visibility of lines/points. + +2009-12-01 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java: + Added one more Transitionstep to each Testcase according to the refactored Transitionmodel. + * src/test/ressources/verticalprofile/verticalprofile_step_*_advance.xml, + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_*_advance.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_*_advance.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_*_advance.xml, + src/test/ressources/timeseries_mesh/timeseries_step_*_advance.xml, + src/test/ressources/timeseries/timeseries_step_*_advance.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_*_advance.xml, + src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_*_advance.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_*_advance.xml: + Moved each Adancedocument plus one according to the refactored Transitionmodel. + Added the first advanced Call for the Product-Artifact + +2009-12-01 Tim Englich + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java: + All Data which is required to generate the Charts is now fetched using the + Method getChartResult. The Method advance and initialize now have nothing to do. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out): + Removed the advance call because all Data which is required to generate the Charts is + fetched using the Method getChartResult. + * src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java (initialize): + Use Method instantiate instead of Advance to add the required Data for describe + and feed this Transition. + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (initialize), + src/main/java/de/intevation/gnv/transition/Transition.java (initialize): + Added new Method Initaialize which will be callcall to Initailize the current + Transition. In this step all Data will be fetched which is required to Ddescribe and + feed each Transition. + Also the AlternativeTransition was removed because it is not longer required. + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (advance): + Switched to the usage of the Method initialize instead of Advance while instantiating + a new Productartifact, according to the Refactoring work wich is done in the + TransitionModel. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (initialize): + Added new Function Initialize so that it is possible to Initialize an Artifact + without doing this in the Constructor. That is nessessary because some Artifacts need + some Metadata (e.g. SourceID) befor it can be initialized. + + * doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Some Refactoring work done according to the Refactoring Work wich + was done in the Transitionmodel. + +2009-11-30 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java, + src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java: + Removed needless imports. + +2009-11-30 Ingo Weinzierl + + * pom.xml: Updated batik dependencies to 1.7 + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: Use + java native DOMImplementation instead of Batik's SVGDOMImplementation, + which is not present in batik 1.7 libs. + +2009-11-30 Ingo Weinzierl + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added svg + to output modes (MimeType image/svg+xml). + + * pom.xml: Added batik 1.6.1 dependencies which are used to create svg + exports. + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: + Implemented chart export to svg. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Output mode 'svg' will call svg export of ChartExportHelper. + +2009-11-30 Ingo Weinzierl + + * pom.xm: Added iText 2.1.7 dependency (to create pdf's). + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: + Implemented chart export to pdf using iText library. The chart fills the + complete page. A boolean system property "export.pdf.landscape" can be + used to adjust the page orientation (portrait or landscape, default is + landscape). + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Added method for exporting chart to pdf. Calls the new method of + ChartExportHelper. + +2009-11-27 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java + (testHorizontalProfileInstantaneousPointArtifact), + src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_*.xml: + Added new stapes using the RegionFilter into the Tescase of HorizontalProfiles Instantaneous Point. + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_feed.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_feed.xml: + Bugfix: Removed second dateid. horizontalcrosssection and verticalcrosssection only provide the usage of one dateid. + * doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml: + Added the RegionFilters into the configuration of the Products for + Horizontalprofiles IntantaneousPoints. + * doc/conf/queries.properties: + Query to select only Ships, Cruises, Tracks which are within an Region. + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (extractKVP): + Added Row-Number lookup for ColumnNames for Performanceimprofements. + +2009-11-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/ChartExportHelper.java: Helper + class to export charts. Dependencies on JFreeChart and iText are capsuled + here, no further dependencies in OutputTransitions. Export methods for + images and pdf already implemented. + + * src/main/java/de/intevation/gnv/chart/Chart.java, + src/main/java/de/intevation/gnv/chart/AbstractChart.java: Outsourcing of + export methods to ChartExportHelper. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Adapted current export of charts. + +2009-11-26 Ingo Weinzierl + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added pdf + as export format. + +2009-11-26 Ingo Weinzierl + + * TODO: Added point in TODO regarding tick units and distance between tick + units in timeseries charts. + +2009-11-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Localized + chart axis. Two method have been added - method to localize y-axis of + charts, abstract method to localize x-axis of charts. + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Override + abstract method to localize x-axis. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Call algorithm to determine the best locale regarding intersection of + supported server and browser locales. This locale is used to create + localized charts. + +2009-11-26 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java: + New method getLocales() which returns an array of locales which are + supported by the server. + + * src/main/resources/lang/lang.conf: Config-file for supported languages. + The resource bundles for localized text should be configured here. It is + used to determine the best locale regarding the supported locales by + server and browser. + +2009-11-25 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Override + method generateChart to instantiate TimeSeries charts instead of XY + charts. Before these changes, timeseries charts did not have a valid date + axis. + +2009-11-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/AbstractChart.java, + src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: Added + timegap definitions, adapted constructors. + + * src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Adapted creation of charts regarding changes of constructors. + +2009-11-24 Tim Englich + + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_feed.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_feed.xml, + src/test/ressources/timeseries_mesh/timeseries_step_08_feed.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_feed.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_feed.xml, + src/test/ressources/timeseries/timeseries_step_06_out_chart.xml: + Added new Timevalues because the Data in the DWH has changed. + +2009-11-24 Ingo Weinzierl + + * pom.xml: Added dependencies for esri and ibm libraries required for unit + tests. + +2009-11-24 Tim Englich + + * src/test/ressources/timeseries/timeseries_step_06_out_chart.xml: + Added mime-type to get a propper output-result and not an NPE + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java (findValueTitle): + Added null-value check to prevent NPEs. + * src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.java (getChart), + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java (getChart), + src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java (getChart), + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java (getChart): + Changed Method-Signature to this one which the base method provide. + Now the Methods will be used again. + +2009-11-24 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java (TestCallContext): + Removed Compilationerrors that were triggert by API-Changes in + Module Artifact-Database. + + * doc/conf/queries.properties, + doc/conf/products/timeseries/conf_mesh.xml: + Removed Meshpoint from SQL-Query because the same value will be + insert by using the depthid. + depthid on layer 1 = featureid + In the old configuration only Charts on Layer 1 were drawn. + issue91 + +2009-11-23 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java: + Remove chart from cache when data which is displayed has changed. + +2009-11-23 Ingo Weinzierl + + * doc/conf/charttemplate.xml: Added configuration file for chart themes. + + * src/main/java/de/intevation/gnv/chart/XMLChartTheme.java: Theme class for + reading xml files which describe chart styles. It extends the + StandardChartTheme class of JFreeChart which defines default values for + chart parameters. It is possible to apply different xml configurations for + different charts. + + * src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Before creating a new chart, an instance of XMLChartTheme is initialized + which is responsible for the chart style. + + NOTE: 'charttemplate.xml' is used by artifact server and has to be placed + in the config directory. + +2009-11-20 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Export format of charts (png, jpeg, gif) depends on mime-type. + + * src/main/java/de/intevation/gnv/chart/Chart.java, + src/main/java/de/intevation/gnv/chart/AbstractChart.java: Renamed export + method, because it doesn't export just png anymore, but jpeg or gif as + well. + +2009-11-20 Ingo Weinzierl + + * src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_out_chart.xml, + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_chart.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_out_chart.xml, + src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_out_chart.xml, + src/test/ressources/timeseries_mesh/timeseries_step_08_out_chart.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_out_chart.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_out_chart.xml, + src/test/ressources/verticalprofile/verticalprofile_step_06_out_chart.xml: + Removed mistake in xml structure of artifact protocol. Mime-type node was + called 'out' instead of 'mime-type'. + +2009-11-20 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java, + src/main/java/de/intevation/gnv/chart/AbstractChart.java, + src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java, + src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java, + src/main/java/de/intevation/gnv/exports/DefaultProfile.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java, + src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Removed duplicated and needless imports. + +2009-11-20 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java: + Added methods for caching charts. + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Changed chart generation. Charts will now be generated in a central place + in TimeSeriesOutputTransition which is the parent class of other + OutputTransitions. Each OutputTransition got a new method to serve its own + special chart class. + + * TODO: Added hint for caching charts. Verticalcrosssection and + orizontalcrosssection charts aren't implemented yet. + + NOTE: Charts can be cached. This could be useful if the user exports + charts as svg, png or pdf. The caching of charts is configured via system + property 'cache.chart' at the moment. + +2009-11-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/transition/OutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Changed parameter of 'out'-method of OutputTransition. Now, the + OutputTransition gets the complete xml document of the request (before + just the target name). The mime type of this xml ist used to distinguish + between different output formats of charts (png, jpeg). + +2009-11-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java, + src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java: + Classes for creating charts of different output transitions, inherit from + AbstractXYLineChart. The subclasses should only implement special code. + General configurations should be done in AbstractChart or + AbstractXYLineChart. + + TODO: Take care of gaps between two values. + +2009-11-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/Chart.java: Interface, which + declares basic method to create charts and export it in different formats. + + * src/main/java/de/intevation/gnv/chart/AbstractChart.java, + src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java: Abstract + chart classes which declare basic methods for chart creation and implement + general methods used by subclasses. + +2009-11-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/utils/DistanceCalculator.java: Declared a + method as static, which can be used without instantiating an object of its + class. + +2009-11-17 Ingo Weinzierl + + * pom.xml: Changed version of JFreeChart from 1.0.12 to 1.0.13 and added + dependency of JCommon 1.0.15, which is used by JFreeChart. + + NOTE: The JFreeChart 1.0.13 jar has to be installed on your own for the + time the central maven repository is broken. + +2009-11-17 Ingo Weinzierl + + * pom.xml: Changed version of JFreeChart from 1.0.7 to 1.0.12, which + includes the template mechanism to configure the style of charts. + + NOTE: JFreeChart 1.0.13 is the newest release, but the maven repository + does not contain a pom.xml file. Created an issue on + (http://jira.codehaus.org/browse/MEV-647). + +2009-11-16 Ingo Weinzierl + + * bin/run.sh: Added start-script to version control. + +2009-11-13 Hans Plum + + * RELEASE 0.2: + Summarized activities in NEWS, Changes + +2009-11-13 Hans Plum + + * ChangeLog: + Unified style of ChangeLog descriptions refering to issues. + +2009-11-13 Tim Englich + + * doc/conf/products/timeseries/conf_timeseriespoint.xml: + Moved Comment according to Instantiationerrors loading Artifact. + +2009-11-13 Tim Englich + + * doc/conf/log4j.properties,, + doc/conf/conf.xml, + doc/conf/arcsdeconnectionpool.properties, + doc/conf/products/timeseries/conf_timeseriespoint.xml: + Added Documentation of Configuration-Files. + +2009-11-13 Tim Englich + + * doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Removed statistics as possible out-Variant from Configuration + according to TG_0030.061 + + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_out_statistics.xml, + src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_out_statistics.xml, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalCrossSectionMeshArtifact), + (testVerticalCrossSectionMeshArtifact): + Removed Statistics-Test on This Artifact-Test because no Statistic is required + for this Producttyp. + + * src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/ + HorizontalCrossSectionMeshOutputTransition.java (createCSV): + No Statistics for this Output is required. + + * src/main/java/de/intevation/gnv/statistics/HorizontalCrossSectionStatistics.java: + Removed becaus the Statistics for ths product is not required. + +2009-11-12 Tim Englich + + * src/main/java/de/intevation/gnv/statistics/HorizontalCrossSectionStatistics.java (calculateXOrdinateValue), + src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java (calculateXOrdinateValue), + src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java (calculateXOrdinateValue), + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java : + Added the previous Row to the Method for calculating the GAP between + those Rows. Also added Calculation of the Distance between two Points in + HorizontalProfileStatistic and returning the Depth in VerticalProfileStatistics. + Also added the Metjod clearStatistics to restet the Object if an new Calculation + will started. + +2009-11-12 Tim Englich + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (extractKVP): + Translated "Keine Auswahl" to "No Selection" according to the Specification that + the primary Language is english. Please note that the Values that are currently + displaied are almost in german. + +2009-11-12 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (writeStatistics2XML): + Changed XML-Syntaxt according to the new Structure of StatisticValues. + (out): + Changed Call of calculateStatistics according to the new Methodsignature. + + * src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java, + src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java. + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java, + src/main/java/de/intevation/gnv/statistics/Statistics.java: + Extended Methods calculateStatistics to put Lable-Values into the + Calculation. Now for each Group of Statistics is it possible + to calclulate a separat name which is simmilar to the name of + the Diagramm-Series-Name. + Also the Representation of the Statistics has changed so each Group + will be stored in one StatisticSet + + * src/main/java/de/intevation/gnv/statistics/StatisticSet.java: + Bean for Storing the Statistic to one Group and also storing the + Name of the Statistic. + +2009-11-11 Tim Englich + + Issue 19: Validation of max. min value order + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (putInputData): + Added Validation if a given maxvalue is greater than a given minvalue issue19 + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid): + Added new Method for validating if a maxvalue is greater than a minvalue. issue19 + +2009-11-11 Tim Englich + + Issue 81: Keeping input values in coordinate input fields + + * src/main/java/de/intevation/gnv/transition/describedata/DefaultSingleValueDescribeData.java + (setValue), src/main/java/de/intevation/gnv/transition/describedata/SingleValueDescribeData.java: + Added setValue-Method + for setting the Value which was sent back to the Server using the feed-request. issue81 + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (getDescribeData): + Added SingleValueDescribeData to the method for storing InputValues for + Describeoutput issue81 + +2009-11-11 Tim Englich + + * src/main/java/de/intevation/gnv/transition/describedata/MinMaxDescribeData.java, + src/main/java/de/intevation/gnv/transition/describedata/DefaultMinMaxDescribeData.java: + Added getName and added Constants for minValue and maxValue Id to + enable the storage of this Values which would be put using the + feed command. + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe): + Changed the usage of the Name of the MinMaxTransition from getMinName to getName. + + * src/main/java/de/intevation/gnv/transition/MinMaxTransition.java (purifyResult): + Changed the Constructor of MinMaxTransition according to API-Changes of + DefaultMinMaxDescribeData + +2009-11-11 Tim Englich + + Issue 76: Improving XML config documents + + * doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Removed unnecessary characters 'v' from the Documents. issue76 + +2009-11-10 Tim Englich + + * src/main/resources/lang/artifactMessages_*.properties: + Added Ressources for the AreaFilter Ids areaid and subareid + +2009-11-10 Tim Englich + + Issue 68: Improving ODV Export + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (TIMESERIES_ODV_PROFILE_NAMES): + Sort Columns to the given order of the ODV-Specification + and added the Columns DATAVALUE and PARAMETER to the output + according to issue68 + + * doc/conf/queries.properties: + Changed Column-alias in Query for HorizontalProfile ODV-Exports in Meshes + from PARAMETERID to PARAMETER to be able to use in only on ODV-Export-Profile + +2009-11-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalCrossSectionMeshArtifact): + Added the ODV-Export to the Unit-Testcase for VerticalCrossSection-Mesh. + Some Refactoring Work done. + * doc/conf/products/verticalcrosssection/conf_mesh.xml: + Added QueryID for ODV-Exports to the Configuration of an + Mesh-VerticalCrossSection-Artifacts + * doc/conf/queries.properties: + Added Query for VerticalCrossSection ODV-Exports in Meshes. + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_feed.xml: + Changed Datevalue, because the old value was out of range to the Data. + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_08_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for + VerticalCrossSection Mesh. + +2009-11-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalCrossSectionMeshArtifact): + Added the ODV-Export to the Unit-Testcase for HorizontalCrossSection-Mesh. + Some Refactoring Work done. + * doc/conf/queries.properties: + Added Query for HorizontalCrossSection ODV-Exports in Meshes. + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Added QueryID for ODV-Exports to the Configuration of an + Mesh-HorizontalCrossSection-Artifacts + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_feed.xml: + Changed Datevalue, because the old value was out of range to the Data. + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for + HorizontalCrossSection Mesh. + +2009-11-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileInstantaneousPointArtifact): + Added the ODV-Export to the Unit-Testcase for HorizontalProfile-InstantaneousPoint. + Some Refactoring Work done. + * src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for + HorizontalProfiles InstantaneousPoint. + * doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml: + Added QueryID for ODV-Exports to the Configuration of an + InstantaneousPoint-HorizontalProfile-Artifacts + * doc/conf/queries.properties: + Added Query for HorizontalProfile ODV-Exports in InstantaneousPoint + +2009-11-10 Tim Englich + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalProfileInstantaneousPointArtifact): + Added the ODV-Export to the Unit-Testcase for VerticalProfile-InstantaneousPoint. + Some Refactoring Work done. + * doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: + Added QueryID for ODV-Exports to the Configuration of an + InstantaneousPoint-VerticalProfile-Artifacts + * doc/conf/queries.properties: + Added Query for VerticalProfile ODV-Exports in InstantaneousPoint + * src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for VerticalProfiles InstantaneousPoint. + +2009-11-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileMeshPointArtifact): + Added the ODV-Export to the Unit-Testcase for HorizontalProfile-Mesh. + Some Refactoring Work done. + * doc/conf/products/horizontalprofile/conf_mesh.xml: + Added QueryID for ODV-Exports to the Configuration of an + Mesh-HorizontalProfile-Artifacts + * doc/conf/queries.properties: + Added Query for HorizontalProfile ODV-Exports in Meshes + * src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for HorizontalProfiles Mesh. + * src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_feed.xml: + BugFix: Changed missspelled Input-Name + +2009-11-09 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (TIMESERIES_ODV_PROFILE_NAMES): + Changed the Order of Columnlookup for ODV-Exports and added column "Depth" to the Export + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testTimeSeriesMeshArtifact): + Added the ODV-Export to the Unit-Testcase for TimeSeries-Mesh. + Some Refactoring Work done. + * doc/conf/queries.properties: + Added Query for VerticalProfile ODV-Exports in Meshes + * doc/conf/products/verticalprofile/conf_mesh.xml: + Added QueryID for ODV-Exports to the Configuration of an + Mesh-VerticalProfile-Artifacts + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_out_odv.xml, + src/test/ressources/verticalprofile/verticalprofile_step_06_out_odv.xml: + Added Out-Request for ODV-Export to the JUnitTest Configuration for VerticalProfiles. + +2009-11-09 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testTimeSeriesMeshArtifact): + Added the ODV-Export to the Unit-Testcase for TimeSeries-Mesh. + Some Refactoring Work done. + + * src/test/ressources/timeseries_mesh/timeseries_step_08_out_odv.xml: + Added Out-request for ODV-Export to the JUnitTest Configuration for TimeSeries Mesh. + + * doc/conf/products/timeseries/conf_mesh.xml: + Added QueryID for ODV-Exports to the Configuration of an Mesh-TimeSeries-Artifacts + + * doc/conf/queries.properties: Added Query for TimeSeries ODV-Exports in Meshes + +2009-11-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/Export.java + src/main/java/de/intevation/gnv/exports/DefaultProfile.java + src/main/java/de/intevation/gnv/exports/DefaultExport.java: Added the + possibility to print column labels in the first line of an export. + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Adjusted instantiation of the DefaultExport object and added column labels + for odv export. + +2009-11-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java: + Implemented a DataCollector for Odv exports. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + OEV-export uses a SimpleOdvDataCollector to collect export data. + +2009-11-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java, + src/main/java/de/intevation/gnv/exports/HorizontalProfileDataCollector.java: + Renamed HorizontalProfileDataCollector into ShapeDataCollector, because it + will be used by other transitions as well. + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java: + Adjusted class name of DataCollector after renaming. + +2009-11-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/HorizontalProfileDataCollector.java: + Special DataCollector for fetching data used for horizontal profile + exports. + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java: + Uses the an exporter for csv export. + +2009-11-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/DefaultDataCollector.java: + Implemented a DataCollector to collect all data used to create exports. + DefaultCollector fetches data with help of its headers. For special + exports, where a header returns more than one value, special + DataCollectors needs to be implemented (overwritung the 'getData' method). + + * src/main/java/de/intevation/gnv/exports/DefaultProfile.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java: Export now + uses a DataCollector to get the data. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Adjusted exports of csv export. + +2009-11-09 Tim Englich + + * doc/conf/queries.properties: + Added SQLStatemenet for ODV-Data for VerticalProfiles + on TimeSeriesPoints. + * doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Added QueryID for ODV-Data-Query + +2009-11-09 Tim Englich + + * src/test/ressources/timeseries/timeseries_step_06_out_*.xml: + Added the missing out-Modes to the Testcase and rename it to + the common used way in this TestCases. + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testTimeSeriesArtifact): + Added the ODV-Export to the Unit-Testcase. + Some Refactoring Work done. + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out): + The Method for generating ODV-Export now reads its Data from + the special Method which delivers the adapted Data. + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (generateFilterValuesFromInputData): + Extracted the Generation of the FilterValues for the geo-backend + to use it in several methods. + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java (getODVResult): + Added Method for getting the rquired Data for ODV-Exports + * doc/conf/products/timeseries/conf_timeseriespoint.xml: + Added separat QueryID Lookup for ODV-Data-Queryies + * doc/conf/queries.properties: + DB-Queries for ODV-Support TimeSeries on TimeSeriesPoints added. + +2009-11-06 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/exports, + src/main/java/de/intevation/gnv/exports/Export.java, + src/main/java/de/intevation/gnv/exports/DefaultProfile.java, + src/main/java/de/intevation/gnv/exports/DefaultExport.java: Implemented an + Exporter for odv and csv exports. Each exports just needs a Profile, which + describes the output. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Added an exemplary export for CSV and ODV formats of + TimeSeriesOutputTransition. + + TODO: ODV exporter exports the same data as CSV exporter does. This needs + to be adapted. + +2009-11-06 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java: + Added and moved Workflowsteps because of changes in the Workflow of these Artifacts. + Now the Region-Filter is added to the Workflow an can be tested using + this UnitTestCases. + + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_*.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_*.xml, + src/test/ressources/timeseries/timeseries_step_*.xml, + src/test/ressources/timeseries_mesh/timeseries_step_*.xml, + src/test/ressources/verticalprofile/verticalprofile_step_*.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_*.xml: + Added and moved Files because of changes in the Workflow of these Artifacts. + Now the Region-Filter is added to the Workflow an can be tested using + the UnitTestCases. + +2009-11-06 Ingo Weinzierl + + * doc/conf/products/horizontalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml, + doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: Added odv + as output format. + +2009-11-06 Tim Englich + + * src/main/java/de/intevation/gnv/chart/ChartFactory.java (calculateMaxGap): + Bugfix Gap-Calculation moved maxGap into negative Valies because of + overflow of Long-Variable. + +2009-11-05 Tim Englich + + * doc/conf/queries.properties: + Query to select only those TimeSeriesPoints + which are within an Region + + * doc/conf/products/timeseries/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml: + Added the RegionFilters into the configuration of the Products + for TimeSeriesPoints. + +2009-11-05 Tim Englich + + * doc/conf/queries.properties: + Added new Queries to fill the Lists for the + Regionfilters and one Query to select only those Meshes + which are within an Region. + + * doc/conf/products/verticalprofile/conf_mesh.xml, + doc/conf/products/verticalcrosssection/conf_mesh.xml, + doc/conf/products/timeseries/conf_mesh.xml, + doc/conf/products/horizontalprofile/conf_mesh.xml, + doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Added the RegionFilters into the configuration of the Products + for Meshes. + +2009-11-05 Tim Englich + + * src/test/ressources/*_describe.xml: + Added the DescribeRequestBodies to each TestCaseData. + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java: + Added the DescribeRequestBody to Describe-Calls in the Test + * src/main/java/de/intevation/gnv/transition/TransitionBase.java: + Added the possibility to switch to an alternative Transition if no value was choosen. + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid): + Added that the Inputvalue is valid if it fullfills the confitions of "no value choosen" (n/n) + + * src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java (calculateXOrdinateValue): + Added Dummyvalue for X-OrdinateValue + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java (describe), + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (describe), + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (createDescibeOutput): + Added the possibility to exclude the UI from the DescribeRequest. + +2009-11-03 Tim Englich + + * src/main/java/de/intevation/gnv/chart/ChartFactory.java (getTimeGapValue): + Integrated special case for TimeGaps in Meshes. There is no Gap defined in + Meshes so we have to use Long.MAXVALE to define a Gap for a Mesh which value + canno be reached. + +2009-11-02 Tim Englich + + * src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java + (createCSV): Code Cleanup: Removed obsoled TODO Flag + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (setSelection): + Changed the Value of the min and maxvalue of the Request to the Value which is unsed to name + the Inputfields in the DescribeOutput. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java, + src/main/java/de/intevation/gnv/transition/Transition.java, + src/main/java/de/intevation/gnv/transition/SingleInputTransition.java, + src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java, + src/main/java/de/intevation/gnv/transition/MinMaxTransition.java, + src/main/java/de/intevation/gnv/transition/DefaultTransition.java, + src/main/java/de/intevation/gnv/transition/CoordinateSelectionTransition.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (advance), + CodeCleanup: Removed needless Method validate from Transition, + because it had always returned true + +2009-10-30 Tim Englich + + * src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_*.xml: + Added the Testdata for the Unittest for HorizontalCrossSectionMeshArtifacts. + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalCrossSectionMeshArtifact): + Added the UnitTest-Case for HorizontalCrossSectionMeshArtifacts + +2009-10-30 Tim Englich + + * doc/conf/queries.properties: + Added the Query for selecting the Data for generating Outputs of + HorizontalCrossSectionMeshOutputTransition + * doc/conf/products/horizontalcrosssection/conf_mesh.xml: + Added the configuration for the HorizontalCrossSectionMeshOutputTransition + * src/main/java/de/intevation/gnv/transition/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputTransition.java: + Added the OutputTransition for generating /HorizontalCrossSections. + * src/main/java/de/intevation/gnv/statistics/HorizontalCrossSectionStatistics.java: + The Class for generating the Statistics to HorizontalCrossSections + * src/main/java/de/intevation/gnv/chart/HorizontalCrossSectionChartFactory.java: + The Class Stub for generating HorizontalCrossSections Charts. + +2009-10-29 Tim Englich + + Issue 45: Defining gaps for spatial and temporal gaps + + * doc/conf/products/timeseries/timegap_definition.xml, + doc/conf/products/timeseries/conf_timeseriespoint.xml: + Added the Configuration for TimeGaps to the TimeSeries-Configurations. issue45 + + * doc/conf/queries.properties: + Added TimeGapIp to the Queries for the Resultdata of TimeSeriesArtifacts. issue45 + + * src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java, + src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (setup): + src/main/java/de/intevation/gnv/chart/ChartFactory.java (calculateMaxGap): + Added configurable TimeGap Support to the TimeSeries-Chart-Generation. issue45 + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java (readConfiguration): + Moved Method from GNVArtifactBase to make it assesible for more Objects. issue45 + +2009-10-28 Tim Englich + + * src/main/java/de/intevation/gnv/profile/horizontalcrosssection/ + HorizontalCrossSectionMeshArtifact.java (HorizontalCrossSectionMeshArtifact), + doc/conf/queries.properties, doc/conf/conf.xml, + doc/conf/products/horizontalcrosssection/conf_mesh.xml, + src/main/resources/lang/artifactMessages* .properties: + Added Workflow for determining the Query-Parameters for Horizontal cross-sections. + +2009-10-28 Tim Englich + + * doc/conf/conf.xml: + Added Configuration for two new FIS. Current Meter and Ice Station Reports + + * src/main/resources/lang/artifactMessages*.properties: + Added Ressources for two new FIS. Current Meter and Ice Station Reports + +2009-10-27 Tim Englich + + * doc/conf/conf.xml: + Added Configuration for two new FIS. Sea State and SEACAT + + * src/main/resources/lang/artifactMessages*.properties: + Added Ressources for two new FIS. Sea State and SEACAT + +2009-10-27 Tim Englich + + Issue 61: Vertical profile (Meshes): Selection of minimal and maximal + depths zones + + * src/main/resources/lang/artifactMessages*.properties: + Added Ressources for the minimal and maximal Layer to use in VerticalProfiles of Meshes issue61 + + * doc/conf/products/verticalprofile/conf_mesh.xml: + Added two new Transitions for selecting the min and max-Layer to use. issue61 + + * doc/conf/queries.properties: + Added Queries for Selecting the Depth for selecting the minimum and the maximum Layer to use + Drawing the Chart. issue61 + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalProfileMeshArtifact): + Integrated two further Transitions-Steps according to changes in Workflow of + VerticalProfiles in Meshes. issue61 + + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_*.xml: + New Testdata generated according to changes in Workflow of VerticalProfiles in Meshes. issue61 + +2009-10-26 Tim Englich + + Issue 31: TG_0020.018: Input of manual depth zones + + * src/main/resources/lang/artifactMessages_de_DE.properties: + Added Ressources for the minimal and maximal value of the depth + + * src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_statistics.xml (renamed), + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_csv.xml (renamed), + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_chart.xml(renamed), + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_feed.xml, + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_advance.xml, + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_05_out_statistics.xml(renamed), + src/test/ressources/verticalprofile/verticalprofile_step_05_out_csv.xml(renamed), + src/test/ressources/verticalprofile/verticalprofile_step_05_out_chart.xml(renamed), + src/test/ressources/verticalprofile/verticalprofile_step_05_feed.xml, + src/test/ressources/verticalprofile/verticalprofile_step_04_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_03_advance.xml, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java: + Edited the RestCases for VerticalProfiles according to the requirement that + the user should be able to enter the minimal and maximal Value of the depth that + should be show n in the charts. issue31 + + * doc/conf/queries.properties, + doc/conf/products/verticalprofile/conf_timeseriespoint.xml, + doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: + Adding required Configuration-Parts to get the possible to enter the minmum + and maximum depth value that should be shown in the charts. issue31 + +2009-10-23 Tim Englich + + * src/test/ressources/timeseries_mesh/timeseries_step_07_feed.xml: + The Timeperiod of the Modeldata has changed. so it was nessessarry to change + the Unittest to get propper Results + +2009-10-23 Tim Englich + + * doc/conf/queries.properties: + Some Queryimproofments done. Inner-Selects has been removed where it was possible. + +2009-10-23 Tim Englich + + Issue 3: Artifact: Storing the internal state instead of results + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java (describe), + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java (describe): + Use super.identifier as uuid. issue3 + +2009-10-23 Tim Englich + + * src/test/ressources/verticalprofile/verticalprofile_step_04_feed.xml, + src/test/ressources/verticalprofile/verticalprofile_step_03_advance.xml, + src/test/ressources/verticalprofile/verticalprofile_step_04_out_*.xml, + src/test/ressources/timeseries_mesh/timeseries_step_07_out_*.xml, + src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_out_*.xml: + Changed the uuid because the new Storage shows that there were different ones in one Testcase + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Put the UUID into the Resultlookup + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java: + Removed the Storage of Results in the Object and put them into the ehcache + + * src/main/java/de/intevation/gnv/transition/Transition.java: + Removed some needless Methods that were not longer Required + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java + (advance), src/main/java/de/intevation/gnv/transition/SingleInputTransition.java + (purifyResult), src/main/java/de/intevation/gnv/transition/MinMaxTransition.java + (purifyResult), src/main/java/de/intevation/gnv/transition/CoordinateSelectionTransition.java + (extractKVP), src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java + (describe), src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java + (describe), src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java + (describe), src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java + (describe), src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (uuid): + Lookup the Results from ehcache and centralize the Lookup to one methode. + +2009-10-23 Tim Englich + + * doc/conf/queries.properties: + Optimized Query horizontalprofile_instantaneouspoint_cruise because it is not warranted + that the name of an cruise is set. issue60 + +2009-10-22 Tim Englich + + * src/main/java/de/intevation/gnv/transition/CoordinateSelectionTransition.java + (extractKVP): Added the possiblility to fetch an further Column with + the alias Value to display it together with the Coordinatevalues + + * doc/conf/queries.properties: + Added the Coordinates to an Measuementpoint to display it. + + * doc/conf/products/verticalprofile/conf_instantaneouspoint.xml: + Change TransitionType for displaying Coordinatevalues aditionaly to + the Time of an Measurement + +2009-10-22 Tim Englich + + Issue 40: Instantiation of artifacts slow + + * doc/conf/conf.xml, doc/conf/products/*/conf_*.xml: + Split the Configuration of the ArtifactDatabase in several Configurationfiles. + For Each Product-Artifact one single File to make it easier to administer the System. + + * src/main/java/de/intevation/gnv/transition/TransitionFactory.java (createTransition), + src/main/java/de/intevation/gnv/transition/TransitionBase.java (setup), + src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java (setup), + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (setup): + Lookup of XML-Attributes was changed from XPath-lookup to direct + Access on the fetched Element to speed up the Artifactinstantiation issue40 + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (getConfigurationFragment): + Read Configuration information for the Productartifact from a separat folder if an xlink:href + Attribute exists in tne Configurationnode of the Artifact. + This was inserted to speed up the Artifactinstantiation and to split the Configuration + in several Configurationfiles that where smallaer issue40 + Also the lookup of XML-Attributes was changed from XPath-lookup to direct + Access on the fetched Element + +2009-10-21 Tim Englich + + Issue 59: Added relative pathnames to central config document + + * doc/conf/conf.xml: + Added relative locations for further required configurationfiles . issue59 + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java (createArtifactContext): + Added the prossibility to configure the location of required configurationfiles not absolute. issue59 + +2009-10-21 Tim Englich + + * doc/conf/arcsdeconnectionpool.properties: + Added separat ConnectionPoolProperties to this Project. + * doc/conf/*: + Moved ConfigurationFiles from src/test/ressources to doc/conf + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (configurationDir): + Changed Configuration Folder to doc/conf + +2009-10-20 Tim Englich + + * doc/conf: + Added Folder for the Configuration of the gnv-artifacts. + +2009-10-20 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalCrossSectionMeshArtifact): + Added Testcase for testing the Workflow for generating VerticalCrossSections. + * src/test/ressources/queries.properties: + Added the required Queries for providing VerticalCrossSection using Meshes. + * src/test/ressources/conf.xml: + Added the Configuration for an VerticalCrossSection using Meshes. + * src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_*.xml: + Adding Requestdocuments for testing the Workflow of Generating an VerticalCrossSection. + * src/main/java/de/intevation/gnv/transition/profile/verticalcrosssection/VerticalCrossSectionOutputTransition.java : + Added an OutputTransition for renedering the Data of VerticalCrossSections. + * src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java: + Added Class for the Representation of VerticalCrossSection Artifacts into the Project. + * src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChartFactory.java (createProfileChart): + Put Class-Sub for the Chart generation of VerticalCrossSections into the Project. + +2009-10-20 Tim Englich + + Issue 54: Errors in diagramms for time series in IMIS + + * src/test/ressources/queries.properties: + Bugfix for TIMESERIESPOINT the first and the last value weren't used + in the Query which was integrated from the Prototyp to the Project + ussue54 + +2009-10-19 Tim Englich + + Issue 55: Harmoization of coordinate values for input fields + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe): + Added uniform Visualization of Single Input-Elements to MinMax-Elements. issue55 + +2009-10-19 Tim Englich + + Issue 56: Error - Behavior of a form without constraint values + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (feed): + Catch Exception that the Calling Program could not put no InputData + into the feed Request.issue56 + +2009-10-19 Tim Englich + + Issue 19: Validation of date and double values + + * src/main/java/de/intevation/gnv/chart/ChartFactory.java (createDataset), + src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java (createDataset): + Adding empty Series into Chart to prevent NPE issue 19 + +2009-10-19 Tim Englich + + Issue 35: Wrong date values force the panel to start from beginning + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (putInputData): + Correct misspelled Exception-Message as an Result of fixing issue35 + +2009-10-19 Tim Englich + + Issue 50: Adding the layer number for depth information + + * src/test/ressources/queries.properties: + Changed the Value of Layer and Depth range visualization of Meshes + according to issue50 + +2009-10-19 Tim Englich + + Issue 47: Translation of strings for time series + + * src/main/resources/lang/artifactMessages*.properties: + Changed the displayed-Values as defined in issue47 + * src/test/ressources/conf.xml: + Changed the Key for the DataName of MIN-Max-Transitions to put a propper Name + into the UI-Describeoutput issue47 + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe): + Added the X-Forms-Group-Element to surround the MinMaxDescibeObject-output to Give the + Group of Objects a propper Name issue47 + * src/main/java/de/intevation/gnv/transition/MinMaxTransition.java (purifyResult): + Added the name of the Data to the MinMaxDescibeObject to put it into the UI-output + +2009-10-16 Tim Englich + + Issue 53: Changing of strings in parameter panel + + * src/test/ressources/timeseries_mesh/timeseries_step_05_feed.xml: + src/test/ressources/conf.xml: + src/main/resources/lang/artifactMessages*.properties: + Conformation to the tanslation of the MeshObjects issue53 + +2009-10-16 Tim Englich + + Issue 49: Integration of FIS to Meshes + + * src/test/ressources/queries.properties: + There are different FIS in the Relation Median.Mesh so it is + nessessary to sepcify which FIS should be selected by using the sourceid + issue49 + * src/test/ressources/conf.xml: + Adding two further FIS to the Configuration which are based on Meshes. + Added the Sourceid to the ModelData issue49 + * src/main/resources/lang/artifactMessages*.properties: + Adding the Names of the two new FIS to the Propertiesfiles issue49 + +2009-10-16 Tim Englich + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java (createXYSeries): + Adding 5% bigger Valuearea to the Chart according to GT0030.011 + +2009-10-16 Tim Englich + + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java (VerticalProfileOutputTransition): + Changed Domainlable for Verticalprofiles according to the Specification GT_0030.005 + * src/test/java/de/intevation/gnv/artifacts/util/DistanceCalculatorTestCase.java (testDistanceCalculator): + Added Testcase for the DistanceCalculation + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java (createXYSeries): + * src/main/java/de/intevation/gnv/utils/DistanceCalculator.java (calculateDistance): + Added Calculation of the Distance in the unit km for Geodetic-Coordinates according to the Specification GT_0030.005 + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java (HorizontalProfileOutputTransition): + Changed Domainlable for Horizintalprofiles according to the Specification GT_0030.005 + +2009-10-16 Tim Englich + + * src/test/ressources/queries.properties: + The Levelnumber of Meshes will also be visualized in the choose of depth GT_0020.0020 + +2009-10-16 Tim Englich + + * src/test/ressources/conf.xml: + Added Coordinate-Values to Title of the TimeseriesDiagramm for Meshes + +2009-10-16 Tim Englich + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java (putInputData): + Bugfix ChartValues were not Recalculated after feed was called second Time. + +2009-10-16 Tim Englich + + * src/test/ressources/conf.xml: + Bugfix in MinMaxTransition the Maxvalue was not the correct Value. + +2009-10-16 Tim Englich + + Issue 38: Horizontal profiles: Visualization of distances in km + + * src/main/java/de/intevation/gnv/transition/CoordinateSelectionTransition.java (convert2DisplayCoordinate): + Added Transformation from WKT-Coordinate Reperesentation to BSH-Coordinate Representation. issue38 + +2009-10-15 Tim Englich + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java, + src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java, + src/test/ressources/queries.properties, src/test/ressources/conf.xml: + Added missing Class Description Values to the Horizontal Profile Charts + +2009-10-15 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (getFisName): + Added Method for lookup FIS Names + * src/main/resources/lang/artifactMessages*.properties: + Added further Key-Value-Pairs for FIS + * src/test/ressources/conf.xml: + Changed Configuratioon to get the ID of an FIS to the Chartgeneration + +2009-10-15 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileMeshPointArtifact): + Activate Tests for CSV and Statistics on HorizontalProfiles + + * + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java + (createCSV), + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java + (createCSV): + Integrated special CSV-Export for HorizontalProfiles + +2009-10-14 Tim Englich + + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java (createXYSeries): + Load WKT from ResultSet and calculate Distance to last point. + * src/test/ressources/queries.properties: + Switch Chart-Queries to Spatial-Queries. + +2009-10-13 Tim Englich + + Issue 33: Improved logging for time-interval queries + + * src/test/ressources/queries.properties, + src/test/ressources/conf.xml: + Added Parameter-Usage in Time-Interval-Query ISSUE-33 + +2009-10-13 Tim Englich + + * src/test/ressources/verticalprofile_mesh/verticalprofile_step_*_feed.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_*_feed.xml: + Switched to Szenario where it is possible to select Data using the Coordinate. + * src/test/ressources/conf.xml, + src/test/ressources/queries.properties: + Switched to SFS-Conformant-Queries in HorzintalProfile- and VerticalProfile-Mesh + +2009-10-13 Tim Englich + + * src/main/resources/lang/artifactMessages_*.properties: + Switched to better Description of an Coordinate-Input-Field + + * src/test/ressources/timeseries_mesh/timeseries_*_feed.xml: + Switched to Szenario where it is possible to select Data using the Coordinate. + + * src/test/ressources/queries.properties, src/test/ressources/conf.xml: + Switched to SFS-Conformant-Queries in Timeseries-Mesh + + * pom.xml: + Added dependency to JTS 1.9 + + * src/main/java/de/intevation/gnv/utils/exception/ValidationException.java + (ValidationException), src/main/java/de/intevation/gnv/utils/InputValidator.java + (getPointValue), src/main/java/de/intevation/gnv/transition/TransitionBase.java + (prepareInputData4RegionDBQuery): + Added the Support for specialized Handling of InputValues of type Coordinate. + + * src/main/java/de/intevation/gnv/transition/CoordinateSelectionTransition.java: + Added Transition for the Support of Coordinateinput handling. + +2009-10-12 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java: + Closed small file descriptor leak. + +2009-10-09 Tim Englich + + * src/main/java/de/intevation/gnv/**/*.java Edited: + Code Formatting and Cleanup. + +2009-10-09 Tim Englich + + * src/test/ressources/queries.properties Edited: + Add Parameters to the Queries to select only the Dates where + the Parameters has been measured. + * src/test/ressources/conf.xml Edited: + Set that the ParameterIds should be used in the Query of the Dates. + +2009-10-07 Sascha L. Teichmann + + RELEASE 0.1 + + * Changes, NEWS: Summarized changes. + +2009-10-06 Tim Englich + + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java (HorizontalProfileOutputTransition) Edited : + Switch Lable-Value for Domain-Axis. + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java (getRessource) Edited: + Added missing Import + * src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java (advance) Edited: + Added i18n Support + * src/main/resources/lang/artifactMessages*.properties Edited: + Added some missing RessourceValues + +2009-10-06 Sascha L. Teichmann + + * src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_out_csv.xml, + src/test/ressources/conf.xml, + src/test/ressources/timeseries_mesh/timeseries_step_07_out_csv.xml, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_06_out_csv.xml, + src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_08_out_csv.xml, + src/test/ressources/verticalprofile/verticalprofile_step_04_out_csv.xml: + s@test/plain@text/plain@g to correct MIME type of CSV export + +2009-10-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/ressource/*.properties: + Deleted. + + * src/main/resources/lang/*.properties: Re-inserted here. Maven now + includes them in the jar package. + + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java: + Make code more robust. TODO: We need a better implementation here. + + * Changelog -> ChangeLog: To make eclipse happy. Unified changelog style. + + * pom.xml: xmllint-ed and set encoding of filtered resources to UTF-8 + +2009-10-06 Tim Englich + + * src/test/ressources/queries.properties Edited: + Bugfix in Query for getting Data for the Output. + Now the Values will be sorted Correcly. Timevalue + has been removed from the Query because it is not a + Parameter which could be choosen from the User. + Also dummies for XCOORD-Value and YCOORD-Value integrated so + that is now Possible to visualize the Profile + gnv/issue21 + +2009-10-05 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/ressource/artifactMessages*.properties Edited: + Added further Ressourec Values. + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalProfileInstantaneousPointArtifact) Edited: + Changed ArtifactName to real FIS. + * src/test/ressources/timeseries_mesh/timeseries_step_01_feed.xml Edited: + Changed Product-Name from timeSeriesMesh to timeSeries to provide a General-Naming-Structure + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (setup) Edited, + src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java Edited, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java Edited: + Added Configurationsupport for the Labeling Data. Now it is possible do define the + value-names in the Configurationfile. + * src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_feed.xml Edited, + src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_02_feed.xml Edited, + src/test/ressources/queries.properties Edited: + Changed the Queries for the VerticalProfileInstantaneusPoint to the FIS-Query Mode. + This Mode was send by Mr. Schulz-Ohlberg. + * src/test/ressources/conf.xml: + Changed the Workflow for the VerticalProfileInstantaneusPoint to the FIS-Query Mode. + This Mode was send by Mr. Schulz-Ohlberg. + Also Added the support for value-names to the Configuration of VerticalProfileInstantaneusPoint. + +2009-10-05 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/ressource/artifactMessages_en.properties Renamed: + Renamed from artifactMessages_en_EN.properties to artifactMessages_en.properties to get a + propper support for PreferedLocale + * src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java (getRessource) Edited, + * src/test/java/de/intevation/gnv/artifacts/ressource/RessourceFactoryTestCase.java (setUp) Edited, + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe) Edited, + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (createSelectBox) Edited: + Changed Method Signature from Locale to PreferedLocale[] to put all Useable Languages to + the RessourceFactory + +2009-10-02 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/ressource/RessourceFactoryTestCase.java Added: + TestCase for Testing the RessourceFactory + + * src/main/java/de/intevation/gnv/artifacts/ressource/artifactMessages*.properties Added, + src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java Added: + Added Factory and Propertiesfiles for getting the localized Values + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Edited, + src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java Edited, + src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited, + src/main/java/de/intevation/gnv/transition/Transition.java Edited, + src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java Edited, + src/main/java/de/intevation/gnv/transition/OutputTransition.java Edited, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Edited, + src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java Edited, + src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java Edited, + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Edited, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + LanguageSupport Integrated + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (createCallContext) Edited: + Extracted Method and Put CallMeta with Language German to the CallContext. Otherwise + TestCase will produce NPEs. + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java Edited: + Added Real CallMeta to the Method for usage in Artifacts. Otherwise + TestCase will produce NPEs. + * src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_feed.xml Edited, + src/test/ressources/timeseries_mesh/timeseries_step_02_feed.xml Edited, + src/test/ressources/verticalprofile_mesh/verticalprofile_step_02_feed.xml Edited, + src/test/ressources/conf.xml Edited: + Changed som Identifiers for Localisation. + +2009-10-02 Tim Englich + + * src/test/ressources/conf.xml Edited: + Added the Configuration of the Horizontal-Profile.Mesh. + Also Edited the Workflowq for HorizontalProfile-Instantaneouspoint and + Put three n ew FIS into the Configuration which represents HorizontalProfile-Instantaneouspoint. + * src/test/ressources/horizontalProfile_instantaneouspoint/*.xml Edited, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileInstantaneousPointArtifact) Edited: + Edited the Workflowlogic given by new Specification of the BSH. + * src/test/ressources/horizontalProfile_mesh/*.xml Added: + The Request for do an Workflow for an HorizontalProfile-Mesh + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileMeshPointArtifact) Edited: + Added TestCase for HorizontalProfiles of Type Mesh. + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java (getMeta) Edited: + Added new Method which is defined in the implemented Interface. + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid) Edited: + Added the Validation of InputValues from Type AttributeName which should represent + an QueryValue of Type String which must not put into "'". + * src/main/java/de/intevation/gnv/transition/profile/horizontal/NorthSouthEastWestTransition.java Added: + Transition to provide the possibility of choosing the axis of an Grid that should be used. + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (dataMultiSelect) Edited: + Changed from private to protected so that this mMeber could be accessed by within extending Classes. + * src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshArtifact.java Added: + Class for the Representation of Horizontal Profiles for the Type Mesh. + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java (HorizontalProfileChartFactory) Edited: + Changed PlotOrientation so that the Profile is displayed correctly. + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (advance) Edited: + Added Log-Message for better Workflowanalyzis. + +2009-10-01 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/utils/ArtifactFactoryUtilities.java, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java, + src/main/java/de/intevation/gnv/transition/MinMaxTransition.java, + src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java, + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java: + Removed needless imports. + + * src/main/java/de/intevation/gnv/utils/InputValidator.java: + Import org.apache.commons.validator.GenericValidator instead of + absolute usage in methods. + +2009-09-30 Tim Englich + + * src/test/ressources/queries.properties Edited: + Added the Queries for HorizontalProfiles of InstantaneousPoints. + * src/test/ressources/conf.xml Edited: + Added the Configuration for HorizontalProfilArtifact for InstantaneousPoints + * src/test/ressources/horizontalProfile_instantaneouspoint/*.xml Added: + Added XML-Requests for the TestCase of HorizontalProfiles of InstantaneousPoints. + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testHorizontalProfileInstantaneousPointArtifact) Edited: + Added TestCase for HorizontalProfiles of InstantaneousPoints. + +2009-09-30 Tim Englich + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid) Edited: + Added the Validation for Double-Values. + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java (createChart) Edited: + The Name of the Method for generaing Charts has changed. + * src/main/java/de/intevation/gnv/transition/profile/horizontal/HorizontalProfileOutputTransition.java Added: + New outputTransition for HorizontalProfiles + * src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java Added: + Class which calculates the Statistics for Horizontal Profiles. + * src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileInstantaneousPointArtifact.java Added, + * src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java Added: + Classes which represents HorizontalProfileArtifacts + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java (plotOrientation) Edited: + Added Member for the representation of the Plotorientation to overwrite it in + extende Classes + Rename Method for generatim the Charts in a common Name. + * src/main/java/de/intevation/gnv/chart/HorizontalProfileChartFactory.java Added: + Class for drawing Horzontal Profiles + +2009-09-30 Sascha L. Teichmann + + * src/test/ressources/conf.xml: s@test/xml@text/xml@g + +2009-09-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (doNextStep) Edited: + Add Responsevalidation for feed-Requests. + * pom.xml Edited: + Add required Library ORO to the Dependencies which is required by Commons-Validator + to do matchRegexp Requests. + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid) Edited: + Add a Validator for the type Point + * src/test/ressources/conf.xml Edited: + Changed mesh_coordinate from type Integer to type Point + +2009-09-29 Tim Englich + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java (findValueTitle): + Key of KeyValueDescribeData is a String. So it is not nessessary to parse the + id into an Integer Value. + Also some NP-Access removed. + +2009-09-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited: + Some Coderedundances refactored. + +2009-09-29 Tim Englich + + * src/test/ressources/queries.properties Edited: + Bug fixed: Mesh TimeSeries will now Handle Charts with multiple Depth-Values properly. + +2009-09-29 Tim Englich + + * src/test/ressources/timeseries_mesh/*.xml Added : + TestCaseRequests for Timeseries FIS Mesh + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testTimeSeriesMeshArtifact) Edited: + Add Testcase for Timeseries Mesh + +2009-09-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (check4ExceptionReport) edited: + ExceptionTest for Responsdocuments added. + UnitTest will now fail if the Artifact delivers an ExceptionReport using the advance Request. + +2009-09-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalProfileMeshArtifact) Edited: + Added TestCase for Vertical Profiles for Mesh + * src/test/ressources/verticalprofile_mesh/*.xml Added: + TestCaseRequests for VerticalProfile FIS Mesh + +2009-09-29 Tim Englich + + * src/main/java/de/intevation/gnv/utils/InputValidator.java (isInputValid) Edited: + Bugfix: Remove leading- and trailingwhitspaces from Date- and Integervalues + +2009-09-29 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testVerticalProfileArtifact): + (testVerticalProfileInstantaneousPointArtifact) Edited: + Added Testcases for VerticalProfile and VerticalProfile Instantaneouspoint + * src/test/ressources/verticalprofile_instantaneouspoint/*.xml Added: + TestCaseRequests for VerticalProfile Instantaneouspoint + * src/test/ressources/verticalprofile/*.xml Added: + TestCaseRequests for VerticalProfile FIS Marnet + +2009-09-29 Tim Englich + + * src/test/ressources/queries.properties Edited: + Remove to_date from TimeSeries-Quueries becaus of Changes in the conf.xml-File + * src/test/ressources/conf.xml Edited: + Correct Types for min- and max-Values from Integer to Date + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java (testTimeSeriesArtifact) Edited: + Add CallContext to the Tests. + * src/test/java/de/intevation/gnv/artifacts/TestCallContext.java Add: + A CallContext used only in Junit-Tests + +2009-09-29 Tim Englich + + * pom.xml Edited: + Added the dependency to Apache-Commons-Validator Version 1.3.1 which is + used for the InputValoue-validation. + * src/main/java/de/intevation/gnv/utils/InputValidator.java Added : + An InputValidator for Validating InputValues. + At this Moment only Integer, String and Date is supported. + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (putInputData) Edited: + Add the InputValidator to validate the incomming Values from the Clients. + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/chart/ChartFactory.java (createTimeSeries) Edited: + Performanceimprovement: The Loop will be interrupted if the Pointer is bigger than the + last Pointer of the Value that must be visualised. + +2009-09-28 Tim Englich + + * pom.xml Edited: + Added the Dependeny to the ehcache-Library + * src/test/ressources/ehcache.xml Added: + The ehcache-Configuration. + * src/test/ressources/conf.xml Edited: + Added the Link to the ehcache-Configuration. + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java (createArtifactContext) Edited: + Added the Initialisation of the CacheManager. + + * src/main/java/de/intevation/gnv/artifacts/cache/CacheFactory.java Added: + An Fractoryimplementation for the central access to the Cache. + + * src/main/java/de/intevation/gnv/transition/MinMaxTransition.java (purifyResult) Edited, + * src/main/java/de/intevation/gnv/transition/SingleInputTransition.java (purifyResult) Edited, + * src/main/java/de/intevation/gnv/transition/Transition.java Edited, + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited, + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Signature of Methods purifyResults, advanced and feed Changed to put the uuid to the Transition + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java (createChart) Edited: + Methodsignatur of getChartResult change for putting the uuid of an Artifact into it + * src/main/java/de/intevation/gnv/transition/OutputTransition.java (out) Edited, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out) Edited: + Method Signature Changed for putting the uuid of an Artifact to the Transition. + stored + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java Edited: + removed the persitence of the Chartresults and put them into an Cache instance. + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (getStatisticsGenerator) Edited: + Extracted the Instantiation of the Statistics-object to an protected Methode + to make it possible that extending Classes could change it. + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java (getStatisticsGenerator) Edited: + Overwrite getStatisticsGenerator to instantiate the VerticalProfileStatistics- + * src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java Added: + Class for Calculating Statistics for VerticalProfiles- The Only thing whisch differs to + TimeSeriesStatists is that the XoordinateValue is an double and not an Date-Value + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java (calculateXOrdinateValue) Edited: + Added the Methode calculateXOrdinateValue to this Class to switch is Values in extending Classes. + * src/main/java/de/intevation/gnv/statistics/Statistics.java (calculateStatistics) Edited: + Added methodsignature to Interface for usage in different Implementations of Statistics. + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java (calculateStatistics) Edited: + Bug fixed. Now all Values will be used to calculate the Statistics + +2009-09-28 Tim Englich + + * src/test/ressources/conf.xml Edited : + Changed the Output-format of Statistics from text/plain to text/xml. + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java Edited: + Moved the calculating-Methods from the Conmstructor to an separat Method. + Switched the ResultContainer from Array to Collection + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out) Edited: + Added the Output-Variante for generating Statistics + +2009-09-28 Tim Englich + + * pom.xml Edited: + Added Link to Apache-Commons-Math to get the required Classes for the calculation + of Statistics. + * src/main/java/de/intevation/gnv/statistics/exception/StatisticsException.java Added: + Specified ExceptionClass for the Statistics Part of the gnv-artifacts + * src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java Edited: + Remove compileErrors and switch to new Datastructure + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/statistics/Statistic.java Added , + src/main/java/de/intevation/gnv/statistics/Statistics.java Added , + src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java Added: + Imported Statistics-Classes from old Project. Revision: 3101 Does not compile + +2009-09-25 Tim Englich + + * src/test/ressources/conf.xml Edited: + Added with and height Inputparameter to each Chart-OutputMode. + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out) Edited: + Added the usage of the Parameters revieved from the client for the ChartRendering + + * src/main/java/de/intevation/gnv/transition/DefaultInputValue.java (DefaultInputValue) (getDefaultValue) Edited , + src/main/java/de/intevation/gnv/transition/InputValue.java (getDefaultValue) Edited: + Added the Method getDefaultValue to the Interface for getting the + deafultvalue of an Parameter. + + * src/main/java/de/intevation/gnv/transition/DefaultOutputMode.java Edited, + src/main/java/de/intevation/gnv/transition/OutputMode.java (getInputParameters) Edited: + Added the Method getInputParameters to the OutputMode for Handling the required Parameters + of an OutputMode. + + * src/main/java/de/intevation/gnv/transition/OutputTransition.java (out) Edited: + Put the InputParameter recived from the Client to the Methodsignature so that + they can be used during the outputprocessing. + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java Edited: + Read rquired Outputparameters from the Configuration + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Added support for Parameters in OutputNode of Describe-Artifact + +2009-09-24 Tim Englich + + * pom.xml Edited: + Added Library for CSV-Support + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (out) Edited: + Add support for CSV-Export + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (out) Edited: + Add Fag on Context for storing the Artifact status after out. + +2009-09-24 Tim Englich + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java (createSuccessReport) Edited: + Added a centraL Method for creating an Successreoprt. + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited, + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Edited: + Add ResultReporting to the different Metshods of an Artifact + +2009-09-24 Tim Englich + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java Edited: + Obsolet TODOs removed + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited, + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Edited, + src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited: + Create Exception Report added + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java (createExceptionReport) Edited: + Method for creating Exceptionreports added. + +2009-09-24 Tim Englich + + * src/test/ressources/queries.properties Edited: + Queries formatted so that they can be analysed and extended easier. + Some Bugs removed + +2009-09-24 Tim Englich + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java Edited, + src/main/java/de/intevation/gnv/chart/ChartLabels.java Edited, + src/main/java/de/intevation/gnv/chart/ChartFactory.java Edited: + Removed obsolet Parameters an Methods. + Use the ChartLable to put the DomainAxisLable into the Chart. + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java Edited: + Some more Loggingoutput integrated. + Some Performanceimprovements done. The ResultData will only be refreshed if + the InputValues has changed. + Some Refactoring Work done. Move some Members into from extending Classes + into this implementation. + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java Edited, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Edited: + Dummywerte fuer Diagrammgenerierung durch Echtwerte ersetzt. + Obsolete Uebergabeparameter entfernt. + +2009-09-23 Tim Englich + + * src/test/ressources/queries.properties Edited: + Statements for InstantaneousPoint Vertical Profiles added + * src/test/ressources/conf.xml Edited: + Configuration for Vertikal Profiles for InstantaneousPoints added + * src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileInstantaneousPointArtifact.java (VerticalProfileInstantaneousPointArtifact) Added: + New Artifact-Class Reperesenting Artifacts for InstantaneousPoints Creating VerticalProfiles added. + +2009-09-23 Tim Englich + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (prepareInputData4DateDBQuery) Edited: + Bug Fixed, now all Inputvalues of String and Date will be put into the Query + +2009-09-23 Tim Englich + + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java (createXYSeries) Edited: + Bug fixed. Now all Values will be Renderd to the Chart + * src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileMeshArtifact.java Added: + Artifact-class for VerticalProfile Mesh added + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited: + Support for StringQuieries and OracleDateQueries added + * src/test/ressources/queries.properties Edited: + Queries for VerticalProfile Mesh integrated + * src/test/ressources/conf.xml Edited: + Artifact for VerticalProfile Mesh integrated + +2009-09-22 Tim Englich + + * src/test/ressources/queries.properties Edited: + Added Queries for the Workfloe of collecting the + required Information to generate a vertical Profile + * src/test/ressources/conf.xml Edited: + Added the Configuration of the VerticalProfileArtifact + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java (getCollection) Edited: + Some Codrefactoring done for reuse of Functionality in extended Classes. + * src/main/java/de/intevation/gnv/transition/profile/vertical/VerticalProfileOutputTransition.java Added: + Outputtransition for the Support of VerticalPropfiles + * src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java (getKey), + src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java (getKey) Edietd, + src/main/java/de/intevation/gnv/transition/TransitionBase.java (purifyResult) Edited: + Change KEY-Attribute of KeyValueDescribeData from Integer to String for the required + Representation of Date-KeyValue-Pairs + * src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java Added: + ArtifactClass for the representation of VerticalProfiles + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (createSelectBox) Edited: + Added support for selected Products in static UI. + * src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java Added: + Factory for producing VerticalCharts added. + * src/main/java/de/intevation/gnv/chart/ChartFactory.java Edited: + Names of Getter for Columns Changed. + +2009-09-21 Tim Englich + + * src/test/ressources/queries.properties Edited: + Queryie for TimeSeriesMesh added. + * src/test/ressources/conf.xml Edited: + New Artifact representing the TimeSeries-Mesh added to the Configuration. + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Edited: + Inputdata for the Chartgeneration will now be allocated by name and not by position in Transitionorder. + * src/main/java/de/intevation/gnv/transition/describedata/SingleValueDescribeData.java Added, + src/main/java/de/intevation/gnv/transition/describedata/DefaultSingleValueDescribeData.java Added, + src/main/java/de/intevation/gnv/transition/SingleInputTransition.java Added: + New Class for Representing a single Input Transition + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited: + Added support of usage inputValues none or multiple times in Queries. + Added support for SingleInputTransitions in Describe-Output + * src/main/java/de/intevation/gnv/transition/InputValue.java Edited, + src/main/java/de/intevation/gnv/transition/DefaultInputValue.java Edited: + An InputValue now is possible to use none or multiple times in Queries. + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesMeshArtifact.java Added: + ArtifactClass for the Representation of an Mesh-Timeseries-Artifact + +2009-09-17 Tim Englich + + * src/test/ressources/conf.xml Edited: + Database Cleanup Interval set to 5 minutes. + +2009-09-17 Tim Englich + * src/test/ressources/conf.xml Edited: + Some structurechanges done. + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Edited: + Fixed Bug supporting UTF-8 Documents properly. + * src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java Edited, + * src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java Edited, + Added Methods for setting and getting the selection-state of this objects. + + * src/main/java/de/intevation/gnv/transition/describedata/DefaultMinMaxDescribeData.java Edited, + src/main/java/de/intevation/gnv/transition/describedata/MinMaxDescribeData.java Edited: + Added setter for min an max-Values and getters an setters for minName and maxName + + * src/main/java/de/intevation/gnv/transition/describedata/NamedCollection.java Added, + src/main/java/de/intevation/gnv/transition/describedata/NamedArrayList.java Added: + Collection ans an Implementation of this Collection for Storing Name of the Collection and if + the Values in it are multiselectable. + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java : + Static UI-Support and valid SelectionStorage added. + I added also an imporvement of the multiselect Methods for Datasets + * src/main/java/de/intevation/gnv/transition/MinMaxTransition.java Edited: + Storage of changed Values added + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Edited: + Static UI Support Added + + +2009-09-16 Tim Englich + + * src/test/ressources/conf.xml Edited, + src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe) Edited, + src/main/java/de/intevation/gnv/transition/InputValue.java (isMultiselect) Edited, + src/main/java/de/intevation/gnv/transition/InputData.java (concartValue) Edited, + src/main/java/de/intevation/gnv/transition/DefaultInputValue.java (isMultiselect) Edited, + src/main/java/de/intevation/gnv/transition/DefaultInputData.java (concartValue)Edited, + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (createUserInterface) Edited, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (parseInputData) Edited: + Added Multiselectsupport for InputValues + +2009-09-16 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java (setup) Edited: + Bug Fixed because of Infrastructure Changes in the Artifact-Module + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited: + Put only the last DescribeData to the UI-Output bnecause auf Renderingproblems in the Client + + * src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java Edited, + src/main/java/de/intevation/gnv/transition/describedata/DefaultMinMaxDescribeData.java Edited, + src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java Edited: + Made Interface Serializable, add UIDs to the Implementations of the Interface + +2009-09-15 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java (createUserInterface) Edited: + Integrate UI-Representation for Describe into the FISArtifact. + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java (createXFormElement) Refactoring, + src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe) Refactoring: + Extract the Element-Creation of XForms Nodes into a Common Class to make them available for + other Classes which have to create XForm-Fragments + +2009-09-14 Tim Englich + + * src/main/java/de/intevation/gnv/transition/Transition.java Edited, + src/main/java/de/intevation/gnv/transition/InputData.java Edited, + src/main/java/de/intevation/gnv/transition/OutputMode.java Edited, + src/main/java/de/intevation/gnv/transition/InputValue.java Edited, + src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java Edited, + src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Edited, + src/main/java/de/intevation/gnv/transition/describedata/DescribeData.java Edited: + Make the Interfaces Serializable to make them usable in the Artifactdatabase + +2009-09-14 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited, + src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Edited, + src/main/java/de/intevation/gnv/transition/OutputTransition.java Edited , + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Edited, + src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Edited, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Refactoring Work depending on Infrastructurchanges in the Artifact-Module + +2009-09-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited, + src/test/ressources/timeseries/timeseries_step_01_feed.xml Edited, + src/test/ressources/timeseries/timeseries_step_01_advance.xml Edited, + src/test/ressources/conf.xml Edited: + TestCase moced from TimeSeriesArtifact to FISArtifact. Used FIS: Marnet + +2009-09-10 Tim Englich + + * src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Added: + Utilities-Class for some XML-Stuff that is only for gnv-artifacts + + * src/main/java/de/intevation/gnv/utils/ArtifactFactoryUtilities.java Added: + Factory to Instantiiate an ArtifactFactory (TODO: Should be moved to Artifact-database) + + * src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java Added, + src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java Added: + Interfcaedefinition and Defaultimplementation for the Representation of the different + Products in an FIS. + + * src/main/java/de/intevation/gnv/artifacts/fis/FISArtifact.java Added: + Artifact to Repersent an FIS. This Artifact is able to switch between different + SubArtifacts for handling the different Products of an FIS. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Refactoring Work done because of changes in the artifact-modules + +2009-09-10 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited, + src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Edited: + Refactoringwork done because of changes in the artifact-module + +2009-09-10 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited: + src/test/ressources/conf.xml Renamed: + Project Structure changed in artifact-database. So we have to rename + the Testconfigurationfile in conf.xml. + + * src/test/ressources/results Added: + Integrated Folder for temporal storing Resultfiles of the TestCases + + * src/test/ressources/queries.properties Edited: + Further Queries for Testcases integrated + * src/test/ressources/timeseries/timeseries_step_05_out.xml Added, + src/test/ressources/timeseries/timeseries_step_05_feed.xml Added: + Integrated the last step of the TimeSeries-Workflow. + Now the TestCase is able to render Charts. + + * src/test/ressources/timeseries/timeseries_step_04_feed.xml Edited, + src/test/ressources/timeseries/timeseries_step_03_feed.xml Edited: + Names of the feed-Parametes changed to the Syntax of BSH-Spelling + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java: + Chart Rendering completed with some Fixes to do + * src/main/java/de/intevation/gnv/transition/TransitionBase.java: + Integrated usage of KeyValueDescibeData + * src/main/java/de/intevation/gnv/transition/OutputTransition.java (getOutputModes): + Errorhandling integrated + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Edited, + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Refactored out-Method from Extending Class + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/chart/exception/TechnicalChartException.java Added, + src/main/java/de/intevation/gnv/chart/ChartFactory.java Edited: + Refactoring of the ChartFactory so that it colud be use and it is possible to compile + this class. + + * src/main/java/de/intevation/gnv/transition/describedata/KeyValueDescibeData.java Added, + src/main/java/de/intevation/gnv/transition/describedata/DefaultKeyValueDescribeData.java Added: + Added an new Representation of Describedata for Key Value Pairs using for the Parameter Lists + of the Transitions an put it into the Chartgeneration + +2009-09-09 Tim Englich + + * pom.xml Edited: + Added JfreeChart Dependency to pom-file + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/chart/Insets.java Added, + src/main/java/de/intevation/gnv/chart/ChartStyle.java Added, + src/main/java/de/intevation/gnv/chart/ChartLabels.java Added, + src/main/java/de/intevation/gnv/chart/ChartFactory.java Added: + Insert Chart-Classes from OLD-Repository Revision: 3101 Does not compile + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java Added: + The specifed OutputTransition for the Product TimeSeries. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Integration of the OutputModes in the DescriberesultDocument. + + * src/main/java/de/intevation/gnv/transition/OutputTransitionBase.java Added, + src/main/java/de/intevation/gnv/transition/OutputTransition.java Added: + The Interface and the abstract Basicimplementation of an Transition which + can produce different outputs. + + * src/main/java/de/intevation/gnv/transition/DefaultOutputMode.java Added, + src/main/java/de/intevation/gnv/transition/OutputMode.java Added: + Interfacestructur and Defaultimplementation for the Representation of the + Different OutputModes given in an Artifact. + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java (describe) Edited: + Changed DateoutputFormat from German- to Anericanstyle + +2009-09-09 Tim Englich + + * src/test/ressources/timeseries/timeseries_step_04_feed.xml Added, + * src/test/ressources/timeseries/timeseries_step_04_advance.xml Added: + Two more ArtifactCommands for the next Step in TimeSeriesArtifactTestCase + * src/test/ressources/queries.properties Edited: + New Queries for timeseries_timeinterval added. + Also use KEY ,VALUE, MIN and MAX as Identifiers for the different Columns. + * src/test/ressources/GNVArtifactsTestCase_Configuration.xml Edited, + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited: + Modified the TimeseriesArtifact and added one further TransitionStep + +2009-09-09 Tim Englich + + * src/main/java/de/intevation/gnv/transition/describedata/DefaultMinMaxDescribeData.java , + * src/main/java/de/intevation/gnv/transition/describedata/MinMaxDescribeData.java, + * src/main/java/de/intevation/gnv/transition/describedata/DescribeData.java Added: + Interface Structure and Defaultimplementation for Representing DescribeData of an + Transition added. In this Way we are able to switch between different Renderingmethods + for descibe. + * src/main/java/de/intevation/gnv/transition/MinMaxTransition.java Added: + Added MinMaxTransition for representing Min-/Max-Value Results in a Tansition + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited: + Integrated Min- / MAX-Value Support for Describe. Also done some Refactoring Work + for easy creating Extensions of this Class. + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Userinterface Informations were integrated in the wrong Method. Now the + Informations are put into the ui-Node + +2009-09-08 Tim Englich + + * src/test/ressources/timeseries/timeseries_step_01_advance.xml Edited, + src/test/ressources/timeseries/timeseries_step_01_feed.xml Edited, + src/test/ressources/timeseries/timeseries_step_02_advance.xml Added, + src/test/ressources/timeseries/timeseries_step_02_feed.xml Added, + src/test/ressources/timeseries/timeseries_step_03_advance.xml Added, + src/test/ressources/timeseries/timeseries_step_03_feed.xml Added, + src/test/ressources/GNVArtifactsTestCase_Configuration.xml: Edited, + src/test/ressources/queries.properties Added, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited: + TestCase implemented until Choosing the TimeInetval of an TimeSeries + + One Entry is Missing + +2009-09-08 Tim Englich + + * src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited, + src/main/java/de/intevation/gnv/transition/Transition.java Edited, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java Edited, + src/test/ressources/GNVArtifactsTestCase_Configuration.xml Edited, + src/test/ressources/timeseries/timeseries_step_01_feed.xml Added , + src/test/ressources/timeseries/timeseries_step_01_advance.xml Added : + Artifact.advance initial implementiert + +2009-09-08 Tim Englich + + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Edited, + src/main/java/de/intevation/gnv/transition/DefaultInputData.java Added, + src/main/java/de/intevation/gnv/transition/InputData.java Added, + src/main/java/de/intevation/gnv/transition/exception/TransitionException.java Added, + src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited, + src/main/java/de/intevation/gnv/transition/Transition.java Edited, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Edited: + Funktionalitat Feed initial bereitgestellt. + +2009-09-08 Tim Englich + + * src/test/ressources/GNVArtifactsTestCase_Configuration.xml, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java, + src/main/java/de/intevation/gnv/transition/TransitionBase.java, + src/main/java/de/intevation/gnv/transition/DefaultInputValue.java Edited: + Required Inputelements integrated in BasicArtifact-Descibe-Output + +2009-09-08 Tim Englich + + * src/main/java/de/intevation/gnv/transition/DefaultInputValue.java Added, + src/main/java/de/intevation/gnv/transition/InputValue.java Added, + src/main/java/de/intevation/gnv/transition/TransitionBase.java Edited, + src/main/java/de/intevation/gnv/transition/Transition.java Edited, + src/test/ressources/GNVArtifactsTestCase_Configuration.xml Edited: + Constructs for the required Inputvalues for an Transition created + +2009-09-08 Tim Englich + + * src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java, + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java:, + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Edited + Added Output for Describe to the Artifactimplementation + +2009-09-08 Tim Englich + + * src/test/ressources/GNVArtifactsTestCase_Configuration.xml, + src/main/java/de/intevation/gnv/transition/Transition.java (getDescription), + src/main/java/de/intevation/gnv/transition/TransitionBase.java (setup), (getDescription): + Added Description to a Transition + +2009-09-07 Tim Englich + + * src/test/ressources/GNVArtifactsTestCase_Configuration.xml, + src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCase.java: ADD + TestClass for GNV-Artifacts an TimeSeriesArtifacs + + * src/main/java/de/intevation/gnv/transition/TransitionFactory.java, + src/main/java/de/intevation/gnv/transition/TransitionBase.java, + src/main/java/de/intevation/gnv/transition/Transition.java, + src/main/java/de/intevation/gnv/transition/DefaultTransition.java: ADD + Transitionimplementation for handling the substeps of an Artifact Livecycle + + * src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java: ADD + The Artifact for handling the TimeSeries + * src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java, + src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java, + src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + The Basic-Classes for providing GNC Artifacts. this Classes should be the Fundament + for the Implementation of Specialized Artifacts e.g. TimeSeries + * pom: Edited Projectreferences to the other GNV-Projects added + +2009-09-04 Tim Englich + + * src/main/java/de/intevation/gnv/artifacts/ArtifactFactoryBase.java: + Implementation of the General ArtifactFactory + +2009-09-04 Tim Englich + + * pom.xml: Created with maven and put the Moduledependencies into it + * target | .settings | .project | .classpath: Add to SVN-Ignore + * Changes | Changelog | NEWS | README | TODO: Added + * src/**: Added to the Project diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/Changes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/Changes Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,197 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for renaming wms layers (#198) + + * Support for Contis, Nauthis and Marine Features (#92, #205) + + * Support for exporting/importing artifacts (#208) + Before an artifact is exported, the cleanup() method is called to do + relevant things before an export. + + * Improved the matrix for parameter-measurement selection. The user can + choose between different depths only without relation to a specific + parameter (#210) + + * ODV export of a 'Profilschnitt' is possible now (#217) + + * The MapServer can be called without explicitly declaration of the + mapfile path (#235, #220). A wrapper script is used - located in the + cgi directory of apache - to export the mapfile path. + + * The transition model can be plotted as pdf or svg (#262) with the help + of an xsl sheet contained in the contrib directory. + + * Added a template mechanism for 'Layer' product. A default layer is + used if there is no specific template for a layer. + + * Support for MapViewer call. A MapViewer call feeds an artifact + initially with parameters that are used if the artifact reaches states + which require these parameters. These states are called + AutoResumeStates and leads the artifact to the next state immediately. + + + Fixed: + + * Date changes have no effect on wms output (#201) + * The subtitle of a horizontalprofile chart contains its beginning + coordinate (#120) + * Limit rendering of floating point numbers to 3 decimals in + MapServer (#209) + * Improvements respective to csv exports (#122) + * Improvements respective to odv exports (#215) + * Display the the time to live of an artifact / wms layer in gui (#197) + * Avoid race-conditions while chart creation (#211) + * Remove shapefile directories if an artifact reaches its end of + life (#164) + * Avoid cut axes labels with a gap between data area and chart + border (#192, #163) + * Wrong time intervals inserted by a user don't cause NPE anymore (#212) + * User inserted wkt string are validated (#214, #251) + * The geometry type used for wms publishing is fetched from database (#213) + * Improved gap detection in timeseries charts (#175) + * Selection of layer without items not possible anymore (#200) + * Improved chart creation for product type SST (#232) + * Added the station name to the subtitle of timeseries charts (#226) + * Added the timeinterval to the subtitle of timeseries charts (#152) + * Calculate the x-range of verticalprofile charts correct (#229) + * Calculate the y-range of horizontalprofile charts correct (#233) + * The width of a class in histograms can be specified by a floating + point number (#231) + * Added label for y-axes in histograms (#243) + * 'Profilschnitte' can be exported as png-image (#216) + * I18N support for statistic output (#228) + * Improved subtitles of horizontalprofile charts (#138) + * Removed a duplicated path to the mapfile in the configuration (#220) + * The layer selection in the product 'Layer' is no longer limited to + a single layer (#252) + * Added missing units into class templates that are displayed when + calling WMS GetLegendGraphic operation on 'Horizontalschnitten' (#246) + * The Restlet server uses the same log4j configuration as the rest of + the application (#6) + * Files used by artifact-database and cache are written to an own + directory - no longer into the conf directory (#218) + + +2010-03-08 RELEASE 0.5 + + +2010-01-27 RELEASE 0.4 + + New: + + * Added entire infrastructure for interpolation pipeline: + * Rasterizers on a configurable grid resolution (x and y). + * Vectorizer producing geoemetries from rasterized data + (introducting dependency to GNU Trove 2.2.1) + * Color palette handling + * Support for using DEM (seabed) in interpolation + * helper script for converting color palettes to + QGIS 1.4 styling format + + * Diagrams: + + * 'Profilschnitte' (via JFreeChart compatible Vectorizer output) + * 'Horizontalschnitte' (via JTS compatible Vectorizer output) + * Multi-polygons: Classes determined by palette values + * Multi-linestrings: Iso lines determined with rules of #108 + + * Support for 2D diagrams with multi-polygons (with shells and holes) + and multi-linestrings (essentially what is called "Simple Feature") + * Improved labeling (heading, subheading) of all diagrams + + * Added support for ProxyArtifact to support access to history of states + * Added support for writing Shapefiles with GeoTools (introducing + dependency to GeoTools 3.5.8) + + Fixed: + + * Generation of vertical profiles failed on Marnet (#142) + * Using correct MIME-type for SVG-Export in configuration (#148) + * Enabling/Disabling points in GUI (#105) + * Reanming values for selcting the direction of an axis (#129) + * Adapting granularity for labels for timeseries (#152) + * adapting range of values for data series with identical name + and different time ranges (#136/137)i + * Corrected interpolation based on horizontal cross-section (#153) + * Enabling/Disabling points in diagrams with PDF export (#156) + * Harmonized background color in 2D diagrams (#157) + * Adding label for axis for 2D diagrams (#158) + + +2009-12-17 RELEASE 0.3 + + New: + + * SVG export for charts (introducing Apache Batik dependency) + * PDF export for charts. (introducing iText dependency) + * style templating for charts via XML. + * Units are now localized and added to the charts + * Gap detection for horizontal and vertical profile charts. + + * 'Horizontale Schnittprofile' + + * Added region filters + + Fixed: + + * Various i18n messages. (Issue 129) + * problems with verticalprofile charts. + * TG_0030.008: "Unterscheidung bei Farben wechselt + zwischen verschiedenen Ausgabeprodukten bei gleicher Parameterwahl" + * TG_0030.004: "Jahreszahlen an der Abszisse werden nicht angezeigt" + * TG_0030.004 : i18n funktioniert an Abzissenbeschriftung noch nicht (Issue 104) + + Changed: + + * The configuration system to define the workflows + with artifacts. Cleaner separation states vs. transistions. + + * Default configuration of ttl of artifacts is more realistic now. + + * Used more recent versions of JFreeChart and Apache Common Math. + + * Local caching of data is now used more consequently + + Removed: + + * Old conterra charting code. + +2009-11-13 RELEASE 0.2 + + * Adding support for relative pathnames relating to central + config document (issue 59) + + * Splitting of configuration documents (Issue 40) + + * Corrected data model of artifacs (issue 3) + + * Added FIS Sea State, SEACAT, Current Meter, Ice Station Reports + + * Implemented gaps for spatial and temportal gaps (issue 45) + + * TG_0040.005: Added a first ODV support + + * Added more input validation to make it more user-friendly + + * Added a first documentation of configuration documents + + +2009-10-07 RELEASE 0.1 + + * Initial release of the artifacts special for the + BSH Generic Viewer. They are to be configured to live + inside an artifact database via conf.xml. + + * The collection of parameters is modelled by transistions + inside the XML. + + * src/test/ressources/conf.xml gives a setup to use all + the provided artifacts. + + * Products can be produced for following FIS: + Marnet, IMIS, STAUN, Modeldata, Delphin, Thermosalinograph, + Chemusurvey, GTS, CTD, CBT in form of time series, + vertical profiles and horizontal profiles on meshes + and instantaneous points. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/NEWS Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,142 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for renaming wms layers + + * Support for Contis, Nauthis and Marine Features + + * Support for saving/loading existing artifacts (e.g. for saving/loading + the current parametrization) + + * Improved the matrix for parameter-measurement selection. The user can + choose between different depths only without relation to a specific + parameter (#210) + + * Support for odv exports on 'Profilschnitten' (#217) + + * The MapServer can be called without explicitly declaration of the + mapfile path (#235, #220) + + * The configuration of the transition model can be plotted as svg or + pdf (#262) + + * Improved shapefile writing in 'Layer' product - write each column + retrieved by database into shapefile. + + * Improved the input validation. More specific error messages are + * displayed if the validation fails. + + * Support for an initial parameterization via MapViewer call. + + + +2010-03-08 RELEASE 0.5 + + +2010-01-27 RELEASE 0.4 + + Processing: + * Added central support for the entire interpolation infrastructure + with a lot of configuration capabilities: + * rasterizing input data sets + * calculating interpolation paying attention to different boundary + conditions: Less than 3 point, extrapolating to the ground, water + surface, ... + * tracing isolines + * clipping geometries + * exporting interpolated polygons and isolines + * rendering of 2D-diagrams and export of Shapefiles + + for "Horizontales Schnittprofil", Vertical- and Horizontal Cross + Section. Made parts of the interpolation configurable like + resolution of interpolation raster; color palettes. + + * Optimizing of runtime of interpolations + + * Diagramm specific: + * Made color paletts configurable for rendering Vertical-Cross + Sections. Added helper script to convert same palettes to QGIS (at + least version 1.4 supported) styling format + + * Support for 2D diagrams with multipolygons with holes and shells + + * Made color of seabed configurable for vertical cross-sections + + * Added special renderer for labeling isolines in dense areas + in order to avoid overlaps + + + * Dependency to GUI generation: + * Splitting date selections in a 2 step transition: year, exact + point of time as required in the webclient + + + * Cleaning up internal model of steps to correspond to internal + objects in cache + + + * Add support for a wizard-based model of states in order to support + a 1-step back history in a first step; preparation for + multistep-history done. + + + * Configuration: + * Configuration: Enhanced configuration for connection testing of + SDE. So fare, now stable for reusing connections. + + * Configurability of Mesh-Width per data model + + * Others: + * Added support for exporting shapefiles and integrating into + artefact-lifecycle in order to remove files/directories after + end-of-life + + * Support for a MapViewer interfaced based on a database-based + configuration + + * Added support for raster data to taking into account sea + topography + + +2009-12-17 RELEASE 0.3 + + * PDF export + + * SVG export + + * Chart Templating + + * 'Horizontale Schnittprofile' + + * various i18n fixes + +2009-11-13 RELEASE 0.2 + + * Added support for all required FIS: + Marnet, IMIS, STAUN, Modelldaten, Eisklimatologie, Eismeldungen, SST, + Delphin, Thermosalinograph, Chemusurvey, GTS, CTD, XBT, SeaCat, + Seegangsarchiv, Strommesser (Req. TG_0020.001) + + * Added support for vertical profiles (Chapter 3.3.3.2.2) + + * Added support for horizontal profiles (Chapter 3.3.3.2.3); + part independent of MapViewer + + * Added a first support for ODV format (Req. TG_0040.005) + + * Enabling client for multi-instances (Req. 00_0000.007) + + * Adding of support of internal area filter (Req. TG_0020.012 b) + + * Added more support for internationalization (TG_0050.004) + + * Improved error handling with more user-friendly messages + + * Added required statistical support (Chapter 3.3.3.3.1) + + +2009-10-07 RELEASE 0.1 + + * Initial release of the artifacts special for the Generic BSH Viewer. + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/TODO Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ +TODO: + * Caching of charts is configured via system property. This should be done + in another way. (Property: -Dcache.chart) + * charts for verticalcrosssection and horizontalcrosssection need to be + implemented + * distance of tick units in timeseries charts are in form of "dd-MMM". This + needs to be adapted depending on range of x-axis. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/bin/run.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/bin/run.sh Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,16 @@ +#!/bin/bash + +DIR=`dirname $0`/.. +CLASSPATH= +for l in `find -name \*.jar -print`; do + CLASSPATH=$CLASSPATH:$l +done + +export CLASSPATH + +exec java -Xmx256m \ + -server \ + -Djava.io.tmpdir=/tmp/ \ + -Dartifact.database.dir="$DIR/conf" \ + de.intevation.artifactdatabase.App \ + 2>&1 > /dev/null diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/contrib/mapserv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/contrib/mapserv Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,3 @@ +#!/bin/sh +export MS_MAPFILE=/opt/artifacts/mapfiles/mapfile.map +./mapserv-gp diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/contrib/palette2polygonVM.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/contrib/palette2polygonVM.xsl Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,21 @@ + + + + + + + + + + + CLASS + NAME "" + EXPRESSION ("[CLASS]"="") + STYLE + COLOR "" + END + END + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/contrib/palette2qgis.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/contrib/palette2qgis.xsl Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + 10 + 11 + 12 + 13 + 14 + 15 + + + + + + + + + + + + + + + + + + + + + hard:circle + 2 + pixels + + + + + NoPen + 0.26 + + + + + + + + + + SolidPattern + + + + + + 255 + CLASS + + + + + hard:circle + 2 + pixels + + + + + DashDotDotLine + 0.26 + + SolidPattern + + + + CLASS + + + + + + + + + + + PARAMETER + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/contrib/visualize-transitions.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/contrib/visualize-transitions.xsl Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,116 @@ + + + + + + . + + + digraph transition_model { + + } + + + + + + + + + + ${artifacts.config.dir} + + + + + + + + + + subgraph + { + label = "Artefakt: + + "; + + + } + + + + + + + + [ shape = "record" label=<<table border="0" cellborder="0" cellpadding="3"> + <tr><td align="center" colspan="2" bgcolor="black"><font color="white"> + + </font></td></tr> + + </table>>] + ; + + + + <tr><td align="right"> + + </td><td align="left"> + + </td></tr> + + + + + + -> + + + ; + + + + [ label=" + + + + + + " ] + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/arcsdeconnectionpool.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/arcsdeconnectionpool.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,35 @@ +############################################################################### +############################################################################### +# In this File it is possible to configure the Connectionpool to the the +# ArcSDE-DataBackend. +# maxActive: Number of maximal Connection which can be used. +# testOnBorrow: Should the Pool test the Connection which will be borrowed +# if it is Valid +# testOnReturn: Should the Pool test the Connection which will be returned +# if it is Valid +# testWhileIdle: Should the Pool test the Connection while it is Idl +# if it is Valid +# timeBetweenEvictionRunsMillis : Time in Milliseconds which is allowed +# to reused a returned Connection. +# serverRoundtripInterval : The Timea ArcSDE-Connection must nor be used until +# the Connection will test if it is valid. +# server: The URL of the Server where the Database is reachable. +# username: The Username which should be used to Connect to the Databackend. +# credentials: The Credentials to the given username +# port: The Communicationport which must be used to connect to the Databackend +# database: The Name of the Instance which should be connected to. +############################################################################### +############################################################################### + +maxActive=2 +testOnBorrow=true +testOnReturn=false +testWhileIdle=false +timeBetweenEvictionRunsMillis=360000 +serverRoundtripInterval=5 +serverInactiveInterval=300 +server=localhost +username=gast +credentials=gast +port=22119 +database=esri_sde diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/charttemplate.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/charttemplate.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,86 @@ + + + + + + + + + + + + <font> + <size value="20" /> + <type value="Tahoma" /> + <color value="0x000000" /> + <bold value="true" /> + </font> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 5 + 5 + 5 + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/conf.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/conf.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,550 @@ + + BLABLABLBALBLABL + + de.intevation.gnv.artifacts.context.GNVArtifactContextFactory + + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + de.intevation.gnv.artifacts.GNVProductArtifactFactory + + + de.intevation.artifactdatabase.DefaultServiceFactory + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + de.intevation.gnv.artifacts.GNVArtifactFactory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${artifacts.config.dir}/charttemplate.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${artifacts.config.dir}/maptemplates + mapfile.vm + + + + + + + + + + + + + + + ${artifacts.config.dir}/ehcache.xml + + + + + ${artifacts.config.dir}/arcsdeconnectionpool.properties + ${artifacts.config.dir}/queries.properties + + + + 8181 + localhost + + + + 60000 + + + SA + + jdbc:h2:${artifacts.config.dir}/../artifactdb/artifacts.db + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/ehcache.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/ehcache.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/log4j.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/log4j.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,17 @@ +############################################################################### +# Developmentconfiguration for the Loggingengine. +# The Configuration will only log the Information to the Console. +# For Test- and Productionenviroment it is necessary to create a +# separate Configuration which will be log the Informations e.g. into +# a File (RolingFileAppender). +############################################################################### + +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/flow-velocity_isolines.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/flow-velocity_isolines.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ + CLASS + NAME "DEFAULT" + LABEL + TYPE TRUETYPE + FONT FreeSans + SIZE 10 + MAXSIZE 10 + MINSIZE 7 + COLOR 0 0 0 + MINDISTANCE 250 + ANGLE AUTO + POSITION CC + MINFEATURESIZE AUTO + OUTLINECOLOR 255 255 255 + PARTIALS False + END + STYLE + COLOR "#000000" + END + END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/flow-velocity_polygons.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/flow-velocity_polygons.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,109 @@ + + + CLASS + NAME "< 0.025 [m/s]" + EXPRESSION ("[CLASS]"="0") + STYLE + COLOR "#38a800" + END + END + + + CLASS + NAME "0.025 - 0.05 [m/s]" + EXPRESSION ("[CLASS]"="1") + STYLE + COLOR "#56b800" + END + END + + + CLASS + NAME "0.05 - 0.1 [m/s]" + EXPRESSION ("[CLASS]"="2") + STYLE + COLOR "#74c700" + END + END + + + CLASS + NAME "0.1 - 0.3 [m/s]" + EXPRESSION ("[CLASS]"="3") + STYLE + COLOR "#96d600" + END + END + + + CLASS + NAME "0.3 - 0.5 [m/s]" + EXPRESSION ("[CLASS]"="4") + STYLE + COLOR "#bfe600" + END + END + + + CLASS + NAME "0.5 - 0.7 [m/s]" + EXPRESSION ("[CLASS]"="5") + STYLE + COLOR "#e9f500" + END + END + + + CLASS + NAME "0.7 - 0.9 [m/s]" + EXPRESSION ("[CLASS]"="6") + STYLE + COLOR "#ffea00" + END + END + + + CLASS + NAME "0.9 - 1.1 [m/s]" + EXPRESSION ("[CLASS]"="7") + STYLE + COLOR "#ffbb00" + END + END + + + CLASS + NAME "1.1 - 1.3 [m/s]" + EXPRESSION ("[CLASS]"="8") + STYLE + COLOR "#ff8c00" + END + END + + + CLASS + NAME "1.3 - 1.5 [m/s]" + EXPRESSION ("[CLASS]"="9") + STYLE + COLOR "#ff5e00" + END + END + + + CLASS + NAME "1.5 - 1.7 [m/s]" + EXPRESSION ("[CLASS]"="10") + STYLE + COLOR "#ff2f00" + END + END + + + CLASS + NAME "> 1.7 [m/s]" + EXPRESSION ("[CLASS]"="11") + STYLE + COLOR "#ff0000" + END + END + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_flow-velocity.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_flow-velocity.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ +LAYER + NAME "$info.getTitle()" + GROUP "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + #include("flow-velocity_polygons.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_flow-velocity_isolines.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_flow-velocity_isolines.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ +LAYER + NAME "$info.getTitle()_isolines" + GROUP "$info.getTitle()" + DATA "${info.getName()}/${info.getData()}" + TYPE $info.getType() + STATUS $info.getStatus() + LABELITEM DESC + #include("flow-velocity_isolines.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_salinity.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_salinity.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ +LAYER + NAME "$info.getTitle()" + GROUP "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + #include("salinity_polygons.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_salinity_isolines.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ +LAYER + NAME "$info.getTitle()_isolines" + GROUP "$info.getTitle()" + DATA "${info.getName()}/${info.getData()}" + TYPE $info.getType() + STATUS $info.getStatus() + LABELITEM DESC + #include("salinity_isolines.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-levels.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-levels.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ +LAYER + NAME "$info.getTitle()" + GROUP "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + #include("water-levels_polygons.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-levels_isolines.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-levels_isolines.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ +LAYER + NAME "$info.getTitle()_isolines" + GROUP "$info.getTitle()" + DATA "${info.getName()}/${info.getData()}" + TYPE $info.getType() + STATUS $info.getStatus() + LABELITEM DESC + #include("water-levels_isolines.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-temperature.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-temperature.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ +LAYER + NAME "$info.getTitle()" + GROUP "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + #include("water-temperature_polygons.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-temperature_isolines.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/horizontalcrosssection_water-temperature_isolines.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ +LAYER + NAME "$info.getTitle()_isolines" + GROUP "$info.getTitle()" + DATA "${info.getName()}/${info.getData()}" + TYPE $info.getType() + STATUS $info.getStatus() + LABELITEM DESC + #include("water-temperature_isolines.class.vm") +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/layer_linestring.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/layer_linestring.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,15 @@ +LAYER + NAME "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + + CLASS + NAME "Layer" + STYLE + SYMBOl 'point' + SIZE 5 + COLOR "#FFFF00" + END + END +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/layer_point.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/layer_point.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,15 @@ +LAYER + NAME "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + + CLASS + NAME "Layer" + STYLE + SYMBOL 'point' + SIZE 7 + COLOR "#FFFF00" + END + END +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/layer_polygon.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/layer_polygon.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ +LAYER + NAME "$info.getTitle()" + TYPE $info.getType() + DATA "${info.getName()}/${info.getData()}" + STATUS $info.getStatus() + + CLASS + NAME "Layer" + STYLE + COLOR "#FFFF00" + END + END +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/mapfile.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/mapfile.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +MAP + NAME "GNV-Map" + STATUS ON + SIZE 600 400 + EXTENT -1 53 11 58 + UNITS DD + SHAPEPATH "../shapefiles" + FONTSET "fontset.txt" + IMAGECOLOR 255 255 255 + PROJECTION + "init=epsg:4326" + END + + WEB + METADATA + "wms_title" "GNV Web Map Service" + "wms_onlineresource" "$MAPSERVERURL" + "wms_accessconstraints" "none" + "wms_fees" "none" + "wms_addresstype" "postal" + "wms_address" "Any Street" + "wms_city" "Any City" + "wms_stateorprovince" "Any state" + "wms_postcode" "My Postalcode" + "wms_country" "Any Country" + "wms_contactperson" "Any Person" + "wms_contactorganization" "Any Orga" + "wms_contactelectronicmailaddress" "any-email@example.com" + "wms_contactvoicetelephone" "Any's telephone number" + "wms_srs" "EPSG:4326 EPSG:32631 EPSG:32632 EPSG:32633" + "wms_feature_info_mime_type" "text/html" + END + END + + SYMBOL + NAME 'point' + TYPE ELLIPSE + POINTS + 1 1 + END + FILLED TRUE + END + + ## Don't change the following lines. + $LAYERS + +END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/salinity_isolines.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/salinity_isolines.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ + CLASS + NAME "DEFAULT" + LABEL + TYPE TRUETYPE + FONT FreeSans + SIZE 10 + MAXSIZE 10 + MINSIZE 7 + COLOR 0 0 0 + MINDISTANCE 250 + ANGLE AUTO + POSITION CC + MINFEATURESIZE AUTO + OUTLINECOLOR 255 255 255 + PARTIALS False + END + STYLE + COLOR "#000000" + END + END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/salinity_polygons.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/salinity_polygons.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,281 @@ + + + CLASS + + NAME "< 2.0 [pSal]" + EXPRESSION ("[CLASS]"="0") + STYLE + COLOR "#02db00" + END + END + + + CLASS + + NAME "2.0 - 3.0 [pSal]" + EXPRESSION ("[CLASS]"="1") + STYLE + COLOR "#01e600" + END + END + + + CLASS + + NAME "3.0 - 4.0 [pSal]" + EXPRESSION ("[CLASS]"="2") + STYLE + COLOR "#02f200" + END + END + + + CLASS + + NAME "4.0 - 5.0 [pSal]" + EXPRESSION ("[CLASS]"="3") + STYLE + COLOR "#00ff00" + END + END + + + CLASS + + NAME "5.0 - 6.0 [pSal]" + EXPRESSION ("[CLASS]"="4") + STYLE + COLOR "#23fd22" + END + END + + + CLASS + + NAME "6.0 - 7.0 [pSal]" + EXPRESSION ("[CLASS]"="5") + STYLE + COLOR "#47fe46" + END + END + + + CLASS + + NAME "7.0 - 8.0 [pSal]" + EXPRESSION ("[CLASS]"="6") + STYLE + COLOR "#5afd59" + END + END + + + CLASS + + NAME "8.0 - 9.0 [pSal]" + EXPRESSION ("[CLASS]"="7") + STYLE + COLOR "#6ffe6e" + END + END + + + CLASS + + NAME "9.0 - 10.0 [pSal]" + EXPRESSION ("[CLASS]"="8") + STYLE + COLOR "#89fd88" + END + END + + + CLASS + + NAME "10.0 - 12.0 [pSal]" + EXPRESSION ("[CLASS]"="9") + STYLE + COLOR "#a5fea4" + END + END + + + CLASS + + NAME "12.0 - 14.0 [pSal]" + EXPRESSION ("[CLASS]"="10") + STYLE + COLOR "#b3feb3" + END + END + + + CLASS + + NAME "14.0 - 16.0 [pSal]" + EXPRESSION ("[CLASS]"="11") + STYLE + COLOR "#c2fec2" + END + END + + + CLASS + + NAME "16.0 - 18.0 [pSal]" + EXPRESSION ("[CLASS]"="12") + STYLE + COLOR "#e0fee0" + END + END + + + CLASS + + NAME "18.0 - 20.0 [pSal]" + EXPRESSION ("[CLASS]"="13") + STYLE + COLOR "#ffffff" + END + END + + + CLASS + + NAME "20.0 - 24.0 [pSal]" + EXPRESSION ("[CLASS]"="14") + STYLE + COLOR "#fef5ef" + END + END + + + CLASS + + NAME "24.0 - 28.0 [pSal]" + EXPRESSION ("[CLASS]"="15") + STYLE + COLOR "#feede0" + END + END + + + CLASS + + NAME "28.0 - 30.0 [pSal]" + EXPRESSION ("[CLASS]"="16") + STYLE + COLOR "#fee5d1" + END + END + + + CLASS + + NAME "30.0 - 32.0 [pSal]" + EXPRESSION ("[CLASS]"="17") + STYLE + COLOR "#fdd8ba" + END + END + + + CLASS + + NAME "32.0 - 34.0 [pSal]" + EXPRESSION ("[CLASS]"="18") + STYLE + COLOR "#fecca4" + END + END + + + CLASS + + NAME "34.0 - 34.5 [pSal]" + EXPRESSION ("[CLASS]"="19") + STYLE + COLOR "#fdbe8b" + END + END + + + CLASS + + NAME "34.5 - 35.0 [pSal]" + EXPRESSION ("[CLASS]"="20") + STYLE + COLOR "#feb073" + END + END + + + CLASS + + NAME "35.0 - 35.2 [pSal]" + EXPRESSION ("[CLASS]"="21") + STYLE + COLOR "#fda35b" + END + END + + + CLASS + + NAME "35.2 - 35.4 [pSal]" + EXPRESSION ("[CLASS]"="22") + STYLE + COLOR "#fe9846" + END + END + + + CLASS + + NAME "35.4 - 35.6 [pSal]" + EXPRESSION ("[CLASS]"="23") + STYLE + COLOR "#fd8422" + END + END + + + CLASS + + NAME "35.6 - 35.8 [pSal]" + EXPRESSION ("[CLASS]"="24") + STYLE + COLOR "#fe7100" + END + END + + + CLASS + + NAME "35.8 - 36.0 [pSal]" + EXPRESSION ("[CLASS]"="25") + STYLE + COLOR "#fe6900" + END + END + + + CLASS + + NAME "36.0 - 37.0 [pSal]" + EXPRESSION ("[CLASS]"="26") + STYLE + COLOR "#fe6100" + END + END + + + CLASS + + NAME "> 37.0 [pSal]" + EXPRESSION ("[CLASS]"="27") + STYLE + COLOR "#fe5900" + END + END + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/water-levels_isolines.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/water-levels_isolines.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ + CLASS + NAME "DEFAULT" + LABEL + TYPE TRUETYPE + FONT FreeSans + SIZE 10 + MAXSIZE 10 + MINSIZE 7 + COLOR 0 0 0 + MINDISTANCE 250 + ANGLE AUTO + POSITION CC + MINFEATURESIZE AUTO + OUTLINECOLOR 255 255 255 + PARTIALS False + END + STYLE + COLOR "#000000" + END + END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/water-levels_polygons.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/water-levels_polygons.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,217 @@ + + + CLASS + NAME "-inf - 5" + EXPRESSION ("[CLASS]"="0") + STYLE + COLOR "#870087" + END + END + + + CLASS + NAME "-5.0 - -4.5" + EXPRESSION ("[CLASS]"="1") + STYLE + COLOR "#c700c7" + END + END + + + CLASS + NAME "-4.5 - -4.0" + EXPRESSION ("[CLASS]"="2") + STYLE + COLOR "#ff00ff" + END + END + + + CLASS + NAME "-4.0 - -3.5" + EXPRESSION ("[CLASS]"="3") + STYLE + COLOR "#bb00ff" + END + END + + + CLASS + NAME "-3.5 - -3.0" + EXPRESSION ("[CLASS]"="4") + STYLE + COLOR "#7700ff" + END + END + + + CLASS + NAME "-3.0 - -2.5" + EXPRESSION ("[CLASS]"="5") + STYLE + COLOR "#0000ff" + END + END + + + CLASS + NAME "-2.5 - -2.0" + EXPRESSION ("[CLASS]"="6") + STYLE + COLOR "#0000e8" + END + END + + + CLASS + NAME "-2.0 - -1.5" + EXPRESSION ("[CLASS]"="7") + STYLE + COLOR "#0082d9" + END + END + + + CLASS + NAME "-1.5 - -1.0" + EXPRESSION ("[CLASS]"="8") + STYLE + COLOR "#00b2ff" + END + END + + + CLASS + NAME "-1.0 - -0.5" + EXPRESSION ("[CLASS]"="9") + STYLE + COLOR "#00ddff" + END + END + + + CLASS + NAME "-0.5 - 0.0" + EXPRESSION ("[CLASS]"="10") + STYLE + COLOR "#00ffff" + END + END + + + CLASS + NAME "0.0 - 0.5" + EXPRESSION ("[CLASS]"="11") + STYLE + COLOR "#49d1cd" + END + END + + + CLASS + NAME "0.5 - 1.0" + EXPRESSION ("[CLASS]"="12") + STYLE + COLOR "#20b0a9" + END + END + + + CLASS + NAME "1.0 - 1.5" + EXPRESSION ("[CLASS]"="13") + STYLE + COLOR "#14c76d" + END + END + + + CLASS + NAME "1.5 - 2.0" + EXPRESSION ("[CLASS]"="14") + STYLE + COLOR "#09e03b" + END + END + + + CLASS + NAME "2.0 - 2.5" + EXPRESSION ("[CLASS]"="15") + STYLE + COLOR "#00ff1a" + END + END + + + CLASS + NAME "2.5 - 3.0" + EXPRESSION ("[CLASS]"="16") + STYLE + COLOR "#aeff00" + END + END + + + CLASS + NAME "3.0 - 3.5" + EXPRESSION ("[CLASS]"="17") + STYLE + COLOR "#f2ff00" + END + END + + + CLASS + NAME "3.5 - 4.0" + EXPRESSION ("[CLASS]"="18") + STYLE + COLOR "#ffc800" + END + END + + + CLASS + NAME "4.0 - 4.5" + EXPRESSION ("[CLASS]"="19") + STYLE + COLOR "#ff8800" + END + END + + + CLASS + NAME "4.5 - 5.0" + EXPRESSION ("[CLASS]"="20") + STYLE + COLOR "#ff4400" + END + END + + + CLASS + NAME "5.0 - 5.5" + EXPRESSION ("[CLASS]"="21") + STYLE + COLOR "#ff0000" + END + END + + + CLASS + NAME "5.5 - 6.0" + EXPRESSION ("[CLASS]"="22") + STYLE + COLOR "#c70000" + END + END + + + CLASS + NAME "6.0 - inf" + EXPRESSION ("[CLASS]"="23") + STYLE + COLOR "#870000" + END + END + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/water-temperature_isolines.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/water-temperature_isolines.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ + CLASS + NAME "DEFAULT" + LABEL + TYPE TRUETYPE + FONT FreeSans + SIZE 10 + MAXSIZE 10 + MINSIZE 7 + COLOR 0 0 0 + MINDISTANCE 250 + ANGLE AUTO + POSITION CC + MINFEATURESIZE AUTO + OUTLINECOLOR 255 255 255 + PARTIALS False + END + STYLE + COLOR "#000000" + END + END diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/maptemplates/water-temperature_polygons.class.vm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/maptemplates/water-temperature_polygons.class.vm Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,281 @@ + + + CLASS + + NAME "< -1 [degC]" + EXPRESSION ("[CLASS]"="0") + STYLE + COLOR "#ff33ff" + END + END + + + CLASS + + NAME "-1 - 0 [degC]" + EXPRESSION ("[CLASS]"="1") + STYLE + COLOR "#ff98ff" + END + END + + + CLASS + + NAME "0 - 1 [degC]" + EXPRESSION ("[CLASS]"="2") + STYLE + COLOR "#3300cc" + END + END + + + CLASS + + NAME "1 - 2 [degC]" + EXPRESSION ("[CLASS]"="3") + STYLE + COLOR "#3366ff" + END + END + + + CLASS + + NAME "2 - 3 [degC]" + EXPRESSION ("[CLASS]"="4") + STYLE + COLOR "#3399ff" + END + END + + + CLASS + + NAME "3 - 4 [degC]" + EXPRESSION ("[CLASS]"="5") + STYLE + COLOR "#33ccff" + END + END + + + CLASS + + NAME "4 - 5 [degC]" + EXPRESSION ("[CLASS]"="6") + STYLE + COLOR "#33ffff" + END + END + + + CLASS + + NAME "5 - 6 [degC]" + EXPRESSION ("[CLASS]"="7") + STYLE + COLOR "#007800" + END + END + + + CLASS + + NAME "6 - 7 [degC]" + EXPRESSION ("[CLASS]"="8") + STYLE + COLOR "#009900" + END + END + + + CLASS + + NAME "7 - 8 [degC]" + EXPRESSION ("[CLASS]"="9") + STYLE + COLOR "#00ba00" + END + END + + + CLASS + + NAME "8 - 9 [degC]" + EXPRESSION ("[CLASS]"="10") + STYLE + COLOR "#00de00" + END + END + + + CLASS + + NAME "9 - 10 [degC]" + EXPRESSION ("[CLASS]"="11") + STYLE + COLOR "#00ff00" + END + END + + + CLASS + + NAME "10 - 11 [degC]" + EXPRESSION ("[CLASS]"="12") + STYLE + COLOR "#ffff33" + END + END + + + CLASS + + NAME "11 - 12 [degC]" + EXPRESSION ("[CLASS]"="13") + STYLE + COLOR "#ffee33" + END + END + + + CLASS + + NAME "12 - 13 [degC]" + EXPRESSION ("[CLASS]"="14") + STYLE + COLOR "#ffdd33" + END + END + + + CLASS + + NAME "13 - 14 [degC]" + EXPRESSION ("[CLASS]"="15") + STYLE + COLOR "#ffcc33" + END + END + + + CLASS + + NAME "14 - 15 [degC]" + EXPRESSION ("[CLASS]"="16") + STYLE + COLOR "#ffbb33" + END + END + + + CLASS + + NAME "15 - 16 [degC]" + EXPRESSION ("[CLASS]"="17") + STYLE + COLOR "#ffaa00" + END + END + + + CLASS + + NAME "16 - 17 [degC]" + EXPRESSION ("[CLASS]"="18") + STYLE + COLOR "#ff9900" + END + END + + + CLASS + + NAME "17 - 18 [degC]" + EXPRESSION ("[CLASS]"="19") + STYLE + COLOR "#ff7700" + END + END + + + CLASS + + NAME "18 - 19 [degC]" + EXPRESSION ("[CLASS]"="20") + STYLE + COLOR "#ff0000" + END + END + + + CLASS + + NAME "19 - 20 [degC]" + EXPRESSION ("[CLASS]"="21") + STYLE + COLOR "#ed0000" + END + END + + + CLASS + + NAME "20 - 21 [degC]" + EXPRESSION ("[CLASS]"="22") + STYLE + COLOR "#cc0000" + END + END + + + CLASS + + NAME "21 - 22 [degC]" + EXPRESSION ("[CLASS]"="23") + STYLE + COLOR "#ba0000" + END + END + + + CLASS + + NAME "22 - 23 [degC]" + EXPRESSION ("[CLASS]"="24") + STYLE + COLOR "#ab0000" + END + END + + + CLASS + + NAME "23 - 24 [degC]" + EXPRESSION ("[CLASS]"="25") + STYLE + COLOR "#990000" + END + END + + + CLASS + + NAME "24 - 25 [degC]" + EXPRESSION ("[CLASS]"="26") + STYLE + COLOR "#870000" + END + END + + + CLASS + + NAME "> 25 [degC]" + EXPRESSION ("[CLASS]"="27") + STYLE + COLOR "#ab0089" + END + END + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/meshwidth.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/meshwidth.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/palette/flow-velocity.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/palette/flow-velocity.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/palette/salinity.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/palette/salinity.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/palette/water-levels.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/palette/water-levels.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/palette/water-temperature.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/palette/water-temperature.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/horizontalcrosssection/conf_mesh.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/horizontalcrosssection/conf_mesh.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + mesh_polygon + false + + + + + + + + + + + + + + horizontalcrosssection_meshpoint_depth + depthid + false + + + + + + + + + + + + + + + + horizontalcrosssection_meshpoint_depth + depthid + false + + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + false + + + + + + + + + + + + + + + + horizontalcrosssection_mesh_year + yearid + false + + + + + + + + + + + + + + + + + horizontalcrosssection_mesh_date + dateid + false + + + + + + + + + + + + + + + + + + horizontalcrosssection_mesh_data + horizontalprofile_meshpoint_cross_ij + horizontalcrosssection_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/horizontalprofile/conf_instantaneouspoint.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_vehicle_with_wkt + vehicleid + false + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_cruise_with_wkt + cruiseid + false + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_track_with_wkt + trackid + false + + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_vehicle_with_area + vehicleid + false + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_cruise_with_area + cruiseid + false + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_track_with_area + trackid + false + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_vehicle + vehicleid + false + + horizontalprofile_instantaneouspoint_cruise + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_cruise + cruiseid + false + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_track + trackid + false + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_surveyinfo + surveyid + false + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_depth + measurementid + true + + + + + + + + + + + + + + + + + horizontalprofile_instantaneouspoint_chart_data + horizontalprofile_instantaneouspoint_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/horizontalprofile/conf_mesh.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/horizontalprofile/conf_mesh.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + mesh_coordinate + false + + + + + + + + + + + + + + verticalprofile_mesh_point + mesh_point + false + + + + + + + + + + + + + + + + verticalprofile_mesh_point + mesh_point + false + + + + + + + + + + + + + + + + + axisid + false + + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + + horizontalprofile_meshpoint_depth + depthid + true + + + + + + + + + + + + + + + + + verticalprofile_mesh_year + yearid + true + + + + + + + + + + + + + + + + + + verticalprofile_mesh_date + dateid + true + + + + + + + + + + + + + + + + + + + horizontalprofile_mesh_chart_data + horizontalprofile_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/horizontalprofile/conf_mesh_cross.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/horizontalprofile/conf_mesh_cross.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + mesh_linestring + false + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + + horizontalprofile_meshpoint_depth + depthid + true + + + + + + + + + + + + + + + + verticalprofile_mesh_year + yearid + true + + + + + + + + + + + + + + + + + + verticalprofile_mesh_date + dateid + true + + + + + + + + + + + + + + + + + + horizontalprofile_mesh_cross_chart_data + horizontalprofile_meshpoint_cross_ij + horizontalprofile_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/layer/conf.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/layer/conf.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + layer + layerid + true + + + + + + + + + + + + + + layer_request_data + layer_data + + + + + + + + + + + + + + + + layer + layerid + true + + + + + + + + + + + + + + + layer_request_data + layer_data_with_geom + geometry_for_subareafilter + layer_colums + subareaid + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/timeseries/conf_mesh.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/timeseries/conf_mesh.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + + mesh_coordinate + false + + + + + + + + + + + + + + timeseries_meshpoint + mesh_point + false + + + + + + + + + + + + + + + + + timeseries_meshpoint + mesh_point + false + + + + + + + + + + + + + + + + timeseries_meshpoint_depth + depthid + true + + + + + + + + + + + + + + + timeseries_mesh_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + + timeseries_mesh_interval + timeinterval + false + + + + + + + + + + + + + + + + + + timeseries_mesh_chart_data + timeseries_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/timeseries/conf_timeseriespoint.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/timeseries/conf_timeseriespoint.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + timeseries_timeseriespoint_with_wkt + featureid + false + + + + + + + + + + + + + + + + + + area_filter + + + areaid + + + false + + + true + + + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + timeseries_timeseriespoint + featureid + false + + + + + + + + + + + + + + timeseries_timeseriespoint_with_area + featureid + false + + + + + + + + + + + + + + + timeseries_parameter + parameterid + parameter + true + + + + + + + + + + + + + + timeseries_depth_height + measurementid + true + + + + + + + + + + + + + + + timeseries_interval + timeinterval + false + + + + + + + + + + + + + + + + + timeseries_chart_data + timeseries_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/timeseries/timegap_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/timeseries/timegap_definition.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/verticalcrosssection/conf_mesh.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/verticalcrosssection/conf_mesh.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + mesh_linestring + false + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + false + + + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + false + + + + + + + + + + + + + + + verticalcrosssection_mesh_year + yearid + false + + + + + + + + + + + + + + + + + + verticalcrosssection_mesh_date + dateid + false + + + + + + + + + + + + + + + + + + + verticalcrosssection_mesh_chart_data + verticalcrosssection_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/verticalprofile/conf_instantaneouspoint.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/verticalprofile/conf_instantaneouspoint.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_series_with_wkt + seriesid + false + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_point_with_wkt + instantaneouspoint_point + false + + + + + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_series_with_area + seriesid + false + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_point_with_aera + instantaneouspoint_point + false + + + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_series + seriesid + false + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_point + instantaneouspoint_point + false + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_minmaxdepth + depthrange + true + + + + + + + + + + + + + + + + + verticalprofile_instantaneouspoint_chart_data + verticalprofile_instantaneouspoint_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/verticalprofile/conf_mesh.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/verticalprofile/conf_mesh.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_wkt + meshid + false + + + + + + + + + + + + + + + + verticalprofile_mesh_point + mesh_point + false + + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_mesh + meshid + false + + + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_with_area + meshid + false + + + + + + + + + + + + + + + + + + + + + + mesh_coordinate + false + + + + + + + + + + + + + + verticalprofile_mesh_point + mesh_point + false + + + + + + + + + + + + + + + + verticalprofile_mesh_mindepth + mindepthid + false + + + + + + + + + + + + + + + verticalprofile_mesh_maxdepth + maxdepthid + false + + verticalprofile_meshpoint_parameter + + + + + + + + + + + + + + + + + verticalprofile_mesh_parameter + parameterid + parameter + true + + + + + + + + + + + + + + + + + verticalprofile_mesh_year + yearid + true + + + + + + + + + + + + + + + + + + verticalprofile_mesh_date + dateid + true + + + + + + + + + + + + + + + + + + + verticalprofile_mesh_chart_data + verticalprofile_mesh_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/products/verticalprofile/conf_timeseriespoint.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/products/verticalprofile/conf_timeseriespoint.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + timeseries_timeseriespoint_with_wkt + featureid + false + + + + + + + + + + + + + + + + area_filter + areaid + false + true + + + + + + + + + + + + + + + + + + + + subarea_filter + subareaid + false + + + + + + + + + + + + + + + verticalprofile_point + featureid + false + + + + + + + + + + + + + + timeseries_timeseriespoint_with_area + featureid + false + + + + + + + + + + + + + + + verticalprofile_parameter + parameterid + parameter + true + + + + + + + + + + + + + + verticalprofile_year + yearid + true + + + + + + + + + + + + + + + verticalprofile_date + dateid + true + + + + + + + + + + + + + + + + verticalprofile_minmaxdepth + depthrange + true + + + + + + + + + + + + + + + + + verticalprofile_chart_data + verticalprofile_odv_data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/conf/queries.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/conf/queries.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1408 @@ +############################################# +############################################# +########## Zeitserie ############## +############################################# +############################################# + +timeseries_timeseriespoint=SELECT DISTINCT \ + tsp.FEATUREID KEY, \ + tsp.NAME VALUE \ + FROM MEDIAN.TIMESERIESPOINT tsp, \ + MEDIAN.MEASUREMENT mmt \ + WHERE tsp.FEATUREID = mmt.FEATUREID AND \ + mmt.SOURCEID = ? \ + order by tsp.name + +timeseries_timeseriespoint_with_area=SELECT \ + MEDIAN.TIMESERIESPOINT.FEATUREID KEY, \ + MEDIAN.TIMESERIESPOINT.NAME VALUE \ + FROM MEDIAN.TIMESERIESPOINT, \ + MEDIAN.MEASUREMENT MMT \ + WHERE MEDIAN.TIMESERIESPOINT.FEATUREID = MMT.FEATUREID AND \ + MMT.SOURCEID = ? AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + )\ + ORDER BY MEDIAN.TIMESERIESPOINT.NAME + +timeseries_timeseriespoint_with_wkt=SELECT \ + MEDIAN.TIMESERIESPOINT.FEATUREID KEY, \ + MEDIAN.TIMESERIESPOINT.NAME VALUE \ + FROM MEDIAN.TIMESERIESPOINT, \ + MEDIAN.MEASUREMENT MMT \ + WHERE MEDIAN.TIMESERIESPOINT.FEATUREID = MMT.FEATUREID AND \ + MMT.SOURCEID = ? AND \ + INTERSECTS(SHAPE,"?")\ + ORDER BY MEDIAN.TIMESERIESPOINT.NAME + +timeseries_parameter=SELECT DISTINCT \ + p.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + FROM MEDIAN.PARAMETER P, \ + MEDIAN.TIMESERIES TS, \ + MEDIAN.TIMESERIESVALUE TSV, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.TIMESERIESPOINT TSP \ + WHERE M.FEATUREID = TSP.FEATUREID AND \ + M.MEASUREMENTID = TSV.MEASUREMENTID AND \ + TS.TIMESERIESID = TSV.TIMESERIESID AND \ + P.PARAMETERID = TS.PARAMETERID AND \ + TSP.FEATUREID = ? \ + ORDER BY P.GERMANNAME + +timeseries_depth_height=SELECT DISTINCT \ + M.MEASUREMENTID KEY, \ + M.ZLOCATION VALUE, \ + P.PARAMETERID PARAMETERID \ + FROM MEDIAN.MEASUREMENT M, \ + MEDIAN.TIMESERIESVALUE TSV, \ + MEDIAN.TIMESERIES T, \ + MEDIAN.PARAMETER P \ + WHERE M.MEASUREMENTID = TSV.MEASUREMENTID AND \ + TSV.TIMESERIESID = T.TIMESERIESID AND \ + T.PARAMETERID = P.PARAMETERID AND \ + M.FEATUREID = ? AND \ + P.PARAMETERID IN (?)\ + ORDER BY m.ZLOCATION DESC + +timeseries_interval=select min(tv.TIMEVALUE) MIN, \ + max(tv.TIMEVALUE) MAX \ + from MEDIAN.TIMESERIES t, \ + MEDIAN.TIMESERIESVALUE tv \ + where tv.TIMESERIESID = t.TIMESERIESID AND \ + t.PARAMETERID IN ( ? ) AND \ + tv.MEASUREMENTID IN ( ? ) + +timeseries_chart_data=SELECT tv.TIMEVALUE XORDINATE, \ + tv.DATAVALUE YORDINATE, \ + t.PARAMETERID GROUP1, \ + tv.MEASUREMENTID GROUP2, \ + tv.TIMESERIESID GROUP3, \ + t.TIMEINTERVAL GAPID \ + FROM MEDIAN.TIMESERIESVALUE tv, \ + MEDIAN.TIMESERIES t \ + WHERE tv.TIMESERIESID = t.TIMESERIESID AND \ + t.PARAMETERID IN ( ? ) AND \ + tv.MEASUREMENTID IN ( ? ) AND \ + tv.TIMEVALUE >= ? AND \ + tv.TIMEVALUE <= ? \ + ORDER BY tv.MEASUREMENTID, \ + tv.TIMESERIESID, \ + t.PARAMETERID, \ + tv.TIMEVALUE + +timeseries_odv_data = SELECT SI.NAME CRUISE, \ + MEDIAN.TIMESERIESPOINT.NAME STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (M.ZLOCATION *-1) DEPTH, \ + TSV.TIMEVALUE, \ + TSV.DATAVALUE, \ + TS.PARAMETERID PARAMETER, \ + TSV.MEASUREMENTID, \ + TSV.TIMESERIESID, \ + '1' QF \ + FROM MEDIAN.TIMESERIESPOINT, \ + MEDIAN.TIMESERIESVALUE TSV, \ + MEDIAN.TIMESERIES TS, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.SOURCEINFO SI \ + WHERE SI.SOURCEID = M.SOURCEID AND \ + M.FEATUREID = MEDIAN.TIMESERIESPOINT.FEATUREID AND \ + M.MEASUREMENTID = TSV.MEASUREMENTID AND \ + TSV.TIMESERIESID = TS.TIMESERIESID AND \ + TS.PARAMETERID IN ( ? ) AND \ + TSV.MEASUREMENTID IN ( ? ) AND \ + TSV.TIMEVALUE >= ? AND \ + TSV.TIMEVALUE <= ? \ + ORDER BY TS.PARAMETERID, \ + TSV.MEASUREMENTID, \ + TSV.TIMESERIESID, \ + TSV.TIMEVALUE + + +############################################# +############################################# +########## Zeitserie Mesh ############## +############################################# +############################################# + +timeseries_mesh = SELECT OBJECTID KEY, \ + m.NAME VALUE \ + FROM MEDIAN.MESH m \ + WHERE SOURCEID IN (?) \ + ORDER BY m.NAME +timeseries_meshpoint = SELECT MEDIAN.MESHPOINT.FEATUREID, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.MESHPOINT, \ + MEDIAN.MESH M \ + WHERE MEDIAN.MESHPOINT.MESHID = M.MESHID AND \ + KPOSITION = 1 AND \ + M.OBJECTID = ? AND \ + INTERSECTS(SHAPE,"?") + +timeseries_meshpoint_depth = SELECT MP.FEATUREID KEY, \ + 'Layer ' || ML.KPOSITION || ': ' || -ML.UPPERZLOCATION || ' - '|| -ML.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT MP, \ + MEDIAN.MESH M \ + WHERE ML.KPOSITION = MP.KPOSITION AND \ + ML.MESHID = MP.MESHID AND \ + M.OBJECTID = ? AND \ + MP.MESHID = M.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) AND \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) \ + ORDER BY ML.UPPERZLOCATION DESC + +timeseries_mesh_parameter=SELECT distinct \ + p.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + from MEDIAN.PARAMETER p, \ + MEDIAN.MESHSCALARVALUE msc, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msc.PARTID >= m.PARTIDMIN AND \ + msc.PARTID <= m.PARTIDMAX AND \ + msc.PARAMETERID = p.PARAMETERID \ + order by p.GERMANNAME +timeseries_mesh_interval=select /*+ parallel(TIMEVALUE,5) */ \ + min(TIMEVALUE) MIN, \ + max(TIMEVALUE) MAX \ + from MEDIAN.MESHSCALARVALUE msc, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msc.PARTID >= m.PARTIDMIN AND \ + msc.PARTID <= m.PARTIDMAX AND \ + msc.PARAMETERID IN (?) + +timeseries_mesh_chart_data=select /*+ parallel(timevalue,10) */ \ + msv.TIMEVALUE XORDINATE, \ + msv.DATAVALUE YORDINATE, \ + msv.PARAMETERID GROUP1, \ + msv.FEATUREID GROUP2, \ + mp.FEATUREID GROUP3, \ + -1 GAPID \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where (m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX ) AND \ + msv.FEATUREID = mp.FEATUREID AND \ + msv.PARAMETERID in ( ? ) AND \ + mp.FEATUREID in ( ? ) AND \ + msv.TIMEVALUE >= ? AND \ + msv.TIMEVALUE <= ? \ + order by mp.FEATUREID, \ + msv.FEATUREID, \ + msv.PARAMETERID, \ + msv.TIMEVALUE + +timeseries_mesh_odv_data = select /*+ parallel(timevalue,10) */ \ + SI.NAME CRUISE, \ + m.MESHID || '-' || MEDIAN.MESHPOINT.IPOSITION || '-' || MEDIAN.MESHPOINT.JPOSITION STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (((ML.UPPERZLOCATION + ML.LOWERZLOCATION) / 2)*-1) DEPTH, \ + msv.TIMEVALUE, \ + msv.DATAVALUE, \ + msv.PARAMETERID PARAMETER, \ + '1' QF \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.SOURCEINFO SI, \ + MEDIAN.MESHLAYER ML \ + where (m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX ) AND \ + m.SOURCEID = SI.SOURCEID AND \ + ML.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + ML.KPOSITION = MEDIAN.MESHPOINT.KPOSITION AND \ + msv.FEATUREID = MEDIAN.MESHPOINT.FEATUREID AND \ + msv.PARAMETERID in (? ) AND \ + MEDIAN.MESHPOINT.FEATUREID in ( ? ) AND \ + msv.TIMEVALUE >= ? AND \ + msv.TIMEVALUE <= ? \ + order by MEDIAN.MESHPOINT.FEATUREID, \ + msv.FEATUREID, \ + msv.TIMEVALUE, \ + msv.PARAMETERID + + +############################################# +############################################# +########## Vertikalprofil ############## +############################################# +############################################# + +verticalprofile_point=SELECT DISTINCT \ + tsp.FEATUREID KEY, \ + tsp.NAME VALUE \ + FROM MEDIAN.TIMESERIESPOINT tsp, \ + MEDIAN.MEASUREMENT mmt \ + WHERE tsp.FEATUREID = mmt.FEATUREID AND \ + mmt.SOURCEID = ? \ + order by tsp.name + +verticalprofile_parameter=SELECT DISTINCT \ + p.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + from MEDIAN.PARAMETER p, \ + MEDIAN.TIMESERIES ts, \ + MEDIAN.TIMESERIESVALUE tsv, \ + MEDIAN.MEASUREMENT m \ + where ts.PARAMETERID = p.PARAMETERID and \ + ts.TIMESERIESID = tsv.TIMESERIESID and \ + m.MEASUREMENTID = tsv.MEASUREMENTID and \ + m.FEATUREID = ? \ + ORDER BY p.GERMANNAME + +verticalprofile_minmaxdepth= SELECT min(M.ZLOCATION) MIN, \ + max(M.ZLOCATION) MAX \ + FROM MEDIAN.MEASUREMENT M, \ + MEDIAN.TIMESERIES TS, \ + MEDIAN.TIMESERIESVALUE TSV \ + WHERE TS.TIMESERIESID = TSV.TIMESERIESID and \ + M.MEASUREMENTID = TSV.MEASUREMENTID and \ + M.FEATUREID = ? and \ + TS.PARAMETERID IN ( ? ) + + +verticalprofile_year=select distinct \ + to_char(tsv.TIMEVALUE,'YYYY') KEY, \ + to_char(tsv.TIMEVALUE,'YYYY') VALUE \ + from MEDIAN.TIMESERIES ts, \ + MEDIAN.TIMESERIESVALUE tsv, \ + MEDIAN.MEASUREMENT m \ + where ts.TIMESERIESID = tsv.TIMESERIESID and \ + m.MEASUREMENTID = tsv.MEASUREMENTID and \ + m.FEATUREID = ? and \ + ts.PARAMETERID IN ( ? ) \ + order by to_char(tsv.TIMEVALUE,'YYYY') + +verticalprofile_date=select distinct \ + tsv.TIMEVALUE KEY, \ + tsv.TIMEVALUE VALUE \ + from MEDIAN.TIMESERIES ts, \ + MEDIAN.TIMESERIESVALUE tsv, \ + MEDIAN.MEASUREMENT m \ + where ts.TIMESERIESID = tsv.TIMESERIESID and \ + m.MEASUREMENTID = tsv.MEASUREMENTID and \ + m.FEATUREID = ? and \ + ts.PARAMETERID IN ( ? ) and \ + to_char(tsv.TIMEVALUE,'YYYY') IN (?) \ + order by tsv.TIMEVALUE + +verticalprofile_chart_data= SELECT M.ZLOCATION XORDINATE, \ + TSV.DATAVALUE YORDINATE, \ + TS.PARAMETERID GROUP1, \ + TSV.TIMEVALUE GROUP2, \ + 1 GROUP3, \ + 1 DATAID, \ + M.FEATUREID, \ + TS.TIMESERIESID \ + from MEDIAN.TIMESERIES TS, \ + MEDIAN.TIMESERIESVALUE TSV, \ + MEDIAN.MEASUREMENT M \ + where TS.TIMESERIESID = TSV.TIMESERIESID AND \ + M.MEASUREMENTID = TSV.MEASUREMENTID AND \ + M.FEATUREID = ? AND \ + TS.PARAMETERID IN ( ? ) AND \ + TSV.TIMEVALUE IN (?) AND \ + M.ZLOCATION >= ? AND \ + M.ZLOCATION <= ? \ + ORDER BY TSV.TIMEVALUE, \ + TSV.TIMESERIESID, \ + TS.PARAMETERID, \ + TSV.TIMEVALUE + +verticalprofile_odv_data = SELECT SI.NAME CRUISE, \ + MEDIAN.TIMESERIESPOINT.NAME STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (M.ZLOCATION *-1) DEPTH, \ + TSV.TIMEVALUE, \ + TSV.DATAVALUE, \ + TS.PARAMETERID PARAMETER, \ + TSV.MEASUREMENTID, \ + TSV.TIMESERIESID, \ + '1' QF \ + FROM MEDIAN.TIMESERIESPOINT, \ + MEDIAN.TIMESERIESVALUE TSV, \ + MEDIAN.TIMESERIES TS, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.SOURCEINFO SI \ + WHERE SI.SOURCEID = M.SOURCEID AND \ + M.FEATUREID = MEDIAN.TIMESERIESPOINT.FEATUREID AND \ + M.MEASUREMENTID = TSV.MEASUREMENTID AND \ + TSV.TIMESERIESID = TS.TIMESERIESID AND \ + M.FEATUREID = ? AND \ + TS.PARAMETERID IN ( ? ) AND \ + TSV.TIMEVALUE IN (?) AND \ + M.ZLOCATION >= ? AND \ + M.ZLOCATION <= ? \ + ORDER BY TSV.MEASUREMENTID, \ + TSV.TIMESERIESID, \ + TSV.TIMEVALUE, \ + TS.PARAMETERID + + +############################################# +############################################# +########## Vertikalprofil Mesh ############## +############################################# +############################################# + +verticalprofile_mesh = SELECT OBJECTID KEY, \ + m.NAME VALUE \ + FROM MEDIAN.MESH m \ + WHERE SOURCEID IN (?) \ + order by m.NAME + +verticalprofile_mesh_with_area = SELECT M.OBJECTID KEY, \ + M.NAME VALUE \ + FROM MEDIAN.MESHPOINT, \ + MEDIAN.MESH M \ + WHERE M.SOURCEID IN (?) AND \ + M.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + order by M.NAME + +verticalprofile_mesh_with_wkt = SELECT M.OBJECTID KEY, \ + M.NAME VALUE \ + FROM MEDIAN.MESHPOINT, \ + MEDIAN.MESH M \ + WHERE M.SOURCEID IN (?) AND \ + M.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + INTERSECTS(SHAPE, "?") \ + order by M.NAME + +verticalprofile_mesh_point = SELECT FEATUREID, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.MESHPOINT \ + WHERE MESHID in \ + (SELECT DISTINCT MESHID \ + FROM MEDIAN.MESH \ + WHERE OBJECTID = ?) AND \ + KPOSITION = 1 AND \ + INTERSECTS(SHAPE,"?") + +verticalprofile_mesh_mindepth = SELECT MP.KPOSITION KEY, \ + 'Layer ' || ML.KPOSITION || ': ' || -ML.UPPERZLOCATION || ' - '|| -ML.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT MP, \ + MEDIAN.MESH M \ + WHERE ML.KPOSITION = MP.KPOSITION AND \ + ML.MESHID = MP.MESHID AND \ + M.OBJECTID = ? AND \ + MP.MESHID = M.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) AND \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) \ + ORDER BY ML.UPPERZLOCATION DESC + +verticalprofile_mesh_maxdepth = SELECT MP.KPOSITION KEY, \ + 'Layer ' || ML.KPOSITION || ': ' || -ML.UPPERZLOCATION || ' - '|| -ML.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT MP, \ + MEDIAN.MESH M \ + WHERE ML.KPOSITION = MP.KPOSITION AND \ + ML.MESHID = MP.MESHID AND \ + M.OBJECTID = ? AND \ + MP.MESHID = M.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) AND \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) AND \ + MP.KPOSITION < ? \ + ORDER BY ML.UPPERZLOCATION DESC + +verticalprofile_mesh_parameter=SELECT distinct \ + p.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + from MEDIAN.PARAMETER p, \ + MEDIAN.MESHSCALARVALUE msc, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msc.PARTID >= m.PARTIDMIN AND \ + msc.PARTID <= m.PARTIDMAX AND \ + msc.PARAMETERID = p.PARAMETERID \ + order by p.GERMANNAME + +verticalprofile_mesh_year= select distinct \ + to_char(msv.TIMEVALUE,'YYYY') KEY, \ + to_char(msv.TIMEVALUE,'YYYY') VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID in (?) \ + order by to_char(msv.TIMEVALUE, 'YYYY') + +verticalprofile_mesh_date= select distinct \ + msv.TIMEVALUE KEY, \ + msv.TIMEVALUE VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID in (?) AND \ + to_char(msv.TIMEVALUE,'YYYY') in (?) \ + order by msv.TIMEVALUE + +verticalprofile_mesh_chart_data=select ml.UPPERZLOCATION XORDINATE, \ + msv.DATAVALUE YORDINATE, \ + mp.KPOSITION KPOSITION, \ + msv.PARAMETERID GROUP1, \ + msv.TIMEVALUE GROUP2, \ + 1 GROUP3, \ + 2 DATAID, \ + MP.FEATUREID, \ + MP.MESHID \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = mp. FEATUREID AND \ + ml.KPOSITION = mp.KPOSITION and \ + ml.MESHID = mp.MESHID and \ + m.MESHID = mp.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (?) AND \ + msv.TIMEVALUE in (?) AND \ + m.OBJECTID = ? AND \ + mp.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) and \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?)) AND \ + mp.KPOSITION <= ? AND \ + mp.KPOSITION >= ? \ + order by msv.PARAMETERID, \ + msv.TIMEVALUE, \ + ml.UPPERZLOCATION + +verticalprofile_mesh_odv_data=select SI.NAME CRUISE, \ + m.MESHID || '-' || MEDIAN.MESHPOINT.IPOSITION || '-' || MEDIAN.MESHPOINT.JPOSITION STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (((ML.UPPERZLOCATION + ML.LOWERZLOCATION) / 2)*-1) DEPTH, \ + msv.DATAVALUE, \ + msv.PARAMETERID PARAMETER, \ + msv.TIMEVALUE , \ + '1' QF \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.SOURCEINFO SI \ + where m.SOURCEID = SI.SOURCEID AND \ + msv.FEATUREID = MEDIAN.MESHPOINT. FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (?) AND \ + msv.TIMEVALUE in (?) AND \ + m.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) and \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?)) AND \ + MEDIAN.MESHPOINT.KPOSITION <= ? AND \ + MEDIAN.MESHPOINT.KPOSITION >= ? \ + order by msv.TIMEVALUE, \ + ml.UPPERZLOCATION, \ + msv.PARAMETERID + +############################################# +############################################# +##### Vertikalprofil InstantaneousPoint ##### +############################################# +############################################# + +verticalprofile_instantaneouspoint_series = SELECT DISTINCT \ + S.SERIESID KEY, \ + S.DESCRIPTION VALUE \ + FROM MEDIAN.SERIES S, \ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.MEASUREMENT M \ + WHERE S.SERIESID = I.SERIESID AND \ + I.POINTSPEC = 4 AND \ + I.FEATUREID = M.FEATUREID AND \ + M.SOURCEID= ? \ + ORDER BY S.DESCRIPTION + +verticalprofile_instantaneouspoint_series_with_area = SELECT \ + S.SERIESID KEY, \ + S.DESCRIPTION VALUE \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.SERIES S, \ + MEDIAN.MEASUREMENT M \ + WHERE S.SERIESID = MEDIAN.INSTANTANEOUSPOINT.SERIESID AND \ + MEDIAN.INSTANTANEOUSPOINT.POINTSPEC = 4 AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.SOURCEID= ? AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + ORDER BY S.DESCRIPTION +verticalprofile_instantaneouspoint_series_with_wkt = SELECT \ + S.SERIESID KEY, \ + S.DESCRIPTION VALUE \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.SERIES S, \ + MEDIAN.MEASUREMENT M \ + WHERE S.SERIESID = MEDIAN.INSTANTANEOUSPOINT.SERIESID AND \ + MEDIAN.INSTANTANEOUSPOINT.POINTSPEC = 4 AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.SOURCEID= ? AND \ + INTERSECTS(SHAPE, "?") \ + ORDER BY S.DESCRIPTION + +verticalprofile_instantaneouspoint_point = SELECT \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + to_char(MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE,'DD.MM.YYYY HH24:MI') VALUE, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M \ + WHERE MEDIAN.INSTANTANEOUSPOINT.SERIESID = ? AND \ + MEDIAN.INSTANTANEOUSPOINT.POINTSPEC = 4 AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.SOURCEID = ? \ + ORDER BY MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE + +verticalprofile_instantaneouspoint_point_with_aera = SELECT \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + to_char(MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE,'DD.MM.YYYY HH24:MI') VALUE, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M \ + WHERE MEDIAN.INSTANTANEOUSPOINT.SERIESID = ? AND \ + MEDIAN.INSTANTANEOUSPOINT.POINTSPEC = 4 AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.SOURCEID = ? AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + ORDER BY MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE + +verticalprofile_instantaneouspoint_point_with_wkt = SELECT \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + to_char(MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE,'DD.MM.YYYY HH24:MI') VALUE, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE, \ + ST_ASTEXT(SHAPE) \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M \ + WHERE MEDIAN.INSTANTANEOUSPOINT.SERIESID = ? AND \ + MEDIAN.INSTANTANEOUSPOINT.POINTSPEC = 4 AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.SOURCEID = ? AND \ + INTERSECTS(SHAPE,"?") \ + ORDER BY MEDIAN.INSTANTANEOUSPOINT.FEATUREID, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE + +verticalprofile_instantaneouspoint_parameter = SELECT DISTINCT \ + P.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + FROM MEDIAN.PARAMETER P, \ + MEDIAN.INSTANTANEOUSPOINT IP, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE IP.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + MSV.PARAMETERID = P.PARAMETERID AND \ + IP.FEATUREID = ? \ + ORDER BY P.GERMANNAME + +verticalprofile_instantaneouspoint_minmaxdepth = SELECT min(M.ZLOCATION) MIN, \ + max(M.ZLOCATION) MAX \ + FROM MEDIAN.INSTANTANEOUSPOINT IP, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE IP.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + IP.FEATUREID = ? AND \ + MSV.PARAMETERID in (?) + +verticalprofile_instantaneouspoint_chart_data = SELECT M.ZLOCATION XORDINATE, \ + MSV.DATAVALUE YORDINATE, \ + MSV.PARAMETERID GROUP1, \ + IP.TIMEVALUE GROUP2, \ + 1 GROUP3, \ + 3 DATAID, \ + IP.FEATUREID, \ + IP.SERIESID \ + FROM MEDIAN.INSTANTANEOUSPOINT IP, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE IP.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + IP.FEATUREID = ? AND \ + MSV.PARAMETERID in (?) AND \ + M.ZLOCATION >= ? AND \ + M.ZLOCATION <= ? \ + ORDER BY IP.TIMEVALUE, \ + MSV.PARAMETERID, \ + M.ZLOCATION + +verticalprofile_instantaneouspoint_odv_data = SELECT S.DESCRIPTION CRUISE, \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (M.ZLOCATION * -1) DEPTH, \ + MSV.DATAVALUE, \ + MSV.PARAMETERID PARAMETER, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE , \ + '1' QF \ + FROM MEDIAN.SERIES S, \ + MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE S.SERIESID = MEDIAN.INSTANTANEOUSPOINT.SERIESID AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = ? AND \ + MSV.PARAMETERID in (?) AND \ + M.ZLOCATION >= ? AND \ + M.ZLOCATION <= ? \ + ORDER BY MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE, \ + M.ZLOCATION, \ + MSV.PARAMETERID + +############################################# +############################################# +#### Horizontalprofil InstantaneousPoint #### +############################################# +############################################# +horizontalprofile_instantaneouspoint_vehicle = SELECT DISTINCT \ + V.VEHICLEID KEY, \ + V.NAME VALUE \ + FROM MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C, \ + MEDIAN.TRACK T, \ + MEDIAN.SURVEYINFO S, \ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.MEASUREMENT M \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = T.CRUISEID AND \ + T.TRACKID = S.TRACKID AND \ + S.SURVEYID = I.SURVEYID AND \ + I.FEATUREID = M.FEATUREID AND \ + M.SOURCEID = ? \ + ORDER BY V.NAME + +horizontalprofile_instantaneouspoint_vehicle_with_area = SELECT V.VEHICLEID KEY, \ + V.NAME VALUE \ + FROM MEDIAN.TRACK, \ + MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = MEDIAN.TRACK.CRUISEID AND \ + MEDIAN.TRACK.TRACKID IN \ + (SELECT DISTINCT S.TRACKID \ + FROM MEDIAN.MEASUREMENT M ,\ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.SURVEYINFO S \ + WHERE M.SOURCEID = ? AND \ + I.FEATUREID = M.FEATUREID AND \ + S.SURVEYID = I.SURVEYID)AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + ORDER BY V.NAME + +horizontalprofile_instantaneouspoint_vehicle_with_wkt = SELECT V.VEHICLEID KEY, \ + V.NAME VALUE \ + FROM MEDIAN.TRACK, \ + MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = MEDIAN.TRACK.CRUISEID AND \ + MEDIAN.TRACK.TRACKID IN \ + (SELECT DISTINCT S.TRACKID \ + FROM MEDIAN.MEASUREMENT M ,\ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.SURVEYINFO S \ + WHERE M.SOURCEID = ? AND \ + I.FEATUREID = M.FEATUREID AND \ + S.SURVEYID = I.SURVEYID)AND \ + INTERSECTS(SHAPE,"?") \ + ORDER BY V.NAME + +horizontalprofile_instantaneouspoint_cruise = SELECT DISTINCT \ + C.CRUISEID KEY, \ + V.NAME || ' ' || \ + C.NAME || ' ' || \ + TO_CHAR(C.STARTDATE,'DD.MM.YYYY') || ' - ' || \ + TO_CHAR(C.ENDDATE,'DD.MM.YYYY') VALUE, \ + V.NAME, \ + C.NAME \ + FROM MEDIAN.CRUISE C, \ + MEDIAN.VEHICLE V, \ + MEDIAN.TRACK T, \ + MEDIAN.SURVEYINFO S, \ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.MEASUREMENT M \ + WHERE C.VEHICLEID = V.VEHICLEID AND \ + C.CRUISEID = T.CRUISEID AND \ + T.TRACKID = S.TRACKID AND \ + S.SURVEYID = I.SURVEYID AND \ + I.FEATUREID = M.FEATUREID AND \ + C.VEHICLEID = ? AND \ + M.SOURCEID = ? \ + ORDER BY V.NAME, C.NAME + +horizontalprofile_instantaneouspoint_cruise_with_area = SELECT C.CRUISEID KEY, \ + V.NAME || ' ' || \ + C.NAME || ' ' || \ + TO_CHAR(C.STARTDATE,'DD.MM.YYYY') || ' - ' || \ + TO_CHAR(C.ENDDATE,'DD.MM.YYYY') VALUE, \ + V.NAME, \ + C.NAME \ + FROM MEDIAN.TRACK, \ + MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = MEDIAN.TRACK.CRUISEID AND \ + MEDIAN.TRACK.TRACKID IN \ + (SELECT DISTINCT S.TRACKID \ + FROM MEDIAN.MEASUREMENT M ,\ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.SURVEYINFO S \ + WHERE M.SOURCEID = ? AND \ + C.VEHICLEID = ? AND \ + I.FEATUREID = M.FEATUREID AND \ + S.SURVEYID = I.SURVEYID)AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + ORDER BY V.NAME + +horizontalprofile_instantaneouspoint_cruise_with_wkt = SELECT C.CRUISEID KEY, \ + V.NAME || ' ' || \ + C.NAME || ' ' || \ + TO_CHAR(C.STARTDATE,'DD.MM.YYYY') || ' - ' || \ + TO_CHAR(C.ENDDATE,'DD.MM.YYYY') VALUE, \ + V.NAME, \ + C.NAME \ + FROM MEDIAN.TRACK, \ + MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = MEDIAN.TRACK.CRUISEID AND \ + MEDIAN.TRACK.TRACKID IN \ + (SELECT DISTINCT S.TRACKID \ + FROM MEDIAN.MEASUREMENT M ,\ + MEDIAN.INSTANTANEOUSPOINT I, \ + MEDIAN.SURVEYINFO S \ + WHERE M.SOURCEID = ? AND \ + C.VEHICLEID = ? AND \ + I.FEATUREID = M.FEATUREID AND \ + S.SURVEYID = I.SURVEYID)AND \ + INTERSECTS(SHAPE,"?") \ + ORDER BY V.NAME + +horizontalprofile_instantaneouspoint_track= SELECT \ + T.TRACKID KEY, \ + to_char(T.STARTDATE,'DD.MM.YYYY HH24:MI') || ' - '|| to_char(T.ENDDATE,'DD.MM.YYYY HH24:MI') || ' - '|| T.NAME VALUE \ + FROM MEDIAN.TRACK T \ + WHERE T.CRUISEID = ? \ + ORDER BY T.STARTDATE, \ + T.ENDDATE, \ + T.NAME + +horizontalprofile_instantaneouspoint_track_with_area = SELECT \ + MEDIAN.TRACK.TRACKID KEY, \ + to_char(STARTDATE,'DD-MM-YYYY HH24:MI') || ' - '|| to_char(ENDDATE,'DD-MM-YYYY HH24:MI') || ' - '|| NAME VALUE, \ + NAME \ + FROM MEDIAN.TRACK \ + WHERE MEDIAN.TRACK.CRUISEID = ? AND \ + INTERSECTS(SHAPE, \ + (SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? )\ + ) \ + ORDER BY STARTDATE, \ + ENDDATE, \ + NAME + +horizontalprofile_instantaneouspoint_track_with_wkt = SELECT \ + MEDIAN.TRACK.TRACKID KEY, \ + to_char(STARTDATE,'DD-MM-YYYY HH24:MI') || ' - '|| to_char(ENDDATE,'DD-MM-YYYY HH24:MI') || ' - '|| NAME VALUE, \ + NAME \ + FROM MEDIAN.TRACK \ + WHERE MEDIAN.TRACK.CRUISEID = ? AND \ + INTERSECTS(SHAPE, "?") \ + ORDER BY STARTDATE, \ + ENDDATE, \ + NAME + +horizontalprofile_instantaneouspoint_surveyinfo = SELECT \ + SURVEYID KEY, \ + to_char(STARTDATE,'DD.MM.YYYY HH24:MI') || ' - '|| to_char(ENDDATE,'DD.MM.YYYY HH24:MI') || ' - '|| DESCRIPTION VALUE \ + FROM MEDIAN.SURVEYINFO \ + WHERE TRACKID = ? \ + ORDER BY STARTDATE, \ + ENDDATE, \ + DESCRIPTION +horizontalprofile_instantaneouspoint_parameter = SELECT DISTINCT \ + P.PARAMETERID KEY, \ + p.GERMANNAME || ' ['|| p.UNIT ||']' VALUE, \ + p.GERMANNAME \ + FROM MEDIAN.PARAMETER P, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.INSTANTANEOUSPOINT IP, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE P.PARAMETERID = MSV.PARAMETERID AND \ + MSV.MEASUREMENTID = M.MEASUREMENTID AND \ + M.FEATUREID = IP.FEATUREID AND \ + IP.SURVEYID = ? \ + ORDER BY P.GERMANNAME +horizontalprofile_instantaneouspoint_depth = SELECT DISTINCT \ + M.ZLOCATION KEY, \ + M.ZLOCATION VALUE \ + FROM MEDIAN.MEASUREMENT M, \ + MEDIAN.INSTANTANEOUSPOINT IP \ + WHERE M.FEATUREID = IP.FEATUREID AND \ + IP.SURVEYID = ? \ + ORDER BY M.ZLOCATION +horizontalprofile_instantaneouspoint_chart_data = SELECT ST_ASTEXT(SHAPE), \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE TIME, \ + MSV.DATAVALUE YORDINATE, \ + MSV.PARAMETERID GROUP1, \ + ZLOCATION GROUP2, \ + 1 GROUP3, \ + 3 DATAID, \ + MEDIAN.INSTANTANEOUSPOINT.SURVEYID \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + MEDIAN.INSTANTANEOUSPOINT.SURVEYID = ? AND \ + M.ZLOCATION IN (?) AND \ + MSV.PARAMETERID in (?) \ + ORDER BY MSV.PARAMETERID, \ + M.ZLOCATION, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE +horizontalprofile_instantaneouspoint_odv_data = SELECT V.NAME || ' ' || C.NAME CRUISE, \ + MEDIAN.InstantaneousPoint.FEATUREID STATION, \ + '*' TYPE, \ + 0 BOTDEPTH, \ + (M.ZLOCATION * -1) DEPTH, \ + ST_ASTEXT(SHAPE), \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE, \ + MSV.DATAVALUE, \ + MSV.PARAMETERID PARAMETER , \ + '1' QF \ + FROM MEDIAN.INSTANTANEOUSPOINT, \ + MEDIAN.VEHICLE V, \ + MEDIAN.CRUISE C, \ + (SELECT TRACKID,CRUISEID FROM MEDIAN.TRACK) T, \ + MEDIAN.SURVEYINFO S, \ + MEDIAN.MEASUREMENT M, \ + MEDIAN.MEASUREDSCALARVALUE MSV \ + WHERE V.VEHICLEID = C.VEHICLEID AND \ + C.CRUISEID = T.CRUISEID AND \ + T.TRACKID = S.TRACKID AND \ + S.SURVEYID = MEDIAN.INSTANTANEOUSPOINT.SURVEYID AND \ + MEDIAN.INSTANTANEOUSPOINT.FEATUREID = M.FEATUREID AND \ + M.MEASUREMENTID = MSV.MEASUREMENTID AND \ + MEDIAN.INSTANTANEOUSPOINT.SURVEYID = ? AND \ + M.ZLOCATION IN (?) AND \ + MSV.PARAMETERID in (?) \ + ORDER BY MSV.PARAMETERID, \ + M.ZLOCATION, \ + MEDIAN.INSTANTANEOUSPOINT.TIMEVALUE + +############################################# +############################################# +########### Horizontalprofil MESH ########### +############################################# +############################################# +horizontalprofile_meshpoint_depth = SELECT DISTINCT \ + mp.KPOSITION KEY, \ + 'Layer ' || ml.KPOSITION || ': ' || -ml.UPPERZLOCATION || ' - '|| -ml.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT mp \ + where ml.KPOSITION = mp.KPOSITION and \ + ml.MESHID = mp.MESHID and \ + mp.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + IPOSITION = (select IPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?) and \ + JPOSITION = (select JPOSITION from MEDIAN.MESHPOINT where FEATUREID = ?)) \ + order by mp.KPOSITION + +horizontalprofile_mesh_chart_data = SELECT ST_ASTEXT(SHAPE), \ + msv.DATAVALUE YORDINATE, \ + msv.PARAMETERID GROUP1, \ + MEDIAN.MESHPOINT.KPOSITION GROUP2, \ + msv.TIMEVALUE GROUP3, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + 2 DATAID, \ + MEDIAN.MESHPOINT.MESHID \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = MEDIAN.MESHPOINT. FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (?) AND \ + msv.TIMEVALUE in (?) AND \ + m.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + KPOSITION in ( ? ) and \ + ? = (select ? from MEDIAN.MESHPOINT where FEATUREID = ?)) \ + order by msv.TIMEVALUE, \ + MEDIAN.MESHPOINT.KPOSITION, \ + msv.PARAMETERID, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION + +horizontalprofile_mesh_odv_data = SELECT SI.NAME CRUISE, \ + m.MESHID || '-' || MEDIAN.MESHPOINT.IPOSITION || '-' || MEDIAN.MESHPOINT.JPOSITION STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (((ML.UPPERZLOCATION + ML.LOWERZLOCATION) / 2)*-1) DEPTH, \ + msv.DATAVALUE, \ + msv.PARAMETERID PARAMETER, \ + msv.TIMEVALUE, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION , \ + '1' QF \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.SOURCEINFO SI \ + where msv.FEATUREID = MEDIAN.MESHPOINT. FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.SOURCEID = SI.SOURCEID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (?) AND \ + msv.TIMEVALUE in (?) AND \ + m.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + KPOSITION in ( ? ) and \ + ? = (select ? from MEDIAN.MESHPOINT where FEATUREID = ?)) \ + order by msv.TIMEVALUE, \ + MEDIAN.MESHPOINT.KPOSITION, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + msv.PARAMETERID + +############################################# +############################################# +########### Horizontalprofil MESH ########### +########### Schnittprofil ########### +############################################# +############################################# +horizontalprofile_meshpoint_depth = SELECT DISTINCT \ + mp.KPOSITION KEY, \ + 'Layer ' || ml.KPOSITION || ': ' || -ml.UPPERZLOCATION || ' - '|| -ml.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT mp \ + where ml.KPOSITION = mp.KPOSITION and \ + ml.MESHID = mp.MESHID and \ + mp.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID )\ + order by mp.KPOSITION + +horizontalprofile_meshpoint_cross_ij=SELECT MEDIAN.MESHFACE.JPOSITION, \ + MEDIAN.MESHFACE.IPOSITION \ + FROM MEDIAN.MESHFACE, \ + MEDIAN.MESH M \ + WHERE MEDIAN.MESHFACE.KPOSITION = 1 AND \ + M.MESHID = MEDIAN.MESHFACE.MESHID AND \ + M.OBJECTID = ? AND \ + INTERSECTS(SHAPE, "?") +horizontalprofile_mesh_cross_chart_data = SELECT ST_ASTEXT(SHAPE), \ + msv.DATAVALUE YORDINATE, \ + msv.PARAMETERID GROUP1, \ + MEDIAN.MESHPOINT.KPOSITION GROUP2, \ + msv.TIMEVALUE GROUP3, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + 2 DATAID \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = MEDIAN.MESHPOINT.FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID in (?) AND \ + msv.TIMEVALUE in (?) AND \ + m.OBJECTID = ? AND \ + ml.KPOSITION in (?) AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( \ + SELECT distinct FEATUREID \ + FROM MEDIAN.MESHPOINT \ + WHERE ? \ + ) \ + order by msv.TIMEVALUE, \ + MEDIAN.MESHPOINT.KPOSITION, \ + msv.PARAMETERID, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION +############################################# +############################################# +############# Profilschnitt MESH ############ +############################################# +############################################# +verticalcrosssection_mesh_year = select distinct \ + to_char(msv.TIMEVALUE,'YYYY') KEY, \ + to_char(msv.TIMEVALUE,'YYYY') VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID = ? \ + order by to_char(msv.TIMEVALUE,'YYYY') +verticalcrosssection_mesh_date = select distinct \ + msv.TIMEVALUE KEY, \ + msv.TIMEVALUE VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID = ? AND \ + to_char(msv.TIMEVALUE,'YYYY') in (?) \ + order by msv.TIMEVALUE +verticalcrosssection_mesh_chart_data = SELECT ST_ASTEXT(SHAPE), \ + ((ml.UPPERZLOCATION + ml.LOWERZLOCATION) / 2) Z, \ + msv.DATAVALUE YORDINATE, \ + msv.PARAMETERID GROUP1, \ + msv.TIMEVALUE GROUP2, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = MEDIAN.MESHPOINT. FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + msv.PARAMETERID = ? AND \ + msv.TIMEVALUE = ? AND \ + m.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( \ + SELECT distinct FEATUREID \ + FROM MEDIAN.MESHPOINT \ + WHERE ? \ + ) \ + order by msv.TIMEVALUE, \ + msv.PARAMETERID, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION + +verticalcrosssection_mesh_odv_data = SELECT SI.NAME CRUISE, \ + M.MESHID || '-' || MEDIAN.MESHPOINT.IPOSITION || '-' || MEDIAN.MESHPOINT.JPOSITION STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (((ML.UPPERZLOCATION + ML.LOWERZLOCATION) / 2)*-1) DEPTH, \ + MSV.TIMEVALUE, \ + MSV.DATAVALUE, \ + MSV.PARAMETERID PARAMETER, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION, \ + 2 DATAID , \ + '1' QF \ + from MEDIAN.MESHLAYER ml, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH m, \ + MEDIAN.SOURCEINFO SI, \ + MEDIAN.MESHSCALARVALUE msv \ + where msv.FEATUREID = MEDIAN.MESHPOINT. FEATUREID AND \ + ml.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ml.MESHID = MEDIAN.MESHPOINT.MESHID and \ + m.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + m.PARTIDMIN <= msv.PARTID AND \ + m.PARTIDMAX >= msv.PARTID AND \ + M.SOURCEID = SI.SOURCEID AND \ + msv.PARAMETERID = ? AND \ + msv.TIMEVALUE = ? AND \ + m.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.FEATUREID in \ + ( select FEATUREID \ + from MEDIAN.MESHPOINT mp, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + mp.MESHID = m.MESHID AND \ + ? = (select ? from MEDIAN.MESHPOINT where FEATUREID = ?)) \ + order by msv.TIMEVALUE, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION, \ + msv.PARAMETERID + +############################################# +############################################# +########## Horizontalschnitt MESH ########### +############################################# +############################################# +horizontalcrosssection_meshpoint_depth = SELECT DISTINCT MP.KPOSITION KEY, \ + 'Layer ' || ML.KPOSITION || ': ' || -ML.UPPERZLOCATION || ' - '|| -ML.LOWERZLOCATION VALUE \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT MP, \ + MEDIAN.MESH M \ + WHERE ML.KPOSITION = MP.KPOSITION AND \ + ML.MESHID = MP.MESHID AND \ + M.OBJECTID = ? AND \ + MP.MESHID = M.MESHID \ + ORDER BY MP.KPOSITION + +horizontalcrosssection_mesh_year = select distinct \ + to_char(msv.TIMEVALUE,'YYYY') KEY, \ + to_char(msv.TIMEVALUE,'YYYY') VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID = ? \ + order by to_char(msv.TIMEVALUE,'YYYY') +horizontalcrosssection_mesh_date = select distinct \ + msv.TIMEVALUE KEY, \ + msv.TIMEVALUE VALUE \ + from MEDIAN.MESHSCALARVALUE msv, \ + MEDIAN.MESH m \ + where m.OBJECTID = ? AND \ + msv.PARTID >= m.PARTIDMIN AND \ + msv.PARTID <= m.PARTIDMAX AND \ + msv.PARAMETERID = ? AND \ + to_char(msv.TIMEVALUE,'YYYY') in (?) \ + order by msv.TIMEVALUE + +horizontalcrosssection_mesh_data = SELECT ST_ASTEXT(SHAPE), \ + MSV.DATAVALUE YORDINATE, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION, \ + MSV.PARAMETERID, \ + MSV.TIMEVALUE, \ + 2 DATAID \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH M, \ + MEDIAN.MESHSCALARVALUE MSV \ + where MSV.FEATUREID = MEDIAN.MESHPOINT.FEATUREID AND \ + ML.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ML.MESHID = MEDIAN.MESHPOINT.MESHID and \ + M.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + M.PARTIDMIN <= MSV.PARTID AND \ + M.PARTIDMAX >= MSV.PARTID AND \ + MSV.PARAMETERID = ? AND \ + MSV.TIMEVALUE = ? AND \ + M.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.KPOSITION = ? \ + order by MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION +horizontalcrosssection_mesh_odv_data = SELECT SI.NAME CRUISE, \ + M.MESHID || '-' || MEDIAN.MESHPOINT.IPOSITION || '-' || MEDIAN.MESHPOINT.JPOSITION STATION, \ + '*' TYPE, \ + ST_ASTEXT(SHAPE), \ + 0 BOTDEPTH, \ + (((ML.UPPERZLOCATION + ML.LOWERZLOCATION) / 2)*-1) DEPTH, \ + MSV.TIMEVALUE, \ + MSV.DATAVALUE, \ + MSV.PARAMETERID PARAMETER, \ + MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MEDIAN.MESHPOINT.KPOSITION \ + from MEDIAN.MESHLAYER ML, \ + MEDIAN.MESHPOINT, \ + MEDIAN.MESH M, \ + MEDIAN.SOURCEINFO SI, \ + MEDIAN.MESHSCALARVALUE MSV \ + where MSV.FEATUREID = MEDIAN.MESHPOINT.FEATUREID AND \ + ML.KPOSITION = MEDIAN.MESHPOINT.KPOSITION and \ + ML.MESHID = MEDIAN.MESHPOINT.MESHID and \ + M.MESHID = MEDIAN.MESHPOINT.MESHID AND \ + M.PARTIDMIN <= MSV.PARTID AND \ + M.PARTIDMAX >= MSV.PARTID AND \ + M.SOURCEID = SI.SOURCEID AND \ + MSV.PARAMETERID = ? AND \ + MSV.TIMEVALUE = ? AND \ + M.OBJECTID = ? AND \ + MEDIAN.MESHPOINT.KPOSITION = ? \ + order by MEDIAN.MESHPOINT.JPOSITION, \ + MEDIAN.MESHPOINT.IPOSITION, \ + MSV.PARAMETERID + +area_filter = SELECT DISTINCT \ + FEATUREID KEY ,\ + DESCRIPTION VALUE \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATUREID > 0 \ + ORDER BY FEATUREID + +subarea_filter = SELECT \ + FEATURECODE KEY, \ + NAME VALUE \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATUREID = ? \ + ORDER BY NAME + +rasterQuery = SELECT ST_ASTEXT(RASTER) \ + FROM MEDIAN.TOPO_WORLD_2MIN \ + WHERE INTERSECTS(RASTER, "?") + +mapviewer_interface_fis_region = SELECT ID_FIS \ + FROM MEDIAN.FEATUREAREA, \ + MEDIAN.FIS_HAS_REGION FHR \ + WHERE FHR.FEATUREID = MEDIAN.FEATUREAREA.FEATUREID AND \ + FHR.FEATURETYPE = MEDIAN.FEATUREAREA.FEATURETYPE AND \ + FHR.FEATURECODE = MEDIAN.FEATUREAREA.FEATURECODE AND \ + INTERSECTS(SHAPE,"?") + +mapviewer_interface_mapservices_has_fis = SELECT DISTINCT ID_FIS, \ + ID_MAPSERVICE \ + FROM MEDIAN.FIS_HAS_MAPSERVICE \ + WHERE ID_MAPSERVICE IN (?) + +mapviewer_interface_mapservices_has_parameter = SELECT DISTINCT ID_PARAMETER \ + FROM MEDIAN.MAPSERVICE_HAS_PARAMETER \ + WHERE ID_MAPSERVICE = ? + +mapviewer_interface_mapservices_has_parameter_using_layer = SELECT DISTINCT ID_PARAMETER \ + FROM MEDIAN.LAYER_HAS_PARAMETER \ + WHERE ID_MAPSERVICE = ? AND \ + ID_LAYER IN (?) + +############################################# +############################################# +# Layer Contis, Nauthis and Marinefeatures # +############################################# +############################################# + +layer = SELECT ROW_ID KEY, \ + TITLE || '-' || LAYER_NAME || '-' || BAND VALUE \ + FROM MEDIAN.LAYER_HAS_SUBTYPES \ + WHERE ID_FEATURECLASS LIKE ? AND \ + ITEMS > 0 \ + ORDER BY LAYER_NAME + +layer_request_data = SELECT ID_FEATURECLASS, \ + QUERY_STRING, \ + ID_MAPSERVICE || '_' ||ID_LAYER \ + FROM MEDIAN.LAYER_HAS_SUBTYPES \ + WHERE ROW_ID IN (?) + +layer_data = SELECT ST_ASTEXT(SHAPE), ? \ + FROM ? \ + WHERE ? + +layer_data_with_geom = SELECT ST_ASTEXT(SHAPE), ? \ + FROM ? \ + WHERE ? AND \ + INTERSECTS(SHAPE,"?") + +geometry_for_subareafilter=SELECT st_astext(SHAPE) \ + FROM MEDIAN.FEATUREAREA \ + WHERE (FEATURETYPE = 7 OR FEATURETYPE = 8) AND \ + FEATURECODE = ? + +layer_colums= SELECT OWNER || '.' || TABLE_NAME || '.' || COLUMN_NAME \ + FROM SDE.COLUMN_REGISTRY \ + WHERE COLUMN_NAME NOT LIKE 'SHAPE' AND \ + OWNER = '?' AND \ + TABLE_NAME = '?' + +geometry_type = select geometry_type \ + from sde.geometry_columns \ + where f_table_schema = '?' and \ + f_table_name = '?' and \ + f_geometry_column='SHAPE' + +updated_tables = SELECT FULLTABLENAME \ + FROM MEDIAN.LASTUPDATED \ + WHERE LASTUPDATE >= to_date('?', 'YYYY.MM.DD HH24:MI:SS') \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/schema/externalinterface_schema.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/schema/externalinterface_schema.sql Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,72 @@ +/* + * Lookup-Tabelle für das FIS anhand eines Gebietes. + * Diese Tabelle ist in der ArcSDE als Layer zu integrieren. + * Die Inhalte der Spalte id_fis müssen mit den vergebenen IDs + * in der Konfiguration des Artefaktservers übereinstimmen. + * + * Abbildung als Layer in der ArcSDE + * Das hier bereitgestellte SQL ist lediglich als Anhalt zu betrachten. + */ +create table fis_has_region ( + id_fis varchar2(30 char) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + description varchar2(90 char), + geometry ??? not null +); + +ALTER TABLE fis_has_region ADD PRIMARY KEY (id_fis); + +/* + * Lookup-Tabelle für das FIS anhand eines Mapservices. + * Die Inhalte der Spalte id_fis müssen mit den vergebenen IDs + * in der Konfiguration des Artefaktservers übereinstimmen. + * Die Inhalte der Spalte id_mapservice müssen mit den vergebenen + * IDs der Services im Mapviewer übereinstimmen. + */ +create table fis_has_mapservice( + id_fis varchar2(30 char) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + id_mapservice varchar2(100 char) not null /* TODO maximale Länge bestimmen und ggf. anpassen.*/ +); + +ALTER TABLE fis_has_mapservice ADD PRIMARY KEY (id_fis,id_mapservice); + +/** + * Lookuptabelle zwischen einer LayerID und dem dazugehörigen + * Mapservice und den im Layer dargestellten Parameter. + * Fremdschlüsselbeziehung zu der Tabelle fis_has_mapservice. + * Primärschlüssel: id_mapservice, id_layer, id_parameter + * id_parameter referenziert zusätzlich die Tabelle MEDIAN.PARAMETER. + * + * Auf eine explizite Abbildung von GroupLayern kann verzichtet werden, + * da sie lediglich einen "ordnenden" Charakter haben. + * vgl. S 52 Pflichtenheft. + * + * Ãœber id_group wird abgebildet ob ein Layer zu einer Gruppe von + * Layern gehört. + */ +create table layer_has_parameter( + id_mapservice varchar2(100 char) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + id_layer NUMBER(10) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + layer_name varchar2(30 char) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + id_group varchar2(30 char ), /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + id_parameter NUMBER(10) not null /* Referenz zur Tabelle MEDIAN.PARAMETER */ +); + +ALTER TABLE layer_has_parameter ADD + PRIMARY KEY (id_mapservice,id_layer,id_parameter); + +/** + * Lookuptabelle ob ein Mapservice genau einen Parameter darstellt. + * Wenn in dieser Tabelle nichts vorhanden ist muss unter zurhilfenahme + * der Layer-ID in der Tabelle layer_has_parameter gesucht werden. + * Die Inhalte der Spalte id_mapservice müssen mit den vergebenen + * IDs der Services im Mapviewer übereinstimmen. + * id_parameter referenziert zusätzlich die Tabelle MEDIAN.PARAMETER. + */ +create table mapservice_has_parameter( + id_mapservice varchar2(100 char) not null, /* TODO maximale Länge bestimmen und ggf. anpassen.*/ + id_parameter NUMBER(10) not null /* Referenz zur Tabelle MEDIAN.PARAMETER */ +); + + +ALTER TABLE mapservice_has_parameter ADD + PRIMARY KEY (id_mapservice,id_parameter); \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/doc/schema/externalinterface_testdata.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/doc/schema/externalinterface_testdata.sql Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ +INSERT INTO fis_has_mapservice (id_fis,id_mapservice) VALUES ('modeldata','BSH_IMS_Prediction_Model_Salinity'); +INSERT INTO fis_has_mapservice (id_fis,id_mapservice) VALUES ('marnet','BSH_IMS_Marine_Environment_Monitoring_Network'); + +INSERT INTO mapservice_has_parameter(id_mapservice,id_parameter) VALUES ('BSH_IMS_Prediction_Model_Salinity',2); + +INSERT INTO layer_has_parameter(id_mapservice,id_layer,layer_name,id_group,id_parameter) VALUES ('BSH_IMS_Marine_Environment_Monitoring_Network', 1, 'Sealevel', null, ?); +INSERT INTO layer_has_parameter(id_mapservice,id_layer,layer_name,id_group,id_parameter) VALUES ('BSH_IMS_Marine_Environment_Monitoring_Network', 2, 'Temperature', null, 1); +INSERT INTO layer_has_parameter(id_mapservice,id_layer,layer_name,id_group,id_parameter) VALUES ('BSH_IMS_Marine_Environment_Monitoring_Network', 3, 'Salinity', null, 2); +INSERT INTO layer_has_parameter(id_mapservice,id_layer,layer_name,id_group,id_parameter) VALUES ('BSH_IMS_Marine_Environment_Monitoring_Network', 4, 'OxygenSaturation', null, 31); +INSERT INTO layer_has_parameter(id_mapservice,id_layer,layer_name,id_group,id_parameter) VALUES ('BSH_IMS_Marine_Environment_Monitoring_Network', 5, 'Current', null, ?); \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/pom.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,160 @@ + + + 4.0.0 + de.intevation.bsh.artifacts + gnv-artifacts + jar + 1.0-SNAPSHOT + gnv-artifacts + http://maven.apache.org + + UTF-8 + + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.5.1 + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.5 + 1.5 + + + + + + + de.intevation.bsh.artifact-database + artifact-database + 1.0-SNAPSHOT + + + de.intevation.bsh.geo-backend + geo-backend + 1.0-SNAPSHOT + + + junit + junit + 3.8.1 + test + + + com.esri.sde + jsde_sdk + 9.3 + test + + + com.esri.sde + jpe_sdk + 9.3 + test + + + com.esri.sde + jpe_sdkres + 9.3 + test + + + com.ibm + icu4j + 3.2 + test + + + log4j + log4j + 1.2.14 + + + jfree + jfreechart + 1.0.13 + + + org.apache.xmlgraphics + batik-dom + 1.7 + + + org.apache.xmlgraphics + batik-svggen + 1.7 + + + org.apache.velocity + velocity + 1.6.1 + + + com.lowagie + itext + 2.1.7 + + + net.sf.opencsv + opencsv + 2.0 + + + org.apache.commons + commons-math + 2.0 + + + net.sf.ehcache + ehcache + 1.6.2 + + + commons-validator + commons-validator + 1.3.1 + + + oro + oro + 2.0.8 + + + org.geotools + gt-shapefile + 2.5.8 + + + org.geotools + gt-epsg-wkt + 2.5.8 + + + com.vividsolutions + jts + 1.9 + + + trove + trove + 2.1.1 + + + + + gt2.repo + GeoTools2 Repository including JTS + http://download.osgeo.org/webdav/geotools + + + repository.jboss.org + JBoss Repository + http://repository.jboss.com/maven2 + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/APP.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/APP.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,18 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.App; + +/** + * @author Tim Englich + * + */ +public class APP { + + /** + * @param args + */ + public static void main(String[] args) { + App.main(args); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,987 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.ProxyArtifact; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactDatabase; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.context.GNVArtifactContext; + +import de.intevation.gnv.artifacts.fis.product.Product; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.state.AutoResumeState; +import de.intevation.gnv.state.DefaultInputData; +import de.intevation.gnv.state.ExportMode; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.InputValue; +import de.intevation.gnv.state.OutputMode; +import de.intevation.gnv.state.OutputState; +import de.intevation.gnv.state.State; +import de.intevation.gnv.state.StateFactory; + +import de.intevation.gnv.state.exception.StateException; + +import de.intevation.gnv.transition.Transition; +import de.intevation.gnv.transition.TransitionFactory; + +import de.intevation.gnv.utils.ArtifactXMLUtilities; + +import java.io.IOException; +import java.io.OutputStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This is the major gnv artifact and handles the requests specified in + * de.intevation.artifactdatabase.Artifact. + * + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public abstract class GNVArtifactBase extends GNVDefaultArtifact + implements PreSettingArtifact { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactBase.class); + /** + * The UID of this Class + */ + private static final long serialVersionUID = -8907096744400741458L; + + /** + * The Identifier for the Replacement of the Artifactname + */ + public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER"; + + /** + * The XPATH to the XML-Fragment that should be used for the Configuration + */ + public static final String XPATH_ARTIFACT_CONFIGURATION = "/artifact-database/artifacts/artifact[@name='" + + XPATH_IDENTIFIER_REPLACE + + "']"; + + public static final String XPATH_STATIC_NODE = "/art:result/art:ui/art:static"; + + public static final String XPATH_INPUT_DATA = "/art:action/art:data/art:input"; + + public static final String XPATH_INCLUDE_UI = "/art:action/art:include-ui"; + + public static final String XPATH_TARGET_NAME = "/art:action/art:target/@name"; + + public static final String XPATH_OUTPUT_NAME = "/art:action/art:out/@name"; + + public static final String XPATH_OUTPUT_PARAMS = "/art:action/art:out/art:params/art:input"; + + public static final String INITIAL_STATE = "product"; + + /** + * The current State + */ + protected State current = null; + + /** + * The States that can be used + */ + protected Map states = null; + + /** + * The Transitions which can switch between the different States. + */ + protected Collection transitions = null; + + /** + * The current product + */ + protected Product product; + + /** + * The Name of the Artifact + */ + protected String name = null; + + /** + * The Presettings of InputData which can be used to + * travel through the States in different Ways or + * manipulate the InputData + */ + private Map preSettings = null; + + /** + * Constructor + */ + public GNVArtifactBase() { + super(); + } + + + /** + * This method handles request for changing the current state of an + * artifact. It is possible to step forward, backward, or to the initial + * state for choosing a fis. + */ + @Override + public Document advance(Document target, CallContext context) { + log.debug("GNVArtifactBase.advance()"); + + Document result = XMLUtils.newDocument(); + String targetState = XMLUtils.xpathString( + target, XPATH_TARGET_NAME, ArtifactNamespaceContext.INSTANCE + ); + + // no current state... + if (current == null) { + log.warn("No current state. Advance not possible."); + + result = createReport( + result, + "exceptionreport", + "exception", + "No State activated." + ); + + return result; + } + + State next = null; + + try { + + // step forward + if (isStateCurrentlyReachable(targetState)) { + + next = states.get(targetState); + + boolean success = go2NextState(context, result, next); + + if (success){ + result = createReport( + result, "result", "success", "Advance success" + ); + }else{ + result = ArtifactXMLUtilities. + createExceptionReport("Error while going to next State.", + XMLUtils.newDocument()); + } + } + + // step backward + else if((next = getPreviousState(current, targetState)) != null) { + + if (current != null) { + current.endOfLife(context.globalContext()); + } + + current = next; + + // 2. Transfer Results + current.reset(identifier); + + result = createReport( + result, "result", "success", "Advance success" + ); + } + + // goto initial step + else if(targetState.equals(INITIAL_STATE)) { + + String fis = product.getArtifactFactory(); + ArtifactDatabase db = context.getDatabase(); + GNVProductArtifactFactory fac = (GNVProductArtifactFactory) + db.getInternalArtifactFactory(fis); + + Artifact select = fac.createArtifact(identifier, context, null); + context.putContextValue(ProxyArtifact.REPLACE_PROXY, select); + + result = createReport( + result, "result", "success", "Advance success" + ); + } + + // advance not possible + else { + log.warn("advance not possible for target: " + targetState); + result = createReport( + result, + "exceptionreport", + "exception", + "Statetransition not supported" + ); + } + } + catch (StateException se) { + log.error(se, se); + result = createReport( + result, + "exceptionreport", + "exception", + se.getLocalizedMessage() + ); + } + + return result; + } + + + private boolean go2NextState(CallContext context, Document result, + State next) throws StateException { + // 2. Transfer Results + next.putInputData(current.getInputData(), identifier); + next.setParent(current); + next.setPreSettings(this.preSettings); + + if (current != null) { + current.endOfLife(context.globalContext()); + } + + // 3. Switch to next State + current = next; + + // 4. Initialize next Step + current.initialize(identifier, context); + + return true; + } + + + protected Document createReport( + Document document, + String nodeName, + String state, + String msg + ) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + Element reportNode = creator.create(nodeName); + Element stateNode = creator.create(state); + + stateNode.setTextContent(msg); + reportNode.appendChild(stateNode); + document.appendChild(reportNode); + + return document; + + } + + + /** + * Step back to the previous state specified by name. + */ + protected State getPreviousState(State current, String name) { + if (current == null) { + return null; + } + + if (current.getID().equals(name)) { + return current; + } + else { + return getPreviousState(current.getParent(), name); + } + } + + + private boolean isStateCurrentlyReachable(String stateid){ + Iterator it = this.transitions.iterator(); + String from = this.current.getID(); + while (it.hasNext()){ + Transition transition = it.next(); + if (transition.getFrom().equals(from)){ + if (transition.getTo().equals(stateid) && transition.isValid(this.current)){ + return true; + } + } + } + return false; + } + + + public Document initialize(CallContext context) { + Document result = XMLUtils.newDocument(); + try { + this.current.initialize(super.identifier, context); + + if (this.current instanceof AutoResumeState){ + // Jump to next State using the Transitions. + State next = this.getNextReachableState(this.current); + if (next != null){ + boolean success = go2NextState(context, result, next); + if (success){ + result = ArtifactXMLUtilities + .createSuccessReport("Initialize success", + XMLUtils.newDocument()); + }else{ + result = ArtifactXMLUtilities. + createExceptionReport( + "Error while going to next State.", + XMLUtils.newDocument()); + } + }else{ + result = ArtifactXMLUtilities. + createExceptionReport("No propper State found.", + XMLUtils.newDocument()); + } + }else{ + result = ArtifactXMLUtilities + .createSuccessReport("Initialize success", + XMLUtils.newDocument()); + } + } catch (StateException e) { + log.error(e,e); + result = ArtifactXMLUtilities.createExceptionReport(e + .getLocalizedMessage(), XMLUtils.newDocument()); + } + return result; + } + + /** + * Step forward to the next reachable state. + * @param current Current state. + * @return Reachable state. + */ + protected State getNextReachableState(State current){ + Iterator it = this.transitions.iterator(); + String from = current.getID(); + while (it.hasNext()){ + Transition transition = it.next(); + if (transition.getFrom().equals(from)){ + if (transition.isValid(current)){ + return this.states.get(transition.getTo()); + } + } + } + return null; + } + + + protected String readStateName(Document document) { + String returnValue = XMLUtils.xpathString( + document, XPATH_TARGET_NAME, ArtifactNamespaceContext.INSTANCE); + return returnValue; + } + + + protected Node getConfigurationFragment(Document document) { + log.debug("GNVArtifactBase.getConfigurationFragment"); + String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll( + XPATH_IDENTIFIER_REPLACE, this.name); + + Element configurationNode = (Element)Config.getNodeXPath(document, xpathQuery); + + String link = configurationNode.getAttribute("xlink:href"); + if (link != null ){ + String absolutFileName = Config.replaceConfigDir(link); + configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName); + } + + return configurationNode; + } + + /** + * Insert new data included in target into the current state. + * @param target XML document which contains data. + * @param context CallContext + * @return XML document with success or error message. + */ + @Override + public Document feed(Document target, CallContext context) { + log.debug("GNVArtifactBase.feed"); + RessourceFactory fac = RessourceFactory.getInstance(); + Locale[] locales = fac.getLocales(); + Locale locale = context.getMeta().getPreferredLocale(locales); + Document result = XMLUtils.newDocument(); + + try { + if (this.current != null) { + Collection inputData = this.parseInputData( + target, + XPATH_INPUT_DATA); + + if (!inputData.isEmpty()){ + result = current.feed(context, inputData, super.identifier); + }else{ + //String msg = "No Inputdata given. Please select at least one Entry."; + String msg = fac.getRessource( + locale, + EXCEPTION_NO_INPUT, + EXCEPTION_NO_INPUT); + + log.warn(msg); + result = ArtifactXMLUtilities.createInputExceptionReport( + msg, + XMLUtils.newDocument()); + } + } else { + String msg = "No State instantiated"; + log.warn(msg); + result = ArtifactXMLUtilities.createExceptionReport(msg, + XMLUtils.newDocument()); + } + } catch (StateException e) { + log.error(e, e); + result = ArtifactXMLUtilities.createExceptionReport(e + .getLocalizedMessage(), XMLUtils.newDocument()); + } + return result; + } + + + /** + * Describe the current artifact. + * @return The description of the current artifact. + */ + @Override + public Document describe(Document data, CallContext context) { + log.debug("GNVArtifactBase.describe"); + + Document document = createDescibeOutput( + context, + identifier, + getIncludeUIFromDocument(data) + ); + + return document; + } + + /** + * Initialse this artifact and insert some data if data + * contains necessary information for this artifact. + */ + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context,Document data) { + log.debug("GNVArtifactBase.setup"); + super.setup(identifier, factory, context, data); + + Object localContext = context; + if (context instanceof CallContext) { + localContext = ((CallContext) context).globalContext(); + + } + + if (localContext instanceof GNVArtifactContext) { + GNVArtifactContext gnvContext = (GNVArtifactContext) localContext; + Document doc = gnvContext.getConfig(); + Node artifactNode = this.getConfigurationFragment(doc); + + NodeList stateList = Config.getNodeSetXPath(artifactNode, + "states/state"); + this.states = new HashMap(stateList + .getLength()); + for (int i = 0; i < stateList.getLength(); i++) { + State tmpState = StateFactory.getInstance() + .createState(stateList.item(i)); + if (tmpState != null) { + log.debug("Initiate new state: " + tmpState.getID()); + this.states.put(tmpState.getID(), tmpState); + if (this.current == null) { + this.current = tmpState; + } + } + } + + NodeList transitionList = Config.getNodeSetXPath(artifactNode, + "states/transition"); + this.transitions = new ArrayList(transitionList.getLength()); + for (int i = 0; i < transitionList.getLength(); i++) { + Transition tmpTransition = TransitionFactory.getInstance() + .createTransition(transitionList.item(i)); + if (tmpTransition != null) { + this.transitions.add(tmpTransition); + } + } + + } + } + + + /** + * Create the xml document returned in {@link #describe(org.w3c.dom.Document, + * de.intevation.artifacts.CallContext)} + */ + protected Document createDescibeOutput( + CallContext context, + String uuid, + boolean incudeUI + ) { + log.debug("GNVArtifactBase.createDescibeOutput"); + Document document = XMLUtils.newDocument(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + Element rootNode = this.createRootNode(creator, document); + this.createHeader(creator, rootNode, document, "describe"); + this.createOutputs(creator, rootNode, document); + this.createCurrentState(creator, rootNode, document); + this.createReachableStates(creator, rootNode, document); + this.createModel(creator, rootNode, document); + if (incudeUI){ + this.createUserInterface(creator, rootNode, document, context, uuid); + } + + return document; + } + + /** + * Determine the wish to append the user interface description to the + * describe document. + * + * @return True, if the user interface description should be appended, + * otherwise false. + */ + protected boolean getIncludeUIFromDocument(Document document){ + String value = XMLUtils.xpathString( + document, XPATH_INCLUDE_UI, ArtifactNamespaceContext.INSTANCE); + + boolean includeUI = false; + if (value != null){ + includeUI = Boolean.parseBoolean(value); + } + return includeUI; + } + + + protected Element createRootNode( + XMLUtils.ElementCreator creator, + Document document + ) { + Element rootNode = creator.create("result"); + document.appendChild(rootNode); + return rootNode; + } + + /** + * Append information about the current artifact (uuid, hash). + */ + protected void createHeader( + XMLUtils.ElementCreator creator, + Element parent, + Document document, + String documentType + ) { + Element typeNode = creator.create("type"); + creator.addAttr(typeNode, "name", documentType); + parent.appendChild(typeNode); + + Element uuidNode = creator.create("uuid"); + creator.addAttr(uuidNode, "value", super.identifier); + parent.appendChild(uuidNode); + + Element hashNode = creator.create("hash"); + creator.addAttr(hashNode, "value", this.hash()); + parent.appendChild(hashNode); + } + + /** + * Create the fis select box. + */ + protected Element createSelectBox( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + CallContext context + ) { + RessourceFactory resource = RessourceFactory.getInstance(); + CallMeta callMeta = (CallMeta) context.getMeta(); + String productName = product.getName(); + + Element selectNode = creator.create("select1"); + creator.addAttr(selectNode, "ref", "product"); + artCreator.addAttr(selectNode, "state", INITIAL_STATE, true); + + + Element labelNode = creator.create("label"); + labelNode.setTextContent( + resource.getRessource(callMeta.getLanguages(), "product", "product") + ); + + Element choicesNode = creator.create("choices"); + + Element itemNode = creator.create("item"); + creator.addAttr(itemNode, "selected", "true"); + + Element choiceLabel = creator.create("label"); + choiceLabel.setTextContent(resource.getRessource( + callMeta.getLanguages(), + productName, + productName + )); + + Element choiceValue = creator.create("value"); + choiceValue.setTextContent(productName); + + itemNode.appendChild(choiceLabel); + itemNode.appendChild(choiceValue); + choicesNode.appendChild(itemNode); + + selectNode.appendChild(labelNode); + selectNode.appendChild(choicesNode); + + return selectNode; + } + + + /** + * Insert all reachable states into the describe document returned by + * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)} + */ + protected void createReachableStates( + XMLUtils.ElementCreator creator, + Element parent, + Document document + ) { + Element stateNode = creator.create("reachable-states"); + if (this.current != null) { + + // add future states + Iterator transitions = this.transitions.iterator(); + while (transitions.hasNext()) { + Transition tmpTransition = transitions.next(); + if (tmpTransition.getFrom().equals(current.getID()) && + tmpTransition.isValid(this.current)){ + Element currentNode = creator.create("state"); + creator.addAttr(currentNode, "name", tmpTransition.getTo()); + creator.addAttr( + currentNode, + "description", + this.states.get(tmpTransition.getTo()).getDescription()); + stateNode.appendChild(currentNode); + } + } + + + // add old states + appendOldReachableStates(creator, stateNode, current); + } + parent.appendChild(stateNode); + } + + + /** + * Insert states which have been visited by this artifact into the xml + * document returned by {@link #describe(org.w3c.dom.Document, + * de.intevation.artifacts.CallContext)} + */ + protected void appendOldReachableStates( + XMLUtils.ElementCreator creator, + Element parent, + State state + ) { + if (state == null) + return; + + while (state != null) { + Element currentNode = creator.create("state"); + creator.addAttr(currentNode, "name", state.getID()); + creator.addAttr(currentNode, "description", state.getDescription()); + parent.appendChild(currentNode); + + state = state.getParent(); + } + } + + + /** + * Insert the current state into the xml document returned by + * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)} + */ + protected void createCurrentState( + XMLUtils.ElementCreator creator, + Element parent, + Document document + ) { + Element stateNode = creator.create("state"); + creator.addAttr(stateNode, "name", this.current.getID()); + creator.addAttr(stateNode, "description", this.current.getDescription()); + parent.appendChild(stateNode); + } + + + protected void createModel( + XMLUtils.ElementCreator creator, + Element parent, + Document document + ) { + Element modelNode = creator.create("model"); + if (this.current != null) { + Collection inputValues = this.current + .getRequiredInputValues(); + if (inputValues != null) { + Iterator it = inputValues.iterator(); + while (it.hasNext()) { + InputValue inputValue = it.next(); + Element inputNode = creator.create("input"); + creator.addAttr(inputNode, "name", inputValue.getName()); + creator.addAttr(inputNode, "type", inputValue.getType()); + modelNode.appendChild(inputNode); + } + } + } + parent.appendChild(modelNode); + } + + /** + * Append the user interface description to the document returned by + * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)} + * @param creator XML element creator. + * @param parent New elements are appended to this node. + * @param document Current document. + * @param context CallContext + * @param uuid The uuid of the artifact. + */ + protected void createUserInterface( + XMLUtils.ElementCreator creator, + Element parent, + Document document, + CallContext context, + String uuid + ) { + XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator( + document, + XMLUtils.XFORM_URL, + XMLUtils.XFORM_PREFIX + ); + + Element uiNode = creator.create("ui"); + Element staticNode = creator.create("static"); + Element dynamic = creator.create("dynamic"); + + uiNode.appendChild(staticNode); + uiNode.appendChild(dynamic); + + parent.appendChild(uiNode); + + // append fis to dynamic part + appendFis(document, staticNode, context, product.getArtifactFactory()); + + if (this.current != null) { + Element staticUI = createSelectBox( + creator, xCreator, document, context + ); + staticNode.appendChild(staticUI); + + this.current.describe( + document, uiNode, context, uuid + ); + } + } + + + /** + * Append possible output targets to the document returned by + * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)} + * @param creator Used to create xml elements. + * @param parent New elements are appended to this node. + * @param document The current document. + */ + protected void createOutputs( + XMLUtils.ElementCreator creator, + Element parent, + Document document + ) { + log.debug("GNVArtifactBase.createOutputs"); + Element outputsNode = creator.create("outputs"); + if (this.current instanceof OutputState) { + Collection outputModes = ((OutputState) this.current) + .getOutputModes(); + if (outputModes != null) { + Iterator it = outputModes.iterator(); + while (it.hasNext()) { + OutputMode outputMode = it.next(); + log.debug("Write Outputnode for " + outputMode.toString()); + Element outputModeNode = creator.create("output"); + creator.addAttr( + outputModeNode, "name", outputMode.getName()); + creator.addAttr( + outputModeNode, "description", outputMode.getDescription()); + creator.addAttr( + outputModeNode, "mime-type", outputMode.getMimeType()); + outputsNode.appendChild(outputModeNode); + + Collection inputParameters = outputMode + .getInputParameters(); + if (inputParameters != null) { + Element inputParametersNode = creator.create("parameter"); + outputModeNode.appendChild(inputParametersNode); + Iterator it2 = inputParameters.iterator(); + while (it2.hasNext()) { + InputValue inputValue = it2.next(); + Element inputParameterNode = + creator.create("parameter"); + creator.addAttr( + inputParameterNode, "name", inputValue.getName()); + creator.addAttr( + inputParameterNode, "type", inputValue.getType()); + creator.addAttr( + inputParameterNode, "value", inputValue.getDefaultValue()); + inputParametersNode.appendChild(inputParameterNode); + } + } + + // append export modes + List exportModes = outputMode.getExportModes(); + if (exportModes != null) { + Element exports = creator.create("exports"); + outputModeNode.appendChild(exports); + + for (ExportMode exp: exportModes) { + Element export = creator.create("export"); + creator.addAttr( + export, "name", exp.getName()); + creator.addAttr( + export, "description", exp.getDescription()); + creator.addAttr( + export, "mime-type", exp.getMimeType()); + + exports.appendChild(export); + } + } + } + } else { + log.warn("No Outputmodes given."); + } + } + parent.appendChild(outputsNode); + } + + /** + * Parse input data from feed-document. + * @param document Feed-document + * @param xPath Path to input data. + * @return A collection with InputData objects. + */ + protected Collection parseInputData(Document document, + String xPath) { + HashMap returnValue = null; + + NodeList inputElemets = (NodeList) XMLUtils.xpath(document, xPath, + XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE); + if (inputElemets != null) { + returnValue = new HashMap(); + + for (int i = 0; i < inputElemets.getLength(); i++) { + Element inputDataNode = (Element)inputElemets.item(i); + String name = inputDataNode.getAttribute("name"); + String value = inputDataNode.getAttribute("value"); + + if (returnValue.containsKey(name)) { + InputData inputData = returnValue.get(name); + inputData.concartValue(value); + log.debug(inputData.toString()); + returnValue.put(name, inputData); + } else { + InputData inputData = new DefaultInputData(name, value); + + returnValue.put(name, inputData); + } + } + } + return returnValue.values(); + } + + /** + * Call an output target (e.g. chart, wms, etc.) + * @param format XML document which contains some further information about + * the desired output. + * @param outputStream Stream used for writing the output. + * @param context CallContext + * @throws IOException If an error occured while writing the result to the + * output stream. + */ + @Override + public void out(Document format, OutputStream outputStream, + CallContext context) throws IOException { + log.debug("TGNVArtifactBase.out"); + try { + + if (current != null && current instanceof OutputState) { + ((OutputState) current) + .out(format, this.parseInputData( + format, XPATH_OUTPUT_PARAMS), + outputStream, super.identifier, context); + } + } catch (StateException e) { + log.error(e, e); + throw new IOException(e.getMessage()); + } + } + + + protected static String readOutputType(Document document) { + String value = XMLUtils.xpathString( + document, XPATH_OUTPUT_NAME, ArtifactNamespaceContext.INSTANCE); + return value; + } + + + /** + * The the current product. + * @param product New product. + */ + public void setProduct(Product product) { + this.product = product; + } + + /** + * Call endOfLife of parent class and the current state. + */ + @Override + public void endOfLife(Object globalContext) { + super.endOfLife(globalContext); + + if (current != null) { + current.endOfLife(globalContext); + } + } + + /** + * Retrieves a map with given InputData which have been inserted into the + * current artifact before the parameterization began. + */ + public Map getPreSettings() { + return this.preSettings; + } + + /** + * Set InputData which are used in later states. + */ + public void setPreSettings(Map preSettings) { + this.preSettings = preSettings; + if (this.current != null){ + this.current.setPreSettings(preSettings); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,42 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.DefaultArtifactFactory; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + + +/** + * The GNV default implementation of DefaultArtifactFactory. + * + * @author Ingo Weinzierl + */ +public class GNVArtifactFactory extends DefaultArtifactFactory { + + /** + * + */ + public static final String XPATH_PRODUCT_FACTORY = "artifact-factory"; + + private static Logger logger = Logger.getLogger(GNVArtifactFactory.class); + + /** + * Constructor. + */ + public GNVArtifactFactory() { + } + + /** + * + * @param document + * @param factoryNode Contains necessary information about the desired + * factory. + */ + @Override + public void setup(Document document, Node factoryNode) { + super.setup(document, factoryNode); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVDefaultArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.DefaultArtifact; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * The default gnv artifact. The only thing defined here is a method to append + * the selected fis to the describe document. + * + * @author Ingo Weinzierl + */ +public class GNVDefaultArtifact extends DefaultArtifact { + + private static Logger logger = Logger.getLogger(GNVDefaultArtifact.class); + + /** + * + */ + public static final String EXCEPTION_NO_INPUT = "no.input.data"; + + + /** + * Constructor. + */ + public GNVDefaultArtifact() { + super(); + } + + + /** + * Append the selected fis to the describe document. + * + * @param document + * @param staticNode + * @param context + * @param fisName + */ + protected void appendFis( + Document document, + Element staticNode, + CallContext context, + String fisName + ) { + RessourceFactory resource = RessourceFactory.getInstance(); + CallMeta callMeta = (CallMeta) context.getMeta(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + XMLUtils.XFORM_URL, + XMLUtils.XFORM_PREFIX + ); + + XMLUtils.ElementCreator artCreator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + Element selectNode = creator.create("select1"); + artCreator.addAttr(selectNode, "fis", "true", true); + + Element labelNode = creator.create("label"); + labelNode.setTextContent( + resource.getRessource(callMeta.getLanguages(), "fis", "fis") + ); + + Element choicesNode = creator.create("choices"); + + Element itemNode = creator.create("item"); + creator.addAttr(itemNode, "selected", "true"); + + Element choiceLabel = creator.create("label"); + choiceLabel.setTextContent(resource.getRessource( + callMeta.getLanguages(), + fisName, + fisName + )); + + Element choiceValue = creator.create("value"); + choiceValue.setTextContent(fisName); + + itemNode.appendChild(choiceLabel); + itemNode.appendChild(choiceValue); + choicesNode.appendChild(itemNode); + + selectNode.appendChild(labelNode); + selectNode.appendChild(choicesNode); + + staticNode.appendChild(selectNode); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVProductArtifactFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,196 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.DefaultArtifactFactory; +import de.intevation.artifactdatabase.ProxyArtifact; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.fis.SelectProductArtifact; + +import de.intevation.gnv.artifacts.fis.product.DefaultProduct; + +import de.intevation.gnv.state.DefaultInputData; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This factory is called to create a {@link + * de.intevation.gnv.artifacts.fis.SelectProductArtifact} which lets the user + * select a product supported by the selected fis. + * + * @author Ingo Weinzierl + */ +public class GNVProductArtifactFactory extends DefaultArtifactFactory { + + public static final String XPATH_REPLACE_NAME = "IDENTIFIER"; + + public static final String XPATH_PRODUCT_ARTIFACT = + "artifact-database/artifacts/artifact[@name='"+XPATH_REPLACE_NAME+"']"; + + public static final String XPATH_PRODUCT = "products/product"; + + public static final String XPATH_PRODUCT_NAME = "@name"; + + public static final String XPATH_PRODUCT_FACTORY = "artifact-factory"; + + public static final String XPATH_PRODUCT_PARAMETER = "parameters/parameter"; + + private Logger logger = Logger.getLogger(GNVProductArtifactFactory.class); + + private Map productFactories; + private Map products; + + + /** + * Constructor. + */ + public GNVProductArtifactFactory() { + } + + /** + * Method to create an artifact. If the created artifact is from type + * ProxyArtifact, a further ProductSelectArtifact is created + * which becomes embedded into the ProxyArtifact. + * @param identifier UUID. + * @param context CallContext. + * @param data Some data. + * @return The created artifact. + */ + @Override + public Artifact createArtifact(String identifier, Object context, Document data) { + + // create a SelectProductArtifact for initial product selection + Artifact artifact = super.createArtifact(identifier, context, data); + + if (artifact instanceof ProxyArtifact) { + + SelectProductArtifact select = new SelectProductArtifact(); + select.setProducts(products); + select.setup(identifier, this, context, data); + + ((ProxyArtifact) artifact).setProxied(select); + } + + return artifact; + } + + + @Override + public void setup(Document document, Node factoryNode) { + super.setup(document, factoryNode); + + String xpath = XPATH_PRODUCT_ARTIFACT.replace(XPATH_REPLACE_NAME, name); + Node artifact = (Node) XMLUtils.xpath( + document, xpath, XPathConstants.NODE); + + NodeList productNodes = (NodeList) XMLUtils.xpath( + artifact, XPATH_PRODUCT, XPathConstants.NODESET); + + if (productNodes == null) { + logger.warn("No products found for fis: " + name); + return; + } + + int productLength = productNodes.getLength(); + + if (productLength != 0) { + productFactories = new HashMap(productLength); + products = new HashMap(productLength); + + parseProductFactories(document, productNodes); + } + } + + + public ArtifactFactory getArtifactFactoryByName(String name) { + return (ArtifactFactory) productFactories.get(name); + } + + + protected void parseProductFactories(Document document, NodeList products) { + int items = products.getLength(); + + for(int i = 0; i < items; i++) { + + try { + Node product = products.item(i); + + String name = (String) XMLUtils.xpath( + product, XPATH_PRODUCT_NAME, XPathConstants.STRING); + + Node factoryNode = (Node) XMLUtils.xpath( + product, XPATH_PRODUCT_FACTORY, XPathConstants.NODE); + + String factoryClass = factoryNode.getTextContent(); + + if (factoryClass == null || factoryClass.equals("")) { + logger.warn("No artifact factory class found for " + name); + continue; + } + + Class cls = Class.forName(factoryClass); + ArtifactFactory factory = (ArtifactFactory) cls.newInstance(); + factory.setup(document, factoryNode); + + productFactories.put(name, factory); + initializeProducts(product); + } + catch (ClassNotFoundException cnfe) { + logger.warn(cnfe, cnfe); + } + catch (InstantiationException ie) { + logger.warn(ie, ie); + } + catch (IllegalAccessException iae) { + logger.warn(iae, iae); + } + } + } + + + /** + * Initialize all products supported by the current fis. + */ + protected void initializeProducts(Node productNode) { + String productName = (String) XMLUtils.xpath( + productNode, "@name", XPathConstants.STRING); + + NodeList parameterNodes = (NodeList) XMLUtils.xpath( + productNode, XPATH_PRODUCT_PARAMETER, XPathConstants.NODESET + ); + + if (parameterNodes != null) { + int items = parameterNodes.getLength(); + Collection inputParameter = new ArrayList(items); + + for (int j = 0; j < items; j++) { + Node parameterNode = (Node) parameterNodes.item(j); + String name = (String) XMLUtils.xpath( + parameterNode, "@name", XPathConstants.STRING); + String value = (String) XMLUtils.xpath( + parameterNode, "@value", XPathConstants.STRING); + + inputParameter.add(new DefaultInputData(name, value)); + } + + products.put( + productName, + new DefaultProduct(productName, inputParameter, this.name) + ); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/PreSettingArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/PreSettingArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,29 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.gnv.state.InputData; + +import java.util.Map; + +/** + * This artifact is used to be fed before the parameterization has started. + * + * @author Tim Englich + * + */ +public interface PreSettingArtifact { + + + /** + * + * @return the InputData which have been inserted before parameterization + * has started. + */ + Map getPreSettings(); + + /** + * + * @param preSettings + */ + void setPreSettings(Map preSettings); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/cache/CacheFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/cache/CacheFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,92 @@ +package de.intevation.gnv.artifacts.cache; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; + +import org.apache.log4j.Logger; + +import de.intevation.gnv.geobackend.base.query.cache.CacheCleaner; +import de.intevation.gnv.state.cache.ThematicDataCacheCleaner; + +/** + * The CacheFactory is used to initialize and retrieve Cache. + * + * @author Tim Englich + */ +public class CacheFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(CacheFactory.class); + + private final static String CACHENAME = "artifactdata"; + + /** + * The singleton Instance of this Factory. + */ + private static CacheFactory instance = null; + + /** + * The manager of the Cache + */ + private CacheManager cacheManager = null; + + /** + * The Cleaner of the Cache + */ + private CacheCleaner cacheCleaner = null; + + /** + * Basic-Constructor of this Class + */ + private CacheFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * + * @return an singleton Instance of this Class + */ + public static CacheFactory getInstance() { + if (instance == null) { + instance = new CacheFactory(); + } + return instance; + } + + /** + * Getting the ConnectionPool + * + * @return the ConnectionPool + */ + public Cache getCache() { + return this.cacheManager.getCache(CACHENAME); + } + + /** + * Initializes the ConnectionPool. Should only be called once on system + * startup + * + * @param configurationFileName + */ + public void initializeCache(String configurationFileName) { + if (cacheManager == null) { + cacheManager = new CacheManager(configurationFileName); + cacheManager.addCache(CACHENAME); + this.cacheCleaner = new ThematicDataCacheCleaner(); + this.cacheCleaner.start(); + } + } + + /** + * Checks if the ConnectionPool has already been initialized. + * + * @return true if the ConnectionPool is initialized. + */ + public boolean isInitialized() { + return this.cacheManager != null; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/cache/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/cache/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +This package contains classes used for data caching. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContext.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,108 @@ +package de.intevation.gnv.artifacts.context; + +import de.intevation.artifactdatabase.DefaultArtifactContext; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Paint; + +import java.io.File; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * This class defines some final fields used to store some meta information + * required during the work with an artifact into a context object which is + * available in each request specified in + * de.intevation.gnv.artifacts.Artifacts and further methods called + * by those. + * + * @author Tim Englich + * @author Sascha L. Teichmann + */ +public class GNVArtifactContext +extends DefaultArtifactContext +{ + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactContext.class); + + public static final String CHART_TEMPLATE_KEY = + "gnv.chart.template"; + + public static final String HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES_KEY = + "gnv.horizontal.cross.section.profile.samples"; + + public static final String HORIZONTAL_CROSS_SECTION_SAMPLES_KEY = + "gnv.horizontal.cross.section.samples"; + + public static final String HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS_KEY = + "gnv.horizontal.cross.section.extrapolation.rounds"; + + public static final String + HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY = + "gnv.horizontal.cross.section.result.shapefile"; + + public static final File + DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH = + new File(System.getProperty("java.io.tmpdir")); + + public static final Integer + DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES = Integer.valueOf(250); + + public static final Integer + DEFAULT_HORIZONTAL_CROSS_SECTION_SAMPLES = Integer.valueOf(1024); + + public static final Integer + DEFAULT_HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS = Integer.valueOf(0); + + public static final String HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY = + "gnv.horizontal.cross.section.ground.interpolation"; + + public static final String DEFAULT_HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION = + "bilinear"; + + public static final String PALETTES_KEY = + "gnv.color.palettes"; + + public static final String VERTICAL_CROSS_SECTION_SAMPLES_KEY = + "gnv.vertical.cross.section.samples"; + + public static final Dimension DEFAULT_VERTICAL_CROSS_SECTION_SAMPLES = + new Dimension(1024, 768); + + public static final String VERTICAL_CROSS_SECTION_FILTER_FACTORIES_KEY = + "gnv.vertical.cross.section.filter.factories"; + + public static final String VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY = + "gnv.vertical.cross.section.ground.interpolation"; + + public static final String DEFAULT_VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION = + "bilinear"; + + public static final String VERTICAL_CROSS_SECTION_GROUND_FILL_KEY = + "gnv.vertical.cross.section.ground.fill"; + + public static final String MAPSERVER_SERVER_PATH_KEY = + "mapserver.server.path"; + + public static final String MAPSERVER_MAP_PATH_KEY = + "mapserver.map.path"; + + public static final Paint DEFAULT_VERTICAL_CROSS_SECTION_GROUND_FILL = + new Color(0x7c8683); + + public GNVArtifactContext() { + super(); + log.debug("GNVArtifactContext.Constructor"); + } + + public GNVArtifactContext(Document config) { + super(config); + log.debug("GNVArtifactContext.Constructor(config)"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/GNVArtifactContextFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,791 @@ +package de.intevation.gnv.artifacts.context; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.ArtifactContextFactory; + +import de.intevation.gnv.artifacts.cache.CacheFactory; + +import de.intevation.gnv.chart.XMLChartTheme; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; + +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +import de.intevation.gnv.raster.Filter; +import de.intevation.gnv.raster.Palette; +import de.intevation.gnv.raster.PaletteManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Paint; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Properties; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * This factory class is used to create new GNVArtfactContext objects, + * initialize required components and put them into the created context object + * for being available in the application. + * + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class GNVArtifactContextFactory implements ArtifactContextFactory { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactContext.class); + + /** + * + */ + public static final String XPATH_GEOBACKEND_CONFIGURATION = + "artifact-database/geo-backend/backend-configuration"; + + /** + * + */ + public static final String XPATH_GEOBACKEND_QUERYCONFIGURATION = + "artifact-database/geo-backend/query-configuration"; + + private final static String CACHECONFIGNODEPATH = + "/artifact-database/ehcache/configuration"; + + private final static String CHARTCONFIGNODEPATH = + "/artifact-database/gnv/charttemplate/configuration"; + + /** + * + */ + public final static String PALETTES_PATH = + "/artifact-database/gnv/palettes"; + + /** + * + */ + public final static String PALETTE_ITEMS = + "palette"; + + /** + * + */ + public final static String HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES = + "/artifact-database/gnv/horizontal-cross-section-profile/samples/@number"; + + /** + * + */ + public final static String HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION = + "/artifact-database/gnv/horizontal-cross-section/ground/@interpolation"; + + /** + * + */ + public final static String HORIZONTAL_CROSS_SECTION_SAMPLES = + "/artifact-database/gnv/horizontal-cross-section/samples/@number"; + + /** + * + */ + public final static String HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS = + "/artifact-database/gnv/horizontal-cross-section/extrapolation/@rounds"; + + /** + * + */ + public final static String HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH = + "/artifact-database/gnv/shapefile-directory/@path"; + + /** + * + */ + public final static String VERTICAL_CROSS_SECTION_SAMPLES = + "/artifact-database/gnv/vertical-cross-section/samples"; + + /** + * + */ + public final static String VERTICAL_CROSS_SECTION_FILTERS = + "/artifact-database/gnv/vertical-cross-section/filters/filter"; + + /** + * + */ + public final static String VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION = + "/artifact-database/gnv/vertical-cross-section/ground/@interpolation"; + + /** + * + */ + public final static String VERTICAL_CROSS_SECTION_GROUND_FILL_COLOR = + "/artifact-database/gnv/vertical-cross-section/ground/@fill-color"; + + /** + * + */ + public final static String XPATH_MAPSERVER_PATH = + "/artifact-database/mapserver/server/@path"; + + /** + * + */ + public final static String XPATH_MAP_PATH = + "/artifact-database/gnv/map-generator/mapfile/@path"; + + /** + * Constructor + */ + public GNVArtifactContextFactory() { + super(); + log.debug("GNVArtifactContextFactory.Constructor"); + } + + /** + * Create a new {@link GNVArtifactContext} object and initialize all + * components required by the application. + * + * @param config + * @return GNVArtifactContext + * @see de.intevation.artifacts.ArtifactContextFactory#createArtifactContext(org.w3c.dom.Document) + */ + public Object createArtifactContext(Document config) { + GNVArtifactContext returnValue = null; + try { + log.debug("GNVArtifactContextFactory.createArtifactContext"); + log.info("Initialisation of the Geo-BackendConnectionPool"); + String backendConfigurationFile = Config.getStringXPath(config, + XPATH_GEOBACKEND_CONFIGURATION); + backendConfigurationFile = Config.replaceConfigDir( + backendConfigurationFile); + + Properties properties = getProperties(backendConfigurationFile); + ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance(); + cpf.initializeConnectionPool(properties); + + log.info("Initialisation of the QueryContainer"); + String queryConfigurationFile = Config.getStringXPath(config, + XPATH_GEOBACKEND_QUERYCONFIGURATION); + queryConfigurationFile = Config.replaceConfigDir( + queryConfigurationFile); + + Properties queryProperties = getProperties(queryConfigurationFile); + QueryContainerFactory qcf = QueryContainerFactory.getInstance(); + qcf.initializeQueryContainer(queryProperties); + + configureCache(config); + + returnValue = new GNVArtifactContext(config); + + configurePalettes(config, returnValue); + + configureChartTemplate(config, returnValue); + + configureHorizontalCrossSectionProfile(config, returnValue); + + configureHorizontalCrossSection(config,returnValue); + + configureVerticalCrossSection(config, returnValue); + + configureMapserver(config, returnValue); + + } catch (FileNotFoundException e) { + log.error(e, e); + } catch (IOException e) { + log.error(e, e); + } catch (QueryContainerException e) { + log.error(e, e); + } + return returnValue; + } + + /** + * + * @param config + * @param context + */ + protected void configureVerticalCrossSection( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of vertical cross section"); + configureVerticalCrossSectionSamples(config, context); + configureVerticalCrossSectionFilters(config, context); + configureVerticalCrossSectionGroundInterpolation(config, context); + configureVerticalCrossSectionGroundFillColor(config, context); + } + + + /** + * + * @param config + */ + protected void configureCache(Document config) { + String cacheConfigurationFile = Config.getStringXPath( + config, CACHECONFIGNODEPATH); + + if (cacheConfigurationFile != null + && !cacheConfigurationFile.equals("")) + { + log.info("Initialisation of the Cache"); + cacheConfigurationFile = Config.replaceConfigDir( + cacheConfigurationFile); + + CacheFactory cf = CacheFactory.getInstance(); + cf.initializeCache(cacheConfigurationFile); + } + } + + /** + * + * @param config + * @param context + */ + protected void configureVerticalCrossSectionGroundFillColor( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of vertical cross section ground fill color"); + + String fillColor = Config.getStringXPath( + config, + VERTICAL_CROSS_SECTION_GROUND_FILL_COLOR); + + Paint fill = + GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_GROUND_FILL; + + if (fillColor != null + && (fillColor = fillColor.trim()).length() != 0) { + try { + Color color = Color.decode(fillColor); + log.info("ground fill color: #" + + Integer.toHexString(color.getRGB())); + fill = color; + } + catch (NumberFormatException nfe) { + log.error("'" + fillColor + "' is not a valid color"); + } + } + + context.put( + GNVArtifactContext + .VERTICAL_CROSS_SECTION_GROUND_FILL_KEY, + fill); + } + + /** + * + * @param config + * @param context + */ + protected void configureVerticalCrossSectionGroundInterpolation( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of vertical cross section ground interpolation"); + String interpolation = Config.getStringXPath( + config, + VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION); + + if (interpolation == null + || (interpolation = interpolation.trim()).length() == 0) { + interpolation = GNVArtifactContext + .DEFAULT_VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION; + } + + log.info("ground interpolation: " + interpolation); + + context.put( + GNVArtifactContext + .VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY, + interpolation); + } + + /** + * + * @param config + * @param context + */ + protected void configureVerticalCrossSectionFilters( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of vertical cross section filters"); + + NodeList filters = Config.getNodeSetXPath( + VERTICAL_CROSS_SECTION_FILTERS); + + ArrayList filterFactories = + new ArrayList(); + + if (filters == null) { + log.warn("no filters found"); + } + else { + for (int i = 0, N = filters.getLength(); i < N; ++i) { + Element filterElement = (Element)filters.item(i); + String factoryName = filterElement.getAttribute("factory"); + if ((factoryName = factoryName.trim()).length() > 0) { + try { + Class clazz = Class.forName(factoryName); + Filter.Factory filterFactory = + (Filter.Factory)clazz.newInstance(); + filterFactories.add(filterFactory); + } + catch (ClassNotFoundException cnfe) { + log.error("filter class not found", cnfe); + } + catch (InstantiationException ie) { + log.error("cannot instantiate filter factory", ie); + } + catch (IllegalAccessException iae) { + log.error("cannot access filter factory", iae); + } + catch (ClassCastException cce) { + log.error("not a filter factory class", cce); + } + } + else { + log.error("No factory name given"); + } + } + } + + log.info("number of filters: " + filterFactories.size()); + + context.put( + GNVArtifactContext.VERTICAL_CROSS_SECTION_FILTER_FACTORIES_KEY, + Collections.unmodifiableList(filterFactories)); + } + + /** + * + * @param config + * @param context + */ + protected void configureVerticalCrossSectionSamples( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of vertical cross section samples"); + + Element samples = (Element)Config.getNodeXPath( + VERTICAL_CROSS_SECTION_SAMPLES); + + Dimension sampleSize = new Dimension( + GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_SAMPLES); + + if (samples == null) { + log.warn("no samples found"); + } + else { + String widthString = samples.getAttribute("width"); + if ((widthString = widthString.trim()).length() > 0) { + try { + sampleSize.width = Math.max(1, Integer.parseInt(widthString)); + } + catch (NumberFormatException nfe) { + log.error("invalid value for width: '" + widthString + "'"); + } + } + String heightString = samples.getAttribute("height"); + if ((heightString = heightString.trim()).length() > 0) { + try { + sampleSize.height = Math.max(1, Integer.parseInt(heightString)); + } + catch (NumberFormatException nfe) { + log.error("invalid value for height: '" + heightString + "'"); + } + } + } + log.info("samples (width x height): " + + sampleSize.width + " x " + sampleSize.height); + + context.put( + GNVArtifactContext.VERTICAL_CROSS_SECTION_SAMPLES_KEY, + sampleSize); + + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSectionProfile( + Document config, + GNVArtifactContext context + ) + { + log.info("configuration of horizontal cross section profile"); + + String numSamples = Config.getStringXPath( + config, + HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES); + + Integer samples = + GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES; + + if (numSamples == null) { + log.warn("No number of samples found."); + } + else { + try { + samples = Integer.valueOf(numSamples); + } + catch (NumberFormatException nfe) { + log.warn("Invalid integer for number of samples"); + } + } + + log.info("# horizontal cross section profile samples: " + samples); + + context.put( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES_KEY, + samples); + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSection( + Document config, + GNVArtifactContext context + ) { + log.info("configuration of horizontal cross section"); + + configureHorizontalCrossSectionSamples(config, context); + configureHorizontalCrossSectionExtrapolation(config, context); + configureHorizontalCrossSectionResultShapeFilePath(config, context); + configureHorizontalCrossSectionGroundInterpolation(config, context); + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSectionExtrapolation( + Document config, + GNVArtifactContext context + ) + { + log.info( + "configuration of horizontal cross section extrapolation"); + + String extrapolationRoundsValue = Config.getStringXPath( + config, + HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS); + + Integer extrapolationRounds = + GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS; + + if (extrapolationRoundsValue != null + && (extrapolationRoundsValue = extrapolationRoundsValue.trim()).length() > 0 + ) { + try { + extrapolationRounds = + Integer.valueOf(extrapolationRoundsValue); + } + catch (NumberFormatException nfe) { + log.error( + "'" + extrapolationRoundsValue + "' is not a valid integer"); + } + } + + log.info("extrapolation rounds: " + extrapolationRounds); + + context.put( + GNVArtifactContext + .HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS_KEY, + extrapolationRounds); + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSectionGroundInterpolation( + Document config, + GNVArtifactContext context + ) + { + log.info( + "configuration of horizontal cross section ground interpolation"); + + String interpolation = Config.getStringXPath( + config, + HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION); + + if (interpolation == null + || (interpolation = interpolation.trim()).length() == 0) { + interpolation = GNVArtifactContext + .DEFAULT_HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION; + } + + log.info("ground interpolation: " + interpolation); + + context.put( + GNVArtifactContext + .HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY, + interpolation); + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSectionResultShapeFilePath( + Document config, + GNVArtifactContext context + ) + { + log.info( + "configuration of horizontal cross section result shape file path"); + + File dir = + GNVArtifactContext. + DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH; + + String path = Config.getStringXPath( + config, + HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH); + + if (path != null && (path = path.trim()).length() > 0) { + dir = new File(Config.replaceConfigDir(path)); + } + else { + log.warn("No 'result-shapefile-directory' given"); + } + + log.info("writing shape files to '" + + dir.getAbsolutePath() + "'"); + + context.put( + GNVArtifactContext + .HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY, + dir); + } + + /** + * + * @param config + * @param context + */ + protected void configureHorizontalCrossSectionSamples( + Document config, + GNVArtifactContext context + ) + { + log.info("configuration of horizontal cross section samples"); + String numSamples = Config.getStringXPath( + config, + HORIZONTAL_CROSS_SECTION_SAMPLES); + + Integer samples = + GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_SAMPLES; + + if (numSamples == null) { + log.warn("No number of samples found."); + } + else { + try { + samples = Integer.valueOf(numSamples); + } + catch (NumberFormatException nfe) { + log.warn("Invalid integer for number of samples"); + } + } + + log.info("# horizontal cross section profile samples: " + samples); + + context.put( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_SAMPLES_KEY, + samples); + } + + + /** + * + * @param config + * @param context + */ + protected void configureChartTemplate( + Document config, + GNVArtifactContext context + ) { + log.info("Initialisation of chart template"); + String chartConfigFile = Config.getStringXPath( + config, CHARTCONFIGNODEPATH + ); + + XMLChartTheme theme = new XMLChartTheme("XMLChartTheme"); + + if (chartConfigFile == null) { + log.warn("no configuration file for chart template found"); + } + else { + chartConfigFile = Config.replaceConfigDir(chartConfigFile); + log.debug("Parse xml configuration of " + chartConfigFile); + + Document tmpl = XMLUtils.parseDocument(new File(chartConfigFile)); + if (tmpl != null) { + theme.applyXMLConfiguration(tmpl); + } + else { + log.error( + "Cannot load chart template from '" + + chartConfigFile + "'"); + } + } + + context.put(GNVArtifactContext.CHART_TEMPLATE_KEY, theme); + } + + /** + * + * @param config + * @param context + */ + protected void configurePalettes( + Document config, + GNVArtifactContext context + ) { + log.info("configure palettes"); + + HashMap palettes = new HashMap(); + + Element node = (Element)Config.getNodeXPath(config, PALETTES_PATH); + + if (node == null) { + log.error("No palettes found"); + } + else { + NodeList pals = node.getElementsByTagName(PALETTE_ITEMS); + for (int i = 0, N = pals==null?0:pals.getLength(); i < N; ++i) { + Element pal = (Element)pals.item(i); + String name = pal.getAttribute("name"); + String description = pal.getAttribute("description"); + String filename = pal.getAttribute("file"); + String parameterIds = pal.getAttribute("parameter-ids"); + + if (name == null || (name = name.trim()).length() == 0) { + log.error("Palette has no 'name' attribute."); + } + else if (filename == null + || (filename = filename.trim()).length() == 0) { + log.error("Palette '" + name + "' has no 'file' attribute."); + } + else if (parameterIds == null + || (parameterIds = parameterIds.trim()).length() == 0) { + log.error("no parameter ids given for '" + name + "'"); + } + else { + ArrayList ids = new ArrayList(); + for (String idString: parameterIds.split("[\t ,]+")) { + try { + ids.add(Integer.valueOf(idString)); + } + catch (NumberFormatException nfe) { + log.error( + "parameter id '" + idString + "' is integer"); + } + } + filename = Config.replaceConfigDir(filename); + Document document = XMLUtils.parseDocument( + new File(filename)); + if (document == null) { + log.error("Cannot load palette file '" + + filename + "'"); + } + else { + PaletteManager manager = new PaletteManager( + name, + description, + new Palette(document)); + for (Integer id: ids) { + palettes.put(id, manager); + } + } + } + } // for all palettes + } + + context.put(GNVArtifactContext.PALETTES_KEY, palettes); + } + + + /** + * + * @param config + * @param context + */ + protected void configureMapserver( + Document config, + GNVArtifactContext context + ) { + log.info("read configuration of mapserver."); + + String serverPath = (String) Config.getStringXPath( + config, XPATH_MAPSERVER_PATH); + + String mapPath = (String) Config.getStringXPath( + config, XPATH_MAP_PATH); + mapPath = Config.replaceConfigDir(mapPath); + + if (serverPath != null && mapPath != null) { + context.put(GNVArtifactContext.MAPSERVER_SERVER_PATH_KEY,serverPath); + context.put(GNVArtifactContext.MAPSERVER_MAP_PATH_KEY, mapPath); + } + } + + /** + * Read some properties from config file specified by filePath. + * + * @param filePath Path to a cofig file. + * @return Properties contained in filePath. + * @throws FileNotFoundException if file specified by filePath is not + * existing. + * @throws IOException if an error occured while reading from file. + */ + private Properties getProperties(String filePath) + throws FileNotFoundException, IOException + { + InputStream inputStream = null; + try { + inputStream = new FileInputStream(filePath); + Properties properties = new Properties(); + properties.load(inputStream); + return properties; + } + finally { + if (inputStream != null) { + try { inputStream.close(); } + catch (IOException ioe) {} + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/context/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +Support for context objects that store data items used in the GNV in different +places across the whole application. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/SelectProductArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,516 @@ +package de.intevation.gnv.artifacts.fis; + +import de.intevation.artifactdatabase.ProxyArtifact; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.GNVArtifactBase; +import de.intevation.gnv.artifacts.GNVDefaultArtifact; +import de.intevation.gnv.artifacts.GNVProductArtifactFactory; +import de.intevation.gnv.artifacts.PreSettingArtifact; + +import de.intevation.gnv.artifacts.fis.product.Product; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.state.DefaultInputData; +import de.intevation.gnv.state.InputData; + +import java.io.IOException; +import java.io.OutputStream; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This artifact is used to handle to input/output at the beginning of a + * parameterization when no product has been selected so far. After the user + * having selected a product, this artifact is replaced by a concrete product + * artifact. + * + * @author Ingo Weinzierl + */ +public class SelectProductArtifact extends GNVDefaultArtifact { + + /** + * THE UID of this Class. + */ + private static final long serialVersionUID = -7952357683127758677L; + + /** + * Path to uuid. + */ + public static final String XPATH_UUID = "art:action/art:uuid/@value"; + + /** + * Path to hash. + */ + public static final String XPATH_HASH = "art:action/art:hash/@value"; + + /** + * Path to selected product. + */ + public static final String XPATH_INPUT_DATA_VALUE = + "art:action/art:data/art:input[@name='product']/@value"; + + /** + * Path to parameters required by the factory. + */ + public static final String XPATH_SETUP_PARAMETER_NODES = + "/art:action/art:factory/art:parameter"; + + public static final String XFORM_URL = "http://www.w3.org/2002/xforms"; + + /** + * Prefix used in the user interface description part of the describe + * document. + */ + public static final String XFORM_PREFIX = "xform"; + + private static Logger log = Logger.getLogger(SelectProductArtifact.class); + + private Map products; + private Product current; + private Artifact artifact; + private String name; + + private Map preSettings = null; + + /** + * Constructor. + */ + public SelectProductArtifact() { + super(); + } + + + /** + * Initialize this artifact and parse all required information from + * data document. + * + * @param identifier + * @param factory + * @param context + * @param data + */ + @Override + public void setup( + String identifier, + ArtifactFactory factory, + Object context, + Document data) { + log.debug("SelectProductArtifact.setup()"); + super.setup(identifier, factory, context,data); + this.name = factory.getName(); + + // Read the Parameters that should be used for the setup from the + // Data-XML.Document. + NodeList parameterNodes = (NodeList) XMLUtils.xpath(data, + XPATH_SETUP_PARAMETER_NODES, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + if (parameterNodes != null && parameterNodes.getLength() > 0){ + this.preSettings = new HashMap(); + for (int i = 0; i < parameterNodes.getLength(); i++){ + Element parameterNode = (Element)parameterNodes.item(i); + String name = parameterNode.getAttribute("name"); + String value = parameterNode.getAttribute("value"); + log.debug("Name: "+name); + log.debug("Value: "+value); + InputData inputData = this.preSettings.get(name); + if (inputData == null){ + inputData = new DefaultInputData(name, value); + this.preSettings.put(name, inputData); + }else{ + inputData.concartValue(value); + } + } + } + + } + + + /** + * + * @param products Insert a bunch of products. + */ + public void setProducts(Map products) { + this.products = products; + } + + + /** + * Search for a selected product and create a new concrecte product artifact + * with this information. + * + * @param target Document which contains the selected product. + * @param context CallContext. + * @return Error or success message. + */ + @Override + public Document feed(Document target, CallContext context) { + log.debug("SelectProductArtifact.feed()"); + + if (artifact == null) { + Document document = XMLUtils.newDocument(); + String productName = XMLUtils.xpathString( + target, + XPATH_INPUT_DATA_VALUE, + ArtifactNamespaceContext.INSTANCE + ); + + current = (Product) products.get(productName); + + String reportNode = null; + String resultNode = null; + String msg = null; + + if (current != null) { + reportNode = "result"; + resultNode = "success"; + msg = "Feed was successfully. New Artifact created."; + } + else { + reportNode = "exceptionreport"; + resultNode = "exception"; + msg = "Product does not exist."; + } + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + Element report = creator.create(reportNode); + Element success = creator.create(resultNode); + success.setTextContent(msg); + report.appendChild(success); + document.appendChild(report); + + return document; + } + else { + return artifact.feed(target, context); + } + } + + + /** + * If {@link #feed(org.w3c.dom.Document, de.intevation.artifacts.CallContext)} + * was sucessfully called before, this artifact is replaced with a concrete + * product artifact. + * + * @param target The advance document. + * @param context The CallContext. + * @return a document with an error or success message. + */ + @Override + public Document advance(Document target, CallContext context) { + log.debug("SelectProductArtifact.advance()"); + + if (artifact != null) { + Document result = artifact.advance(target, context); + context.putContextValue(ProxyArtifact.REPLACE_PROXY, artifact); + return result; + } + + Document result = XMLUtils.newDocument(); + if (current == null) { + // artifact needs to be feeded first + String msg = "Artifact is not configured properly. Call 'feed' fist."; + log.error(msg); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + result, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + Element report = creator.create("exceptionreport"); + Element exception = creator.create("exception"); + exception.setTextContent(msg); + report.appendChild(exception); + result.appendChild(report); + + return result; + } + + String uuid = XMLUtils.xpathString( + target, XPATH_UUID, ArtifactNamespaceContext.INSTANCE + ); + + String hash = XMLUtils.xpathString( + target, XPATH_HASH, ArtifactNamespaceContext.INSTANCE + ); + + // fetch ArtifactFactory from context and create a new Artifact + ArtifactFactory factory = context.getDatabase() + .getInternalArtifactFactory(this.name); + factory = ((GNVProductArtifactFactory)factory) + .getArtifactFactoryByName(current.getName()); + artifact = factory.createArtifact(uuid, context, null); + + + if (this.preSettings != null && artifact instanceof PreSettingArtifact){ + ((PreSettingArtifact)artifact).setPreSettings(this.preSettings); + } + + artifact.feed(feedDocument(uuid, hash), context); + + result = ((GNVArtifactBase) artifact).initialize(context); + if (artifact instanceof GNVArtifactBase) { + ((GNVArtifactBase) artifact).setProduct(current); + } + context.putContextValue(ProxyArtifact.REPLACE_PROXY, artifact); + return result; + } + + + /** + * Create a describe document including the user interface description. The + * user gets the choice to select a product supported by the current fis. + * + * @param data The describe document. + * @param context The CallContext. + * @return A document with an error or success message. + */ + @Override + public Document describe(Document data, CallContext context) { + log.debug("SelectProductArtifact.describe()"); + + // create root node + Document document = XMLUtils.newDocument(); + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + Element rootNode = creator.create("result"); + Element typeNode = creator.create("type"); + creator.addAttr(typeNode, "name", "describe"); + rootNode.appendChild(typeNode); + + Element uuidNode = creator.create("uuid"); + creator.addAttr(uuidNode, "value", super.identifier); + rootNode.appendChild(uuidNode); + + Element hashNode = creator.create("hash"); + creator.addAttr(hashNode, "value", hash()); + rootNode.appendChild(hashNode); + + // create output node + Element out = creator.create("outputs"); + rootNode.appendChild(out); + + // create current state + Element state = creator.create("state"); + creator.addAttr(state, "name", "choose-product"); + creator.addAttr(state, "description", "Auswahl des Produktes."); + rootNode.appendChild(state); + + // create reachable states + Element rStates = creator.create("reachable-states"); + appendProducts(document, rStates, context); + rootNode.appendChild(rStates); + + // create model + Element model = creator.create("model"); + Element input = creator.create("input"); + creator.addAttr(input, "name", "product"); + creator.addAttr(input, "type", "String"); + model.appendChild(input); + rootNode.appendChild(model); + + // create ui + Element ui = creator.create("ui"); + Element staticNode = creator.create("static"); + Element dynamic = creator.create("dynamic"); + + appendFis(document, staticNode, context, this.name); + appendSelectProducts(document, dynamic, context.getMeta()); + ui.appendChild(staticNode); + ui.appendChild(dynamic); + rootNode.appendChild(ui); + + document.appendChild(rootNode); + + return document; + } + + + /** + * + * @param document + * @param out + * @param context + * @throws IOException + */ + @Override + public void out(Document document, OutputStream out, CallContext context) + throws IOException + { + log.debug("SelectProductArtifact.out()"); + if (artifact != null) { + artifact.out(document, out, context); + } + } + + + /** + * Append products to the describe document. + * + * @param document The describe document. + * @param parent The node the products should be appended to. + * @param context The CallContext object. + */ + protected void appendProducts( + Document document, + Node parent, + Object context + ) { + Iterator iter = products.values().iterator(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + while(iter.hasNext()) { + Product prod = (Product) iter.next(); + String name = prod.getName(); + + Element current = creator.create("state"); + creator.addAttr(current, "name", name); + creator.addAttr(current, "description", name); + parent.appendChild(current); + } + } + + + /** + * Append the product select box to the user interface description of the + * describe document. + * + * @param document The describe document. + * @param node The node the products should be appended to. + * @param callMeta The CallMeta object. + */ + protected void appendSelectProducts( + Document document, + Node node, + CallMeta callMeta + ) { + RessourceFactory ressource = RessourceFactory.getInstance(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + XFORM_URL, + XFORM_PREFIX + ); + + String selectboxName = "product"; + Element selectNode = creator.create("select1"); + creator.addAttr(selectNode, "ref", selectboxName); + + Element lableNode = creator.create("label"); + lableNode.setTextContent(ressource.getRessource(callMeta.getLanguages(), + selectboxName, + selectboxName + ) + ); + + Element choiceNode = creator.create("choices"); + selectNode.appendChild(lableNode); + selectNode.appendChild(choiceNode); + + Iterator it = products.values().iterator(); + while (it.hasNext()) { + Product p = (Product) it.next(); + Element itemNode = creator.create("item"); + Element choiceLableNode = creator.create("label"); + choiceLableNode.setTextContent(ressource.getRessource( + callMeta.getLanguages(), + p.getName(), + p.getName() + )); + itemNode.appendChild(choiceLableNode); + + Element choiceValueNode = creator.create("value"); + choiceValueNode.setTextContent(p.getName()); + itemNode.appendChild(choiceValueNode); + choiceNode.appendChild(itemNode); + } + + node.appendChild(selectNode); + } + + + /** + * Create a feed document. + * + * @param uuid The UUID of the current artifact. + * @param hash The hash of the current artifact. + * @return the feed document. + */ + protected Document feedDocument(String uuid, String hash) { + Document document = XMLUtils.newDocument(); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + Element rootNode = creator.create("action"); + + Element typeNode = creator.create("type"); + creator.addAttr(typeNode, "name", "feed"); + rootNode.appendChild(typeNode); + + Element uuidNode = creator.create("uuid"); + creator.addAttr(uuidNode, "value", uuid); + rootNode.appendChild(uuidNode); + + Element hashNode = creator.create("hash"); + creator.addAttr(hashNode, "value", hash); + rootNode.appendChild(hashNode); + + Element dataNode = creator.create("data"); + rootNode.appendChild(dataNode); + + Collection parameter = this.current.getParameter(); + if (parameter != null) { + Iterator parameterIt = parameter.iterator(); + + while (parameterIt.hasNext()) { + InputData inputData = parameterIt.next(); + + Element inputNode = creator.create("input"); + creator.addAttr(inputNode, "name", inputData.getName()); + creator.addAttr(inputNode, "value", inputData.getValue()); + dataNode.appendChild(inputNode); + } + } + document.appendChild(rootNode); + return document; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes providing a special artifact used after a fis is +selected and the user needs to choose a concrete product. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/DefaultProduct.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,66 @@ +package de.intevation.gnv.artifacts.fis.product; + +import de.intevation.gnv.state.InputData; + +import java.util.Collection; + +/** + * This is the default implementation of Product. + * + * @author Tim Englich + * + */ +public class DefaultProduct implements Product { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 6473812725442092770L; + + private String name = null; + + private Collection parameter = null; + + private String artifactFactory = null; + + /** + * Constructor + * + * @param name The name of this product. + * @param parameter Required parameters for this product. + * @param artifactFactory The artifact factory. + */ + public DefaultProduct( + String name, + Collection parameter, + String artifactFactory + ) { + super(); + this.name = name; + this.parameter = parameter; + this.artifactFactory = artifactFactory; + } + + /** + * @return the name if this product. + */ + public String getName() { + return this.name; + } + + /** + * @return the input data. + */ + public Collection getParameter() { + return this.parameter; + } + + /** + * @return the artifact factory. + */ + public String getArtifactFactory() { + return this.artifactFactory; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/Product.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,40 @@ +package de.intevation.gnv.artifacts.fis.product; + +import de.intevation.gnv.state.InputData; + +import java.io.Serializable; + +import java.util.Collection; + +/** + * This is the interface description of Product. Currently, there + * are three methods defined:
+ *

    + *
  1. getName(): retrieves the name of the Product
  2. + *
  3. getParameter(): retrieves a collection of required parameters.
  4. + *
  5. getArtifactFactory(): retrieves the factory used to create this artifact. + *
  6. + *
+ * @author Tim Englich + */ +public interface Product extends Serializable { + + /** + * + * @return The name of this product. + */ + public String getName(); + + /** + * + * @return All required parameters for parameterization. + */ + public Collection getParameter(); + + /** + * + * @return The artifact factory used to create the current artifact. + */ + public String getArtifactFactory(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/fis/product/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +Classes and interfaces representing a product (eg 'Horizontalschnitt', +'Horizontalprofil', 'Vertikalprofil', 'Profilschnitt', 'Zeitserien'). + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +Map user workflows to software components using classes and interfaces in this +package. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/ressource/RessourceFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,174 @@ +package de.intevation.gnv.artifacts.ressource; + +import de.intevation.artifacts.PreferredLocale; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class RessourceFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(RessourceFactory.class); + + /** + * The singleton Instance of this Factory. + */ + private static RessourceFactory instance = null; + + private static String RESSOURCE_BASE_ID = "artifact.ressource.dir"; + + private static String ressourceName = "artifactMessages"; + private static String DEFAULT_DIR = "lang"; + private static String LANG_CONFIG_FILE = "lang.conf"; + + private String ressourceDir = null; + + private Locale[] locales = null; + + /** + * Basic-Constructor of this Class + */ + private RessourceFactory() { + super(); + ressourceDir = System.getProperty(RESSOURCE_BASE_ID, DEFAULT_DIR); + } + + /** + * This Method provides an singleton Instance of this Class. + * + * @return an singleton Instance of this Class + */ + public static synchronized RessourceFactory getInstance() { + if (instance == null) { + instance = new RessourceFactory(); + } + return instance; + } + + + /** + * This method reads locales, configured in LANG_CONFIG_FILE, from + * filesystem and returns them as array. + * + * @return Array of locales supported by the the server. + */ + public Locale[] getLocales() { + + if (locales != null) + return locales; + + log.debug("Supported locales have not been read - read now."); + try { + String config = "/" + ressourceDir + "/" + LANG_CONFIG_FILE; + InputStream in = RessourceFactory.class.getResourceAsStream(config); + + BufferedReader reader = new BufferedReader( + new InputStreamReader(in) + ); + + String line = null; + String country = null; + String language = null; + int idx = -1; + + List tmpLocales = new ArrayList(); + + while((line = reader.readLine()) != null) { + // validate if defined locale has a valid length + if (line.length() != 2 && line.length() != 5) { + log.warn("Illegal locale definition found."); + continue; + } + + idx = line.indexOf("_"); + if (idx > 0) { + // found locale containing language and country code + language = line.substring(0, idx); + country = line.substring(idx+1); + tmpLocales.add(new Locale(language, country)); + } + else { + // found locale containing languagey code only + tmpLocales.add(new Locale(line)); + } + } + + locales = (Locale[]) tmpLocales.toArray( + new Locale[tmpLocales.size()] + ); + + return locales; + } + catch (FileNotFoundException fnfe) { + log.warn("File not found: " + LANG_CONFIG_FILE, fnfe); + } + catch (IOException ioe) { + log.warn(ioe.getLocalizedMessage(), ioe); + } + + return null; + } + + + /** + * Deliveres the translated Value for an Key to an given Language + * + * @param preferredLocales + * @param key the key + * @param defaultValue the Value that should be returned. + * @return the translated Value + */ + public String getRessource(PreferredLocale[] preferredLocales, String key, + String defaultValue) { + if (key == null || preferredLocales.length == 0) { + return defaultValue; + } + + return getRessource(preferredLocales[0].getLocale(), key, defaultValue); + } + + + /** + * Deliveres the language specific value for the given key + * + * @param locale + * @param key + * @param defaultVal + * @return language specific string. + */ + public String getRessource(Locale locale, String key, String defaultVal) { + if (key == null || locale == null) + return defaultVal; + + try { + ResourceBundle rb = ResourceBundle.getBundle( + ressourceDir + "/" + ressourceName, + locale + ); + + return rb.getString(key); + } + catch (MissingResourceException mre) { + log.warn("No resource bundle: " + locale.toString(), mre); + return defaultVal; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/ressource/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/ressource/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Classes to handle working with resources. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,450 @@ +package de.intevation.gnv.artifacts.services; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.artifactdatabase.DefaultService; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.artifacts.ServiceFactory; +import de.intevation.gnv.artifacts.services.requestobjects.DefaultFIS; +import de.intevation.gnv.artifacts.services.requestobjects.DefaultLayer; +import de.intevation.gnv.artifacts.services.requestobjects.DefaultMapService; +import de.intevation.gnv.artifacts.services.requestobjects.DefaultParameter; +import de.intevation.gnv.artifacts.services.requestobjects.FIS; +import de.intevation.gnv.artifacts.services.requestobjects.Layer; +import de.intevation.gnv.artifacts.services.requestobjects.MapService; +import de.intevation.gnv.artifacts.services.requestobjects.Parameter; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.utils.ArtifactXMLUtilities; + +/** + * This Class Provides the Functionality to return only those + * Artifacfactories which fulfill the conditions of the Request. + * + * This Service is used to implement the Functionality of the MV-GNV-Interface + * by looking if an Region of an FIS is intersecting the Area which is send + * during the Request or which FIS belongs to the requested MapServices. + * + * @author Tim Englich + * + */ +public class MetaDataService extends DefaultService { + + /** + * the logger, used to log exceptions and additionally information + */ + private static Logger log = Logger.getLogger(MetaDataService.class); + + + private final static String FIS_REGION_QUERY_ID = + "mapviewer_interface_fis_region"; + private final static String MAPSERVICES_HAS_FIS_QUERY_ID = + "mapviewer_interface_mapservices_has_fis"; + private final static String MAPSERVICES_HAS_PARAMETER_QUERY_ID = + "mapviewer_interface_mapservices_has_parameter"; + + private final static String MAPSERVICES_HAS_PARAMETER_USING_LAYER_QUERY_ID = + "mapviewer_interface_mapservices_has_parameter_using_layer"; + + private static String ATTRIBUTE_ID = "id"; + private static String ATTRIBUTE_NAME = "name"; + private static String ATTRIBUTE_TYPE = "type"; + private static String ATTRIBUTE_URL = "url"; + private static String ATTRIBUTE_GROUPLAYER = "isgrouplayer"; + private static String ATTRIBUTE_PARENTID = "parentid"; + private static String ATTRIBUTE_SRS = "srs"; + + + private static String XPATH_LOACTION_NODE = "art:GetMetaData/art:location"; + private static String XPATH_MAPSERVICES_NODESET = "art:GetMetaData/" + + "art:mapservices/" + + "art:mapservice"; + private static String XPATH_LAYER_NODESET = "art:layer"; + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -8446483887497236372L; + + /** + * Constructor + */ + public MetaDataService() { + super(); + } + + @Override + public Document process(Document data, Object globalContext, + CallMeta callMeta) { + log.debug("MetaDataService.process"); + Document document = null; + try { + Geometry g = this.parseGeometry(data); + Collection mapServices = this.parseMapServices(data); + Collection resultFIS = this.unionFIS(this.getFIS(g), + this.getFIS(mapServices)); + document = XMLUtils.newDocument(); + this.writeFIS2Document(document, resultFIS); + log.debug(ArtifactXMLUtilities.writeDocument2String(document)); + } catch (MetaDataServiceException e) { + log.error(e,e); + document = ArtifactXMLUtilities + .createExceptionReport(e.getMessage(), document); + } + return document; + } + + private Geometry parseGeometry(Document data) + throws MetaDataServiceException{ + log.debug("MetaDataService.parseGeometry"); + + Element locationNode = (Element) XMLUtils.xpath( + data, + XPATH_LOACTION_NODE, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE + ); + Geometry returnValue = null; + if (locationNode != null) { + String srs = locationNode.getAttribute(ATTRIBUTE_SRS); + // TODO: use SRS to transform the Geometry to target-System. + String geometryValue = locationNode.getTextContent(); + if (geometryValue != null){ + try { + returnValue = new WKTReader().read(geometryValue); + } catch (ParseException e) { + log.error(e,e); + throw new MetaDataServiceException("The given Geometry" + + "String is not a " + + "valid WKT."); + } + } + } + return returnValue; + } + + private Collection parseMapServices(Document data){ + log.debug("MetaDataService.parseMapServices"); + + NodeList mapServices = (NodeList) XMLUtils.xpath(data, + XPATH_MAPSERVICES_NODESET, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + Collection returnValue = null; + if (mapServices != null){ + returnValue = new ArrayList(mapServices.getLength()); + for (int i = 0; i < mapServices.getLength(); i++){ + Element mapServiceNode = (Element)mapServices.item(i); + String id = mapServiceNode.getAttribute(ATTRIBUTE_ID); + String type = mapServiceNode.getAttribute(ATTRIBUTE_TYPE); + String url = mapServiceNode.getAttribute(ATTRIBUTE_URL); + Collection layer = null; + + NodeList layerNodes = (NodeList) XMLUtils.xpath(mapServiceNode, + XPATH_LAYER_NODESET, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + if (layerNodes != null){ + layer = new ArrayList(layerNodes.getLength()); + for (int j = 0; j < layerNodes.getLength(); j++){ + Element layerNode = (Element)layerNodes.item(j); + String layerId = layerNode.getAttribute(ATTRIBUTE_ID); + String layerName = layerNode.getAttribute(ATTRIBUTE_NAME); + boolean isGroupLayer = + Boolean.parseBoolean(layerNode + .getAttribute( + ATTRIBUTE_GROUPLAYER)); + String parentId = layerNode + .getAttribute(ATTRIBUTE_PARENTID); + + layer.add(new DefaultLayer(layerId, + layerName, + isGroupLayer, + parentId)); + } + } + MapService mapService = new DefaultMapService(id, layer, + type, url); + returnValue.add(mapService); + + } + } + return returnValue; + } + + private Collection unionFIS(Collection fromGeometry, + Collection fromMapservices){ + log.debug("MetaDataService.unionFIS"); + Collection returnValue = null; + if (fromGeometry == null || fromGeometry.isEmpty()){ + returnValue = fromMapservices; + }else if (fromMapservices == null || fromMapservices.isEmpty()){ + returnValue = fromGeometry; + }else{ + + returnValue = new ArrayList(); + Iterator it = fromMapservices.iterator(); + while (it.hasNext()){ + FIS fis = it.next(); + if (fromGeometry.contains(fis)){ + returnValue.add(fis); + } + } + } + return returnValue; + } + + /** + * Puts the retrieved FIS into the given XML-Document. + * @param document the Document where the FIS should be put in. + * @param fis the retrieved FIS which should be written into + * the XML-Document. + */ + private void writeFIS2Document(Document document, Collection fis){ + + if (fis != null){ + Iterator it = fis.iterator(); + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + Node rootNode = creator.create("result"); + document.appendChild(rootNode); + + Node factoriesNode = creator.create("factories"); + rootNode.appendChild(factoriesNode); + while (it.hasNext()){ + FIS tmpFIS = it.next(); + Element fisNode = creator.create("factory"); + fisNode.setAttribute("art:name",tmpFIS.getID()); + + Collection parameter = tmpFIS.getParameter(); + + if(parameter != null){ + Iterator pit = parameter.iterator(); + while (pit.hasNext()){ + Parameter p = pit.next(); + Element parameterNode = creator.create("parameter"); + parameterNode.setAttribute(ATTRIBUTE_ID, p.getID()); + parameterNode.setAttribute(ATTRIBUTE_NAME, p.getName()); + fisNode.appendChild(parameterNode); + } + } + factoriesNode.appendChild(fisNode); + } + } + } + + /** + * Returns all FIS which Areas is intersected by this given Geometry + * @param g the Geometry which should be used to determine the FIS. + * @return all FIS which Areas is intersected by this given Geometry + * @throws MetaDataServiceException + */ + protected Collection getFIS(Geometry g) + throws MetaDataServiceException{ + log.debug("MetaDataService.getFIS ==> Geometry"); + Collection resultValue = null; + if (g != null){ + try { + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + Collection result = queryExecutor.executeQuery(FIS_REGION_QUERY_ID, + new String[]{g.toString()}); + + if (result != null){ + resultValue = new ArrayList(result.size()); + Iterator it = result.iterator(); + while (it.hasNext()){ + Result value = it.next(); + String fis_id = value.getString(0).trim(); + resultValue.add(new DefaultFIS(fis_id)); + } + } + } catch (QueryException e) { + log.error(e,e); + throw new MetaDataServiceException("Cannot Query FIS from DB."); + } + } + return resultValue; + } + + /** + * Returns all FIS which were represented by the given Mapservices + * @param mapServices the Mapservices which should determine the FIS. + * @return all FIS which where represented my the given Mapservices. + * @throws MetaDataServiceException + */ + protected Collection getFIS(Collection mapServices) + throws MetaDataServiceException{ + log.debug("MetaDataService.getFIS ==> MapServices"); + Collection resultValue = null; + if (mapServices != null && !mapServices.isEmpty()){ + try { + + String mapServiceNames = ""; + Iterator mit = mapServices.iterator(); + while(mit.hasNext()){ + if (mapServiceNames.length() > 0){ + mapServiceNames += " , "; + } + mapServiceNames += "'"+mit.next().getID()+"'"; + } + + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + Collection result = queryExecutor.executeQuery( + MAPSERVICES_HAS_FIS_QUERY_ID, + new String[]{mapServiceNames}); + if (result != null){ + resultValue = new ArrayList(result.size()); + Iterator it = result.iterator(); + while (it.hasNext()){ + Result value = it.next(); + String fisId = value.getString(0).trim(); + String mapServiceID = value.getString(1).trim(); + + // FIRST LOOK IF ONE MAPSERVICE REPRESENTS ONLY ONE PARAM + Collection result2 = queryExecutor.executeQuery( + MAPSERVICES_HAS_PARAMETER_QUERY_ID, + new String[]{"'"+mapServiceID+"'"}); + Collection parameter = null; + if (result2 != null && result2.size() == 1){ + Iterator it2 = result2.iterator(); + parameter = new ArrayList(1); + while (it2.hasNext()){ + Result parameterValue = it2.next(); + String parameterID = parameterValue.getString(0) + .trim(); + parameter.add(new DefaultParameter(parameterID, + parameterID)); + } + }else{ + // IF FALSE LOOK IF THE GIVEN LAYERs TO AN MAPSERVICE + // REPRESENTS DIFFERENT PARAMS + MapService service = this.getMapService(mapServices, + mapServiceID); + Collection layer = service.getLayer(); + if (layer != null && !layer.isEmpty()){ + String layerQueryString = + this.createLayerQueryString(layer); + Collection parameterResult = + queryExecutor.executeQuery( + MAPSERVICES_HAS_PARAMETER_USING_LAYER_QUERY_ID, + new String[]{"'"+mapServiceID+"'", + layerQueryString}); + if (parameterResult != null && + !parameterResult.isEmpty()){ + Iterator it2 = parameterResult.iterator(); + parameter = new ArrayList(parameterResult.size()); + while (it2.hasNext()){ + Result parameterValue = it2.next(); + String parameterID = parameterValue.getString(0) + .trim(); + parameter.add(new DefaultParameter(parameterID, + parameterID)); + } + } + } + + } + + FIS fis = this.getFIS(resultValue, fisId); + if (fis != null){ + if (parameter != null){ + fis.addParameter(parameter); + } + }else{ + resultValue.add(new DefaultFIS(fisId, parameter)); + } + } + } + } catch (QueryException e) { + log.error(e,e); + throw new MetaDataServiceException("Cannot Query FIS from DB."); + } + + } + return resultValue; + } + + + private FIS getFIS (Collection fis, String fisId){ + + Iterator it = fis.iterator(); + while(it.hasNext()){ + FIS tmpFIS = it.next(); + if (tmpFIS.getID().equals(fisId)){ + return tmpFIS; + } + } + return null; + } + + private MapService getMapService(Collection mapServices, + String mapServiceID){ + log.debug("MetaDataService.getMapService"); + Iterator it = mapServices.iterator(); + while (it.hasNext()){ + MapService service = it.next(); + if (service.getID().equals(mapServiceID)){ + return service; + } + } + return null; + } + + private String createLayerQueryString(Collection layer){ + log.debug("MetaDataService.createLayerQueryString"); + StringBuffer sb = new StringBuffer();; + Iterator it = layer.iterator(); + synchronized (sb) { + while (it.hasNext()){ + Layer l = it.next(); + if (!l.isGroupLayer()){ + sb.append(l.getID()); + if (it.hasNext()){ + sb.append(" , "); + } + } + + } + } + String returnValue = sb.toString(); + if (returnValue.endsWith(" , ")){ + returnValue = returnValue.substring(0,returnValue + .lastIndexOf(",")) + .trim(); + } + return returnValue; + } + + @Override + public void setup(ServiceFactory factory, Object globalContext) { + log.debug("MetaDataService.setup"); + super.setup(factory, globalContext); + // TODO: Perhaps it is necessary to init the QueryIds here. + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataServiceException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataServiceException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.artifacts.services; + +/** + * ExceprionClass for MetaDataServices. + * @author Tim Englich + * + */ +public class MetaDataServiceException extends Exception { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -7489185270678994565L; + + /** + * Constructor + */ + public MetaDataServiceException() { + super(); + } + + /** + * Constructor + * @param arg0 + */ + public MetaDataServiceException(String arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + */ + public MetaDataServiceException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public MetaDataServiceException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + +This package provides Classes which Implements the Interface +de.intevation.artifactdatabase.Service +to provide different Services offered by the ArtifactDatabase. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultFIS.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,97 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +import java.util.Collection; +import java.util.Iterator; + +/** + * The default implementation of Fis. + * + * @author Tim Englich + * + */ +public class DefaultFIS implements FIS { + + /** + * The ID of the FIS + */ + private String id = null; + + /** + * The Parameter which belongs to the FIS. + */ + private Collection parameter = null; + + /** + * Constructor + * + * @param id The id for this fis. + */ + public DefaultFIS(String id){ + super(); + this.id = id; + } + /** + * Constructor + * @param id The id for this fis. + * @param parameter A collection of parameters. + */ + public DefaultFIS(String id, Collection parameter) { + this(id); + this.parameter = parameter; + } + + + public String getID() { + return this.id; + } + + public Collection getParameter() { + return this.parameter; + } + + /** + * Two objects are equal if they have the same id. + * + * @param arg0 Object which is checked for equality. + * @return True, if both objects are equal, otherwise false. + */ + @Override + public boolean equals(Object arg0) { + boolean returnValue = false; + if (arg0 instanceof FIS){ + returnValue = this.id.equals(((FIS)arg0).getID()); + } + return returnValue; + } + + /** + * Creates a hash code using the id and the given parameters. + * + * @return A hash code. + */ + @Override + public int hashCode() { + int hash = 7; + hash = 47 * hash + (this.id != null ? this.id.hashCode() : 0); + hash = 47 * hash + (this.parameter != null ? this.parameter.hashCode() : 0); + return hash; + } + + /** + * @param parameter Collection of parameters. + */ + public void addParameter(Collection parameter) { + if (this.parameter != null){ + Iterator it = parameter.iterator(); + while (it.hasNext()){ + Parameter tmpParameter = it.next(); + if (!this.parameter.contains(tmpParameter)){ + this.parameter.add(tmpParameter); + } + } + }else{ + this.parameter = parameter; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultLayer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,75 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +/** + * The default Implementation of Layer. + * + * @author Tim Englich + * + */ +public class DefaultLayer implements Layer { + + /** + * The id of the Layer + */ + private String id = null; + + /** + * The name of the Layer + */ + private String name = null; + + /** + * Flag which defines if the Layer is a GroupLayer + */ + private boolean groupLayer = false; + + /** + * The ID of the Parentlayer or null if the Layer is a Rootlayer + */ + private String parentId = null; + + /** + * Constructor + * @param id The id of this layer. + * @param name The name of this layer. + * @param groupLayer A boolean property to define this layer as group layer. + * @param parentId The id of the parent layer. + */ + public DefaultLayer(String id,String name, + boolean groupLayer,String parentId) { + this.id = id; + this.name = name; + this.groupLayer = groupLayer; + this.parentId = parentId; + } + + public String getID() { + return this.id; + } + + public String getName() { + return this.name; + } + + public boolean isGroupLayer() { + return this.groupLayer; + } + + public String parentID() { + return this.parentId; + } + + /** + * This methods returns this layer as string. + * + * @return this layer as string. + */ + @Override + public String toString() { + return "ID: "+ this.id + " Name: "+this.name+ + " IsGroupLayer: "+this.groupLayer+ + " ParentID: "+this.parentId; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultMapService.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +import java.util.Collection; + +/** + * The default Implementation of MapService. + * + * @author Tim Englich + * + */ +public class DefaultMapService implements MapService { + + /** + * The id of the Mapservice + */ + private String id = null; + + /** + * The Layer which belongs to the Mapservice + */ + private Collection layer = null; + + /** + * The Type of the Mapservice + */ + private String type = null; + + /** + * The Url under which the Mapservice could be accessed. + */ + private String url = null; + + /** + * Constructor + * @param id The id of this service. + * @param type The type of this service. + * @param layer The layers available in this service. + * @param url The url used to call this service. + */ + public DefaultMapService(String id, Collection layer, + String type, String url) { + super(); + this.id = id; + this.layer = layer; + this.type = type; + this.url = url; + } + + public String getID() { + return this.id; + } + + public Collection getLayer() { + return this.layer; + } + + public String getType() { + return this.type; + } + + public String getURL() { + return this.url; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/DefaultParameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,40 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +/** + * The default Implementation of Parameter. + * + * @author Tim Englich + */ +public class DefaultParameter implements Parameter { + + + /** + * The id of the Parameter + */ + private String id = null; + + /** + * The name of the Parameter + */ + private String name = null; + + /** + * Constructor + * @param id The id of this parameter. + * @param name The name of this parameter. + */ + public DefaultParameter(String id, String name) { + super(); + this.id = id; + this.name = name; + } + + public String getID() { + return this.id; + } + + public String getName() { + return this.name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/FIS.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,40 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +import java.util.Collection; + +/** + * This is the interface description for a fis. Currently, there are three + * methods defined which need to be implemented by concrete classes:
+ *
    + *
  1. getID(): Returns the id of this fis.
  2. + *
  3. getParameter(): Returns a collection of parameter.
  4. + *
  5. addParameter(Collection): Adds a parameter collection to this + * fis.
  6. + *
+ * + * @author Tim Englich + * + */ +public interface FIS { + + /** + * Returns the id of this FIS + * @return the id of this fis. + */ + String getID(); + + /** + * Returns a collection of Parameters which belongs to the FIS. + * @return a collection of parameters. + */ + Collection getParameter(); + + /** + * Add a collection of parameters to this fis. + * + * @param parameter Some parameters. + */ + void addParameter(Collection parameter); + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Layer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Layer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +/** + * This is the inteface description of a Layer. Currently, there + * are four methods defined here:
+ *
    + *
  1. getName(): Returns the name of this layer.
  2. + *
  3. getID(): Returns the id of this layer.
  4. + *
  5. isGroupLayer(): Returns true, if this layer contains child layers.
  6. + *
  7. parentID(): Returns the id of the parent layer if this layer is a + * group layer.
  8. + *
+ * + * @author Tim Englich + * + */ +public interface Layer { + + /** + * Returns the name of this layer. + * @return the name of this layer. + */ + String getName(); + + /** + * Returns the id of this layer. + * @return the id of this layer. + */ + String getID(); + + /** + * Returns true if the Layer is an GroupLayer + * @return true, if this layer is a group layer - otherwise false. + */ + boolean isGroupLayer(); + + /** + * Returned the ID of the Parent Layer. + * Only if the Layer is a Child-Layer. + * If this Layer is an Root-Layer null will be returned. + * @return the id of the parent. + */ + String parentID(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/MapService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/MapService.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +import java.util.Collection; + +/** + * This is the interface description of MapService. Currently, + * there are four methods defined:
+ *
    + *
  1. getID(): Returns the id of this service.
  2. + *
  3. getURL(): Returns the url used to call this service.
  4. + *
  5. getType(): Returns the service type.
  6. + *
  7. getLayer(): Returns a collection of layers contained in this service. + *
  8. + *
+ * + * @author Tim Englich + * + */ +public interface MapService { + + + /** + * Returns the id of this Service. + * @return the id of this service. + */ + String getID(); + + /** + * Returns the Url under which this service is available. + * @return the url under which this service is available. + */ + String getURL(); + + /** + * Returns the service type + * @return the service type. + */ + String getType(); + + /** + * Returns the Layer which belongs to this Service. + * @return a collection of layers contained in this service. + */ + Collection getLayer(); + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Parameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/Parameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,27 @@ +package de.intevation.gnv.artifacts.services.requestobjects; + +/** + * This is the interface description of Parameter. Currently, there + * are two methods defined:
+ *
    + *
  1. getName(): Returns the name of this parameter.
  2. + *
  3. getID(): Returns the id of this parameter.
  4. + *
+ * + * @author Tim Englich + */ +public interface Parameter { + + /** + * The Name of this Parameter + * @return the name of this parameter. + */ + String getName(); + /** + * The ID of this Parameter + * @return the id of this parameter. + */ + String getID(); + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/requestobjects/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + +This package provides Interfaces and Classes which are required to represent the +Objects which are required to handle all Servicerequests which are defined in the +Parentpackage. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +package de.intevation.gnv.chart; + +import java.util.Collection; +import java.util.Locale; + +import org.jfree.chart.ChartTheme; +import org.jfree.chart.JFreeChart; + +/** + * Abstract chart class to define the basic fields used for chart creation. + * + * @author Ingo Weinzierl + */ +public abstract class AbstractChart +implements Chart +{ + /** + * JFreeChart object. Created after {@link #generateChart()} is called. + */ + protected JFreeChart chart; + + /** + * Field storing the visibility of lines in the chart plot. + */ + protected boolean linesVisible; + + /** + * Field storing the visibility of points in the chart plot. + */ + protected boolean shapesVisible; + + /** + * Locale object used for i18n support. + */ + protected Locale locale; + + /** + * ChartLabels + */ + protected ChartLabels labels; + + /** + * ChartTheme + */ + protected ChartTheme theme; + + /** + * Collection which contains a bunch of parameters. + */ + protected Collection parameters; + + /** + * Collection which contains a bunch of measurements. + */ + protected Collection measurements; + + /** + * Collection which contains all data objects used to be displayed in the + * chart. It contains different series and different datasets which is not + * very elegant. + */ + protected Collection resultSet; + + /** + * Collection which contains a bunch of date objects. + */ + protected Collection dates; + + /** + * Collection which contains a bunch of time gap definitions used to + * detect gaps in timeseries charts. + */ + protected Collection timeGaps; + + /** + * Abstract method which needs to be implemented by concrete subclasses. + * This method triggers the JFreeChart creation process. After calling this + * method {@link #chart} should be a valid JFreeChart object. + */ + public abstract JFreeChart generateChart(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractHistogram.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractHistogram.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,118 @@ +package de.intevation.gnv.chart; + +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartTheme; +import org.jfree.chart.JFreeChart; + +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +import org.jfree.chart.renderer.xy.XYBarRenderer; + +/** + * This abstract class defines some methods to adjust chart settings after its + * creation. + * + * @author Ingo Weinzierl + */ +public abstract class AbstractHistogram +implements Chart +{ + /** + * Logger used for logging with Apache log4j. + */ + private Logger logger = Logger.getLogger(AbstractHistogram.class); + + /** + * JFreeChart chart stored at this place after chart creation. + */ + protected JFreeChart chart; + + /** + * Labels used for chart title, subtitle, axis description. + */ + protected ChartLabels labels; + + /** + * Theme which is used to adjust the styling of this chart. + */ + protected ChartTheme theme; + + /** + * Raw data which should be displayed in the chart. + */ + protected Object[] data; + + /** + * Locale object used for i18n support. + */ + protected Locale locale; + + + /** + * Constructor for creating histogram charts. + * + * @param labels See {@link #labels} + * @param data See {@link #data} + * @param theme See {@link #theme} + */ + public AbstractHistogram( + ChartLabels labels, Object[] data, ChartTheme theme + ) { + this.labels = labels; + this.data = data; + this.theme = theme; + } + + + /** + * @see de.intevation.gnv.chart.Chart#generateChart() + */ + public JFreeChart generateChart() { + + if (chart != null) + return chart; + + chart = ChartFactory.createHistogram( + labels.getTitle(), + labels.getDomainAxisLabel(), + labels.getRangeAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + applyDatasets(); + + theme.apply(chart); + adjustPlot(); + + return chart; + } + + + /** + * Method to do some changes in plot settings. + */ + protected void adjustPlot() { + XYPlot plot = (XYPlot) chart.getPlot(); + XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer(); + + renderer.setShadowVisible(false); + renderer.setSeriesVisibleInLegend(0, false); + } + + + /** + * This method needs to be implemented by subclasses and should add valid + * HistogramDataset objects to the created chart. It is called + * by {@link #generateChart} after chart creation. + */ + protected abstract void applyDatasets(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,442 @@ +package de.intevation.gnv.chart; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import java.awt.Color; + +import java.awt.geom.Ellipse2D; + +import java.text.NumberFormat; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.AxisLocation; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.NumberTickUnit; + +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; + +import org.jfree.chart.title.TextTitle; + +import org.jfree.data.Range; + +import org.jfree.data.general.Series; + +import org.jfree.data.xy.XYDataset; + +import org.jfree.ui.RectangleInsets; + +/** + * This abstract class defines some methods to adjust chart settings after its + * creation. + * + * @author Ingo Weinzierl + */ +public abstract class AbstractXYLineChart +extends AbstractChart +{ + /** + * Constant field used to expand the area between data and chart border. Its + * value is {@value}.
+ * A value of 0.05 equals 5 percent. + */ + public static final double LOWER_MARGIN = 0.05D; + + /** + * Constant field used to expand the area between data and chart border. Its + * value is {@value}.
+ * A value of 0.05 equals 5 percent. + */ + public static final double UPPER_MARGIN = 0.05D; + + /** + * Logger used to log with log4j. + */ + private static Logger log = Logger.getLogger(AbstractXYLineChart.class); + + /** + * Field of supported colors used for lines and data points in charts. + */ + protected static Color[] COLOR = { + Color.black, Color.red, Color.green, Color.blue, Color.yellow, + Color.gray, Color.orange, Color.pink, Color.cyan + }; + + /** + * Static field to remember the index of the previously used color. + */ + protected static int nextColor = 0; + + /** + * Default PlotOrientation. + */ + protected PlotOrientation PLOT_ORIENTATION = PlotOrientation.VERTICAL; + + /** + * Map to store datasets for each parameter. + */ + protected Map datasets; + + /** + * Map to store max ranges of each parameter (axis.setAutoRange(true) + * doesn't seem to work */ + protected Map ranges; + + /** + * This method is called by Chart to bring the data into the + * right form fitting to JFreeChart objects. + */ + protected abstract void initData(); + + /** + * Add a value of row to series. + * + * @param row Result Object returned from database. Contains + * a value used to add to series + * @param series A JFreeChart Series object. + */ + protected abstract void addValue(Result row, Series series); + + /** + * Add series to JFreeChart's Dataset object currently which is + * processing. + * + * @param series Series to add. + * @param label Label used show in legend. + * @param idx Currently not used. + */ + protected abstract void addSeries(Series series, String label, int idx); + + /** + * Abstract method which is called by Chart interface after + * chart creation. It turns an axis' label into a locale specific format. + * + * @param axis Axis to adjust. + * @param locale java.util.Locale object used specify the format. + */ + protected abstract void localizeDomainAxis(Axis axis, Locale locale); + + /** + * Abstract method to create a label for a series of parameters. + * + * @param breakPoint1 Identifier returned from database. These identifier + * are used to identify the results from database which are all stored in + * one big java.util.Collection. + * @param breakPoint2 Identifier returned from database. + * @param breakPoint3 Identifier returned from database. + * + * @return Concatinated string of parameter name and measurement. + */ + protected abstract String createSeriesName( + String breakPoint1, + String breakPoint2, + String breakPoint3 + ); + + + /** + * @see de.intevation.gnv.chart.Chart#generateChart() + */ + public JFreeChart generateChart() { + log.debug("generate XYLineChart"); + nextColor = 0; + + if (chart != null) + return chart; + + initChart(); + + chart.addSubtitle(new TextTitle(labels.getSubtitle())); + + theme.apply(chart); + initData(); + + adjustPlot((XYPlot)chart.getPlot()); + + return chart; + } + + + protected void initChart() { + chart = ChartFactory.createXYLineChart( + labels.getTitle(), + labels.getDomainAxisLabel(), + null, + null, + PLOT_ORIENTATION, + true, + false, + false + ); + } + + + /** + * Method used to adjust the axes after chart generation. Methods for i18n + * support ({@link #localizeDomainAxis} and {@link #localizeRangeAxis}) are + * called and axes of this series are expanded. + * + * @param seriesKey Identifier of an axis which have to be adjusted. + * @param idx Set the axis identified by seriesKey to position + * idx. + */ + protected void prepareAxis(String seriesKey, int idx) { + log.debug("prepare axis of xychart"); + + XYPlot plot = chart.getXYPlot(); + Axis xAxis = plot.getDomainAxis(); + NumberAxis yAxis = new NumberAxis(seriesKey); + + localizeDomainAxis(xAxis, locale); + localizeRangeAxis(yAxis, locale); + + // litte workarround to adjust the max range of axes. + // NumberAxis.setAutoRange(true) doesn't seem to work properly. + Range yRange = (Range) ranges.get(seriesKey); + yAxis.setRange(Range.expand(yRange, LOWER_MARGIN, UPPER_MARGIN)); + log.debug("Max Range of dataset is: " + yRange.toString()); + + if (seriesKey.contains("richtung")) { + yAxis.setTickUnit(new NumberTickUnit(30.0)); + yAxis.setUpperBound(360.0); + yAxis.setLowerBound(0.0); + } + else { + yAxis.setFixedDimension(10.0); + yAxis.setAutoRangeIncludesZero(false); + } + + plot.setRangeAxis(idx, yAxis); + yAxis.configure(); + + if (idx % 2 != 0) + plot.setRangeAxisLocation(idx, AxisLocation.BOTTOM_OR_RIGHT); + else + plot.setRangeAxisLocation(idx, AxisLocation.BOTTOM_OR_LEFT); + + plot.mapDatasetToRangeAxis(idx, idx); + } + + + /** + * Method to adjust the rendering of a series in a chart. Line color and + * symbols of vertices are configured here. + * + * @param idx Position of the renderer. + * @param seriesCount Maximum number of series in this chart. + * @param renderLines Lines are displayed if true, otherwise they are not. + * @param renderShapes Vertices are displayed if true, otherwise they are + * not. + */ + protected void adjustRenderer( + int idx, + int seriesCount, + boolean renderLines, + boolean renderShapes + ) { + log.debug("Adjust render of series"); + XYLineAndShapeRenderer renderer = null; + XYPlot plot = chart.getXYPlot(); + + try { + renderer = (XYLineAndShapeRenderer)((XYLineAndShapeRenderer) + (plot.getRenderer())).clone(); + } + catch (CloneNotSupportedException cnse) { + log.warn("Error while cloning renderer.", cnse); + renderer = new XYLineAndShapeRenderer(renderLines, renderShapes); + renderer.setBaseShape(new Ellipse2D.Double(-2,-2,4,4)); + } + + for (int i = 0; i < seriesCount; i++) { + renderer.setSeriesShape(i, renderer.getSeriesShape(0)); + renderer.setSeriesPaint(i, COLOR[nextColor() % COLOR.length]); + renderer.setSeriesShapesVisible(i, renderShapes); + renderer.setSeriesLinesVisible(i, renderLines); + } + plot.setRenderer(idx, renderer); + } + + + /** + * @return Index of the next color + */ + protected static synchronized int nextColor() { + return nextColor++; + } + + + /** + * Method to adjust the plot rendering. Disable horizontal grid lines if + * plot contains only a single y-axis. + * + * @param plot JFreeChart Plot object to be adjusted. + */ + protected void adjustPlot(XYPlot plot) { + if (plot.getRangeAxisCount() > 1) + plot.setRangeGridlinesVisible(false); + + plot.setAxisOffset(new RectangleInsets(0, 0, 0, 15)); + } + + + /** + * Abstract method which is called after chart creation. It turns an + * axis' label into a locale specific format. + * + * @param axis Axis to adjust. + * @param locale java.util.Locale object used specify the format. + * + */ + protected void localizeRangeAxis(Axis axis, Locale locale) { + if (locale == null) + return; + + log.debug( + "Set language of axis [" + axis.getLabel() + "] " + + "to " + locale.toString() + ); + + NumberFormat format = NumberFormat.getInstance(locale); + ((NumberAxis) axis).setNumberFormatOverride(format); + } + + + /** + * Return the maximum y-range of dataset. + * + * @param dataset Dataset to be scaned. + * + * @return JFreeChart Range object containing min and max y-value. + */ + public Range getMaxRangeOfDataset(XYDataset dataset) { + int seriesCount = dataset.getSeriesCount(); + double upper = Double.NEGATIVE_INFINITY; + double lower = Double.POSITIVE_INFINITY; + + for (int i = 0; i < seriesCount; i++) { + int itemCount = dataset.getItemCount(i); + + for (int j = 0; j < itemCount; j++) { + Number num = dataset.getY(i, j); + + if (num != null) { + double y = num.doubleValue(); + lower = y < lower ? y : lower; + upper = y > upper ? y : upper; + } + } + } + + return new Range(lower, upper); + } + + + /** + * Return the maximum y-range of dataset with a margin of + * percent percent. + * + * @param dataset Dataset to be scaned. + * @param percent Percent used to expand the range. + * @return JFreeChart Range object containing min and max y-value with a + * margin. + */ + public Range getMaxRangeOfDatasetWithMargin( + XYDataset dataset, + double percent + ) { + Range range = getMaxRangeOfDataset(dataset); + double length = range.getLength(); + double upper = range.getUpperBound() + length /100 * percent; + double lower = range.getLowerBound() - length /100 * percent; + + return new Range(lower, upper); + } + + + /** + * Method to find a parameter specified by its value. + * + * @param label Search string. + * + * @return Value of a parameter with the given label. + */ + protected String findParameter(String label) { + Iterator iter = parameters.iterator(); + + while (iter.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) iter.next(); + String key = data.getValue(); + + if (label.indexOf(key) > -1) + return key; + } + + return label; + } + + + /** + * Method to find a description of a given collection of values. + * + * @param values Collection to be scaned. + * @param id Identifier and search string of the searched value. + * + * @return title + */ + protected String findValueTitle(Collection values, String id) { + log.debug("find description of dataset"); + + if (values != null){ + Iterator it = values.iterator(); + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + + if (id.equals(data.getKey())) + return data.getValue(); + } + } + return ""; + } + + + /** + * Method to store the maximum range. Since we need to adjust the range of + * each range axis, we have to memorize its range - each parameter uses an + * own range axis. + * + * @param ranges Map where ranges of each axis will be stored in. + * @param value A given value on an axis. + * @param parameter Parameter name which belongs to value. + */ + protected void storeMaxRange(Map ranges, double value, String parameter) { + Range range = null; + + range = ranges.containsKey(parameter) + ? (Range) ranges.get(parameter) + : new Range(value, value); + + double lower = range.getLowerBound(); + double upper = range.getUpperBound(); + + lower = value < lower ? value : lower; + upper = value > upper ? value : upper; + + ranges.put(parameter, new Range(lower, upper)); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,24 @@ +package de.intevation.gnv.chart; + +import java.io.Serializable; + +import org.jfree.chart.JFreeChart; + +/** + * The Chart interface should be implemented by each type of chart. + * The class must implement a method generateChart which returns a + * JFreeChart object. + * + * @author Ingo Weinzierl + */ +public interface Chart +extends Serializable +{ + /** + * This method is used to create a JFreeChart of this object. + * + * @return JFreeChart object. + */ + public JFreeChart generateChart(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartLabels.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartLabels.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,140 @@ +/* Copyright (C) 2007 con terra GmbH (http://www.conterra.de) + * All rights reserved + * + * $Id: ChartLabels.java,v 1.1 2007/12/10 13:57:13 drewnak Exp $ + * + * created by: drewnak + * created at : 10.12.2007 + * created at : 11:48:39 + * + * modified by: $Author: drewnak $ + * modified at: $Date: 2007/12/10 13:57:13 $ + */ +package de.intevation.gnv.chart; + +/** + * This class stores some strings used for decorating charts (e.g. title, + * subtitle, etc). + * + * @author drewnak + * @author Tim Englich Changes and codecleanup + * @author Ingo Weinzierl + */ +public class ChartLabels { + /** + * + */ + private String title; + + /** + * + */ + private String subtitle; + + /** + * + */ + private String domainAxisLabel; + + /** + * + */ + private String rangeAxisLabel; + + /** + * + */ + private String parameterName; + + + /** + * Constructor + * + * @param title Title + * @param subtitle Subtitle + * @param domainAxisLabel X-axis label + */ + public ChartLabels(String title, String subtitle, String domainAxisLabel) { + this(title, subtitle, domainAxisLabel, null); + } + + /** + * Constructor + * + * @param title Title + * @param subtitle Subtitle + * @param domainAxisLabel X-axis label + * @param rangeAxisLabel Y-axis label + */ + public ChartLabels( + String title, + String subtitle, + String domainAxisLabel, + String rangeAxisLabel + ) { + this(title, subtitle, domainAxisLabel, rangeAxisLabel, null); + } + + + /** + * Constructor + * + * @param title Title + * @param subtitle Subtitle + * @param domainAxisLabel X-axis label + * @param rangeAxisLabel Y-axis label + * @param parameterName Name of a given parameter in the chart. + */ + public ChartLabels( + String title, + String subtitle, + String domainAxisLabel, + String rangeAxisLabel, + String parameterName + ) { + this.title = title; + this.subtitle = subtitle; + this.domainAxisLabel = domainAxisLabel; + this.rangeAxisLabel = rangeAxisLabel; + this.parameterName = parameterName; + } + + /** + * @return the title + */ + public String getTitle() { + return this.title; + } + + + /** + * @return the subtitle + */ + public String getSubtitle() { + return subtitle; + } + + /** + * @return the timeAxisLabel + */ + public String getDomainAxisLabel() { + return this.domainAxisLabel; + } + + + /** + * @return the y-axis label + */ + public String getRangeAxisLabel() { + return this.rangeAxisLabel; + } + + + /** + * @return the parameter name + */ + public String getParameterName() { + return this.parameterName; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/DefaultHistogram.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/DefaultHistogram.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,262 @@ +package de.intevation.gnv.chart; + +import java.text.NumberFormat; +import java.text.ParseException; + +import java.util.Locale; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +import org.jfree.chart.plot.XYPlot; + +import org.jfree.data.statistics.HistogramDataset; + +/** + * Default implementation of {@link de.intevation.gnv.chart.AbstractHistogram}. + * + * @author Ingo Weinzierl + */ +public class DefaultHistogram +extends AbstractHistogram +{ + /** + * Default bin count. + * TODO find a better default value + */ + public static final int DEFAULT_BINS = 15; + + /** + * Constant field for limitating the number of bin in a single histogram. + */ + public static final int MAXIMAL_BINS = 20; + + /** + * Default key to retrieve the number of bins from {@link + * #requestParameter}. + */ + public static final String REQUEST_KEY_BIN_COUNT = "bincount"; + + /** + * Default key to retrieve the width of a single bin from {@link + * #requestParameter}. + */ + public static final String REQUEST_KEY_BIN_WIDTH = "binwidth"; + + /** + * Default key to retrieve the chart width from {@link #requestParameter}. + */ + public static final String REQUEST_KEY_CHART_WIDTH = "width"; + + /** + * Default key to retrieve the Locale object from {@link + * #requestParameter} used for i18n support. + */ + public static final String REQUEST_KEY_LOCALE = "locale"; + + /** + * Default key to retrieve the object from {@link #requestParameter}. It + * defines which value this chart has to be used for bin calculation. You + * can either adjust the number of bins or the width of a single bin. + */ + public static final String REQUEST_KEY_BIN_CHOICE = "bintype"; + + /** + * Logger used for logging with log4j. + */ + private static Logger logger = Logger.getLogger(DefaultHistogram.class); + + /** + * Object storing some further parameter used for chart settings. + */ + protected Map requestParameter; + + + /** + * Constructor to create DefaultHistogram objects. + * + * @param labels Labels to decorate this chart. + * @param data Raw data to be displayed in histogram. + * @param theme Theme used to adjust the chart look. + * @param requestParameter Object which serves some further settings. + */ + public DefaultHistogram( + ChartLabels labels, Object[] data, ChartTheme theme, Map requestParameter + ) { + super(labels, data, theme); + this.requestParameter = requestParameter; + } + + + @Override + protected void applyDatasets() { + XYPlot plot = (XYPlot) chart.getPlot(); + + // prepare data and create add them to histogram dataset + String name = (String) data[0]; + double[] values = toDouble((Double[]) data[1]); + int bins = getBinCount(values); + + HistogramDataset dataset = new HistogramDataset(); + dataset.addSeries(name, values, bins); + + plot.setDataset(0, dataset); + } + + + /** + * Method which scans the hole bunch of values and returns an array with + * contains min and max value. Min value is stored at position 0, max value + * is stored at position 1 in that array. + * + * @param values Array which contains all values + * + * @return Array which contains min and max value + */ + protected double[] getMinMax(double[] values) { + double[] minmax = new double[2]; + minmax[0] = Double.MAX_VALUE; + minmax[1] = Double.MIN_VALUE; + + int length = values.length; + for (int i = 0; i < length; i++) { + minmax[0] = values[i] < minmax[0] ? values[i] : minmax[0]; + minmax[1] = values[i] > minmax[1] ? values[i] : minmax[1]; + } + + return minmax; + } + + + /** + * Turn a Double[] into a double[]. + * + * @param array Doube[] + * + * @return double[] + */ + protected double[] toDouble(Double[] array) { + int length = array.length; + double[] values = new double[length]; + + for(int i = 0; i < length; i++) { + values[i] = array[i].doubleValue(); + } + + return values; + } + + + /** + * Method to calculate the number of bins this chart should be parted into. + * The real calculation takes place in {@link #getBinCountByNumber} and + * {@link #getBinCountByWidth}. This method switches between these methods + * depending on the object stored in {@link #requestParameter}. + * + * @param values All values used in this histogram + * + * @return Number of bins + */ + protected int getBinCount(double[] values) { + String param = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE); + + if (param != null && param.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) { + return getBinCountByWidth(values); + } + else { + return getBinCountByNumber(); + } + } + + + /** + * Method to retrieve the number of bins. If {@link #requestParameter} + * contains a valid Integer at + * REQUEST_KEY_BIN_COUNT and this is smaller than or equal + * {@link #MAXIMAL_BINS}, this value is used. If no valid + * Integer is given or if the value in {@link #requestParameter} + * is bigger than {@link #MAXIMAL_BINS}, {@link #DEFAULT_BINS} is used. + * + * @return Number of bins + */ + protected int getBinCountByNumber() { + int bins = -1; + String param = (String) requestParameter.get(REQUEST_KEY_BIN_COUNT); + + try { + bins = Integer.parseInt(param); + bins = bins <= 0 ? DEFAULT_BINS : bins; + bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins; + + return bins; + } + catch (NumberFormatException nfe) { + logger.warn("Invalid number of bins for histogram chart: " + param); + logger.warn("Return default bins: " + DEFAULT_BINS); + + return DEFAULT_BINS; + } + } + + + /** + * Serves the number of bins depending on a given width for each bin, but + * maximum bin count is limited by {@link #MAXIMAL_BINS}. + * + * @param values All values in this histogram + * + * @return Number of bins + */ + protected int getBinCountByWidth(double[] values) { + int bins = -1; + String param = (String) requestParameter.get(REQUEST_KEY_BIN_WIDTH); + Locale locale = (Locale) requestParameter.get(REQUEST_KEY_LOCALE); + NumberFormat format = NumberFormat.getInstance(locale); + + try { + double[] minmax = getMinMax(values); + double totalWidth = minmax[1] - minmax[0]; + Number number = format.parse(param); + double binWidth = -1d; + + if (number instanceof Double) { + binWidth = ((Double) number).doubleValue(); + } + else if (number instanceof Long) { + binWidth = ((Long) number).doubleValue(); + } + else if (number instanceof Integer) { + binWidth = ((Integer) number).doubleValue(); + } + else { + logger.warn("Invalid bin width for histogram chart: " + param); + logger.warn("Return default bins: " + DEFAULT_BINS); + + return DEFAULT_BINS; + } + + double tmpBins = totalWidth / binWidth; + + bins = (int) Math.round(tmpBins); + bins = bins <= 0 ? DEFAULT_BINS : bins; + bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins; + + return bins; + } + catch (ParseException pe) { + logger.warn("Invalid bin width for histogram chart: " + param); + logger.warn("Return default bins: " + DEFAULT_BINS); + + return DEFAULT_BINS; + } + catch (NumberFormatException nfe) { + logger.warn("Invalid bin width for histogram chart: " + param); + logger.warn("Return default bins: " + DEFAULT_BINS); + + return DEFAULT_BINS; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalCrossProfileChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,87 @@ +package de.intevation.gnv.chart; + +import de.intevation.gnv.geobackend.base.Result; + +import java.util.Collection; +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +import org.jfree.data.general.Series; + +/** + * Implementation to create a special type of horizontal profile charts. + * + * @author Ingo Weinzierl + */ +public class HorizontalCrossProfileChart +extends HorizontalProfileChart +{ + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(HorizontalCrossProfileChart.class); + + /** + * Constructor to create HorizontalCrossProfileChart objects. + * + * @param labels Labels used to be displayed in title, subtitle and so on. + * @param theme ChartTheme used to adjust the rendering of this chart. + * @param parameters Collection containing a bunch of parameters. + * @param measurements Collection containing a bunch of measurements. + * @param dates Collection containing a bunch of date objects. + * @param result Collection containing a bunch of Result + * objects which contain the actual data items to be displayed. + * @param timeGaps Collection with timegap definitions. + * @param locale Locale used to specify the format of labels, numbers, ... + * @param linesVisible Render lines between data points if true, otherwise + * not. + * @param shapesVisible Render vertices as points if true, otherwise not. + */ + public HorizontalCrossProfileChart( + ChartLabels labels, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Collection result, + Collection timeGaps, + Locale locale, + boolean linesVisible, + boolean shapesVisible + ) { + super( + labels, + theme, + parameters, + measurements, + dates, + result, + timeGaps, + locale, + linesVisible, + shapesVisible + ); + } + + + /** + * Method for gap detection. Nothing is done here, because in this type of + * chart no gap detection takes place. + * + * @see de.intevation.gnv.chart.HorizontalProfileChart#gapDetection(Result[], + * Series, int, int) + */ + @Override + protected void gapDetection( + Result[] results, + Series series, + int startPos, + int endPos + ) { + // nothing to do here, gap detection is done in interpolation + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,474 @@ +package de.intevation.gnv.chart; + +import com.vividsolutions.jts.geom.Point; + +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.utils.DistanceCalculator; + +import java.util.Collection; +import java.util.Locale; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.AxisLocation; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.NumberTickUnit; + +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +import org.jfree.data.Range; + +import org.jfree.data.general.Series; + +import org.jfree.data.xy.XYSeries; + +/** + * This class is used to create xy-charts of horizontal profiles. + * + * @author Ingo Weinzierl + */ +public class HorizontalProfileChart +extends VerticalProfileChart +{ + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(HorizontalProfileChart.class); + + /** + * WKTReader used to turn wkt strings into geometries. + */ + private static WKTReader wktReader = new WKTReader(); + + /** + * The first point in a HorizontalProfileChart. It is used to calculate the + * distance between the currently processed point an the start. + */ + private Point firstPoint; + + /** + * Constructor used to create horizontal profile charts. + * + * @param labels Labels used to be displayed in title, subtitle and so on. + * @param theme ChartTheme used to adjust the rendering of this chart. + * @param parameters Collection containing a bunch of parameters. + * @param measurements Collection containing a bunch of measurements. + * @param dates Collection containing a bunch of date objects. + * @param result Collection containing a bunch of Result + * objects which contain the actual data items to be displayed. + * @param timeGaps Collection with timegap definitions. + * @param locale Locale used to specify the format of labels, numbers, ... + * @param linesVisible Render lines between data points if true, otherwise + * not. + * @param shapesVisible Render vertices as points if true, otherwise not. + */ + public HorizontalProfileChart( + ChartLabels labels, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Collection result, + Collection timeGaps, + Locale locale, + boolean linesVisible, + boolean shapesVisible + ) { + super( + labels, + theme, + parameters, + measurements, + dates, + result, + timeGaps, + locale, + linesVisible, + shapesVisible + ); + this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; + } + + + @Override + protected Object getValue(Result row) { + try { + return (Point) wktReader.read(row.getString("SHAPE")); + } + catch(ParseException pe) { + log.warn("No data found while parsing."); + return null; + } + } + + + @Override + protected void gapDetection( + Result[] results, + Series series, + int startPos, + int endPos + ) { + log.debug("Start gap detection."); + try { + Point startValue = getPoint(results[startPos]); + Point endValue = getPoint(results[endPos-1]); + if (results[0].getInteger("DATAID") == 2) + addGapsOnGrid(results, series, startPos, endPos); + else + addGaps( + results, + series, + startValue, + endValue, + startPos, + endPos + ); + } + catch (ParseException pe) { + log.warn( + "Error while parsing points for gap detection. " + + "No gaps for current series will be detected." + ); + } + + log.debug("Gap detection finished."); + } + + + @Override + protected void addValue(Result row, Series series) { + double distance = 0; + + try { + Point point = (Point) wktReader.read(row.getString("SHAPE")); + if (firstPoint != null) { + distance = DistanceCalculator.calculateDistance( + firstPoint, point + ); + } + else { + firstPoint = point; + } + + ((XYSeries) series).add( + distance, + row.getDouble("YORDINATE") + ); + } + catch(ParseException pe) { + log.warn("No data found while parsing."); + } + } + + + @Override + protected void addSeries(Series series, String label, int idx) { + super.addSeries(series, label, idx); + + // reset firstPoint for next series + firstPoint = null; + } + + + @Override + protected void prepareAxis(String seriesKey,int idx) { + log.debug("prepare axis of xychart"); + + XYPlot plot = chart.getXYPlot(); + Axis xAxis = plot.getDomainAxis(); + NumberAxis yAxis = new NumberAxis(seriesKey); + + localizeDomainAxis(xAxis, locale); + localizeRangeAxis(yAxis, locale); + + // litte workarround to adjust the max range of axes. + // NumberAxis.setAutoRange(true) doesn't seem to work properly. + Range yRange = (Range) ranges.get(seriesKey); + double lo = yRange.getLowerBound(); + double hi = yRange.getUpperBound(); + + // XXX Special case: only a single value in this chart. + // JFreeChart doesn't expand this range, because its length is 0. + if (lo == hi) { + yRange = new Range( + lo - (lo / 100 * LOWER_MARGIN), + hi + (hi / 100 * UPPER_MARGIN)); + } + else { + yRange = Range.expand(yRange, LOWER_MARGIN, UPPER_MARGIN); + } + + yAxis.setRange(yRange); + log.debug("Max Range of dataset is: " + yRange.toString()); + + if (seriesKey.contains("richtung")) { + yAxis.setTickUnit(new NumberTickUnit(30.0)); + yAxis.setUpperBound(360.0); + yAxis.setLowerBound(0.0); + } + else { + yAxis.setFixedDimension(10.0); + yAxis.setAutoRangeIncludesZero(false); + } + + plot.setRangeAxis(idx, yAxis); + yAxis.configure(); + + if (idx % 2 != 0) + plot.setRangeAxisLocation(idx, AxisLocation.BOTTOM_OR_RIGHT); + else + plot.setRangeAxisLocation(idx, AxisLocation.BOTTOM_OR_LEFT); + + plot.mapDatasetToRangeAxis(idx, idx); + } + + + @Override + protected void prepareRangeAxis(String seriesKey, int idx) { + return; + // do nothing here + } + + + @Override + protected void storeMaxValue(Map values, Object value, String parameter) { + return; + // do nothing here + } + + + @Override + protected String createSeriesName( + String breakPoint1, + String breakPoint2, + String breakPoint3 + ) { + log.debug("create seriesname of horizontalprofile chart"); + return super.createSeriesName( + breakPoint1, + breakPoint2, + breakPoint3) + + " " + + findValueTitle(dates, breakPoint3); + } + + + @Override + protected void addGapsOnGrid( + Result[] results, + Series series, + int startPos, + int endPos + ) { + String axis = getDependendAxisName( + results[startPos], + results[startPos+1] + ); + + int last = 0; + int current = 0; + Point lastPoint = null; + Point currentPoint = null; + + try { + firstPoint = getPoint(results[0]); + } + catch (ParseException pe) { + log.error("Unable to parse start point for gap detection."); + return; + } + + for (int i = startPos+1; i < endPos; i++) { + try { + last = results[i-1].getInteger(axis); + lastPoint = getPoint(results[i-1]); + current = results[i].getInteger(axis); + currentPoint = getPoint(results[i]); + double distance = DistanceCalculator.calculateDistance( + firstPoint, + currentPoint); + double distanceOld = DistanceCalculator.calculateDistance( + firstPoint, + lastPoint); + + boolean detected = gridDetection(last, current); + + if (log.isDebugEnabled()) { + log.debug("Last point: " + lastPoint.toString()); + log.debug("Current point: " + currentPoint.toString()); + log.debug("Current distance from start: " + distance); + } + + if (detected) { + log.info( + "Gap detected on grid between " + distanceOld + + " and " + distance); + + ((XYSeries) series).add(distance-1d, null); + ((XYSeries) series).add(distanceOld+1d, null); + } + } + catch (ParseException pe) { + log.warn("Error while parsing point for gap detection.", pe); + } + } + } + + + /** + * Method to add gaps between two data points. The real detection is done by + * {@link #simpleDetection} and {@link #specialDetection}. + * + * @param results All data points in this dataset. + * @param series Series to be processed. + * @param startValue Point where the scan for gaps should begin. + * @param endValue Point where the scan should end. + * @param startPos Start position of this series in results. + * @param endPos End position of a series in results + */ + protected void addGaps( + Result[] results, + Series series, + Point startValue, + Point endValue, + int startPos, + int endPos + ) { + double range = 0; + Point last = null; + Point now = null; + + for (int i = startPos+1; i < endPos; i++) { + boolean detected = false; + + try { + last = (Point) getPoint(results[i-1]); + now = (Point) getPoint(results[i]); + + // gap detection for more than GAP_MAX_VALUES values + if (results.length > GAP_MAX_VALUES) + detected = simpleDetection(startValue, endValue, last, now); + // gap detection for less than GAP_MAX_VALUES values + else + detected = specialDetection( + startValue, + endValue, + last, + now, + results.length + ); + + // gap detected, insert null value to break line + if (detected) { + log.info("Gap after " + range); + double x = range + 0.0001; + + ((XYSeries)series).add(x, null); + } + + range += DistanceCalculator.calculateDistance(last,now); + } + catch (ParseException pe) { + log.warn("Error while parsing point."); + } + + } + } + + + /** + * Simple method to detect gaps. A gap is detected if the delta between two + * data points (current, last) is bigger than PERCENTAGE percent + * of delta of start and end. + *
+ * (smallDelta > delta / 100 * PERCENTAGE) + * + * @param start First data point in a series + * @param end Last data point in a series + * @param last Left point + * @param current Right point + * + * @return true, if a gap is detected between last and current - otherwise + * false. + */ + protected boolean simpleDetection( + Point start, + Point end, + Point last, + Point current + ) { + double delta = DistanceCalculator.calculateDistance(start, end); + double deltaSmall = DistanceCalculator.calculateDistance(last,current); + + return (deltaSmall > (delta / 100 * PERCENTAGE)); + } + + + /** + * Method to detect gaps between two data points. Following formula is used + * for detection:
+ * smallDelta > (3.0 / (count - 1) * delta)
+ * smallDelta = distance between current and last + *
+ * delta = distance between start and end + * + * @param start First data point in a series + * @param end Last data point in a series + * @param last Left point + * @param current Right point + * @param count Number of datapoints + * @return true, if a gap is detected between last and current - otherwise + * false. + */ + protected boolean specialDetection( + Point start, + Point end, + Point last, + Point current, + int count + ) { + double delta = Math.abs( + DistanceCalculator.calculateDistance(end, start) + ); + double smallDelta = Math.abs( + DistanceCalculator.calculateDistance(current, last) + ); + + return (smallDelta > (3.0 / (count - 1) * delta)); + } + + + @Override + protected String getDependendAxisName(Result first, Result second) { + if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION")) + return "JPOSITION"; + + return "IPOSITION"; + } + + /** + * This method returns a point from a given wkt string stored in + * result. + * + * @param result Result object which contains the wkt string. + * The wkt string needs to be available under the key SHAPE. + * + * @return Point representation of wkt string. + */ + private Point getPoint(Result result) + throws ParseException + { + return (Point) wktReader.read(result.getString("SHAPE")); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,629 @@ +package de.intevation.gnv.chart; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import de.intevation.gnv.timeseries.gap.TimeGap; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.TimeZone; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartTheme; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.DateAxis; +import org.jfree.chart.axis.DateTickUnit; +import org.jfree.chart.axis.DateTickUnitType; +import org.jfree.chart.axis.TickUnitSource; +import org.jfree.chart.axis.TickUnits; +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +import org.jfree.data.general.Series; + +import org.jfree.data.time.Minute; +import org.jfree.data.time.TimeSeries; +import org.jfree.data.time.TimeSeriesCollection; + +/** + * This class is used to create timeseries charts. The domain axis contains + * multiple date/time objects. + * + * @author Ingo Weinzierl + */ +public class TimeSeriesChart +extends AbstractXYLineChart +{ + + /** + * Constant format which can be useful to format date items. Value is + * {@value}. + */ + public static final String DEFAULT_DATE_FORMAT = "dd-MMM-yyyy"; + + /** + * Constant field used if no gap detection should be done here. This field + * is used in @see #getTimeGapValue. Value is {@value}. + */ + public static final long NO_TIME_GAP = Long.MAX_VALUE - 1000; + + /** + * Percentage used for gap detection. Its value is {@value}. + */ + public static int GAP_SIZE = 5; // in percent + + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(TimeSeriesChart.class); + + static { + /* The percentage defining the width of a gap should be configured in + * conf.xml instead of being configured in a system property */ + GAP_SIZE = Integer.getInteger("chart.gap.percentage", GAP_SIZE); + } + + + /** + * Constructor used to create TimeSeries charts. + * + * @param labels Labels used to be displayed in title, subtitle and so on. + * @param theme ChartTheme used to adjust the rendering of this chart. + * @param parameters Collection containing a bunch of parameters. + * @param measurements Collection containing a bunch of measurements. + * @param dates Collection containing a bunch of date objects. + * @param result Collection containing a bunch of Result + * objects which contain the actual data items to be displayed. + * @param timeGaps Collection with timegap definitions. + * @param locale Locale used to specify the format of labels, numbers, ... + * @param linesVisible Render lines between data points if true, otherwise + * not. + * @param shapesVisible Render vertices as points if true, otherwise not. + */ + public TimeSeriesChart( + ChartLabels labels, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Collection result, + Collection timeGaps, + Locale locale, + boolean linesVisible, + boolean shapesVisible + ) { + this.labels = labels; + this.theme = theme; + this.parameters = parameters; + this.measurements = measurements; + this.dates = dates; + this.resultSet = result; + this.timeGaps = timeGaps; + this.locale = locale; + this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; + this.linesVisible = linesVisible; + this.shapesVisible = shapesVisible; + this.datasets = new HashMap(); + this.ranges = new HashMap(); + } + + + /** + * see de.intevation.gnv.chart.AbstractXYLineChart#initChart() + */ + @Override + protected void initChart() { + chart = ChartFactory.createTimeSeriesChart( + labels.getTitle(), + labels.getDomainAxisLabel(), + null, + null, + true, + false, + false + ); + + XYPlot plot = (XYPlot) chart.getPlot(); + plot.setDomainAxis(0, new DateAxis( + labels.getDomainAxisLabel(), TimeZone.getDefault(), locale)); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#initData() + */ + protected void initData() { + log.debug("init data for timeseries chart"); + + String breakPoint1 = null; + String breakPoint2 = null; + String breakPoint3 = null; + + Iterator iter = resultSet.iterator(); + Result row = null; + String seriesName = null; + String parameter = null; + TimeSeries series = null; + + int idx = 0; + int startPos = 0; + int endPos = 0; + Date startDate = null; + Date endDate = null; + + Result[] results = + (Result[]) resultSet.toArray(new Result[resultSet.size()]); + + while (iter.hasNext()) { + row = (Result) iter.next(); + + // add current data to plot and prepare for next one + if (!row.getString("GROUP1").equals(breakPoint1) || + !row.getString("GROUP2").equals(breakPoint2) || + !row.getString("GROUP3").equals(breakPoint3) + ) { + log.debug("prepare data/plot for next dataset"); + + if(series != null) { + // add gaps before adding series to chart + startDate = results[startPos].getDate("XORDINATE"); + endDate = results[endPos-1].getDate("XORDINATE"); + addGaps(results,series,startDate,endDate,startPos,endPos); + addSeries(series, parameter, idx); + + startPos = endPos + 1; + } + + // prepare variables for next plot + breakPoint1 = row.getString("GROUP1"); + breakPoint2 = row.getString("GROUP2"); + breakPoint3 = row.getString("GROUP3"); + + seriesName = createSeriesName( + breakPoint1, + breakPoint2, + breakPoint3 + ); + parameter = findParameter(seriesName); + + log.debug("next dataset is '" + seriesName + "'"); + series = new TimeSeries(seriesName, Minute.class); + } + + addValue(row, series); + storeMaxRange(ranges, row.getDouble("YORDINATE"), parameter); + endPos++; + } + + if (startPos < results.length && endPos-1 < results.length) { + // add the last dataset if existing to plot and prepare its axis + startDate = results[startPos].getDate("XORDINATE"); + endDate = results[endPos-1].getDate("XORDINATE"); + addGaps(results, series, startDate, endDate, startPos, endPos); + addSeries(series, parameter, idx); + } + + addDatasets(); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#addValue(Result, Series) + */ + protected void addValue(Result row, Series series) { + ((TimeSeries) series).addOrUpdate( + new Minute(row.getDate("XORDINATE")), + row.getDouble("YORDINATE") + ); + } + + + /** + * @param parameter + * @see de.intevation.gnv.chart.AbstractXYLineChart#addSeries(Series, + * String, int) + */ + protected void addSeries(Series series, String parameter, int idx) { + log.debug("add series (" + parameter + ")to timeseries chart"); + + if (series == null) { + log.warn("no data to add"); + return; + } + + TimeSeriesCollection tsc = null; + + if (datasets.containsKey(parameter)) + tsc = (TimeSeriesCollection) datasets.get(parameter); + else + tsc = new TimeSeriesCollection(); + + tsc.addSeries((TimeSeries) series); + datasets.put(parameter, tsc); + } + + + /** + * Method to add processed datasets to plot. Each dataset is adjusted using + * prepareAxis and adjustRenderer methods. + */ + protected void addDatasets() { + Iterator iter = parameters.iterator(); + XYPlot plot = chart.getXYPlot(); + int idx = 0; + + TimeSeriesCollection tsc = null; + KeyValueDescibeData data = null; + String key = null; + while (iter.hasNext()) { + data = (KeyValueDescibeData) iter.next(); + key = data.getValue(); + + if (datasets.containsKey(key)) { + tsc = (TimeSeriesCollection)datasets.get(key); + plot.setDataset(idx, tsc ); + log.debug("Added " + key + " parameter to plot."); + prepareAxis(key, idx); + adjustRenderer( + idx++, + tsc.getSeriesCount(), + linesVisible, + shapesVisible + ); + } + } + } + + + /** + * @param locale + * @see de.intevation.gnv.chart.AbstractXYLineChart#localizeDomainAxis(Axis, + * Locale) + */ + protected void localizeDomainAxis(Axis axis, Locale locale) { + ((ValueAxis)axis).setStandardTickUnits(createStandardDateTickUnits( + TimeZone.getDefault(), + locale)); + } + + + /** + * @param zone + * @param locale + * @return TickUnitSource + * @see org.jfree.chart.axis.DateAxis#createStandardDateTickUnits(TimeZone, + * Locale) + */ + public static TickUnitSource createStandardDateTickUnits( + TimeZone zone, + Locale locale) + { + /* + * This method have been copied from JFreeChart's DateAxis class. + * DateFormat objects are hard coded in DateAxis and cannot be adjusted. + */ + if (zone == null) { + throw new IllegalArgumentException("Null 'zone' argument."); + } + if (locale == null) { + throw new IllegalArgumentException("Null 'locale' argument."); + } + TickUnits units = new TickUnits(); + + // date formatters + DateFormat f1 = new SimpleDateFormat("HH:mm:ss.SSS", locale); + DateFormat f2 = new SimpleDateFormat("HH:mm:ss", locale); + DateFormat f3 = new SimpleDateFormat("HH:mm", locale); + DateFormat f4 = new SimpleDateFormat("d-MMM, HH:mm", locale); + DateFormat f5 = new SimpleDateFormat("d-MMM yyyy", locale); + DateFormat f6 = new SimpleDateFormat("MMM-yyyy", locale); + DateFormat f7 = new SimpleDateFormat("yyyy", locale); + + f1.setTimeZone(zone); + f2.setTimeZone(zone); + f3.setTimeZone(zone); + f4.setTimeZone(zone); + f5.setTimeZone(zone); + f6.setTimeZone(zone); + f7.setTimeZone(zone); + + // milliseconds + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 1, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 5, + DateTickUnitType.MILLISECOND, 1, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 10, + DateTickUnitType.MILLISECOND, 1, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 25, + DateTickUnitType.MILLISECOND, 5, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 50, + DateTickUnitType.MILLISECOND, 10, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 100, + DateTickUnitType.MILLISECOND, 10, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 250, + DateTickUnitType.MILLISECOND, 10, f1)); + units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 500, + DateTickUnitType.MILLISECOND, 50, f1)); + + // seconds + units.add(new DateTickUnit(DateTickUnitType.SECOND, 1, + DateTickUnitType.MILLISECOND, 50, f2)); + units.add(new DateTickUnit(DateTickUnitType.SECOND, 5, + DateTickUnitType.SECOND, 1, f2)); + units.add(new DateTickUnit(DateTickUnitType.SECOND, 10, + DateTickUnitType.SECOND, 1, f2)); + units.add(new DateTickUnit(DateTickUnitType.SECOND, 30, + DateTickUnitType.SECOND, 5, f2)); + + // minutes + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 1, + DateTickUnitType.SECOND, 5, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 2, + DateTickUnitType.SECOND, 10, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 5, + DateTickUnitType.MINUTE, 1, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 10, + DateTickUnitType.MINUTE, 1, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 15, + DateTickUnitType.MINUTE, 5, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 20, + DateTickUnitType.MINUTE, 5, f3)); + units.add(new DateTickUnit(DateTickUnitType.MINUTE, 30, + DateTickUnitType.MINUTE, 5, f3)); + + // hours + units.add(new DateTickUnit(DateTickUnitType.HOUR, 1, + DateTickUnitType.MINUTE, 5, f3)); + units.add(new DateTickUnit(DateTickUnitType.HOUR, 2, + DateTickUnitType.MINUTE, 10, f3)); + units.add(new DateTickUnit(DateTickUnitType.HOUR, 4, + DateTickUnitType.MINUTE, 30, f3)); + units.add(new DateTickUnit(DateTickUnitType.HOUR, 6, + DateTickUnitType.HOUR, 1, f3)); + units.add(new DateTickUnit(DateTickUnitType.HOUR, 12, + DateTickUnitType.HOUR, 1, f4)); + + // days + units.add(new DateTickUnit(DateTickUnitType.DAY, 1, + DateTickUnitType.HOUR, 1, f5)); + units.add(new DateTickUnit(DateTickUnitType.DAY, 2, + DateTickUnitType.HOUR, 1, f5)); + units.add(new DateTickUnit(DateTickUnitType.DAY, 7, + DateTickUnitType.DAY, 1, f5)); + units.add(new DateTickUnit(DateTickUnitType.DAY, 15, + DateTickUnitType.DAY, 1, f5)); + + // months + units.add(new DateTickUnit(DateTickUnitType.MONTH, 1, + DateTickUnitType.DAY, 1, f6)); + units.add(new DateTickUnit(DateTickUnitType.MONTH, 2, + DateTickUnitType.DAY, 1, f6)); + units.add(new DateTickUnit(DateTickUnitType.MONTH, 3, + DateTickUnitType.MONTH, 1, f6)); + units.add(new DateTickUnit(DateTickUnitType.MONTH, 4, + DateTickUnitType.MONTH, 1, f6)); + units.add(new DateTickUnit(DateTickUnitType.MONTH, 6, + DateTickUnitType.MONTH, 1, f6)); + + // years + units.add(new DateTickUnit(DateTickUnitType.YEAR, 1, + DateTickUnitType.MONTH, 1, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 2, + DateTickUnitType.MONTH, 3, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 5, + DateTickUnitType.YEAR, 1, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 10, + DateTickUnitType.YEAR, 1, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 25, + DateTickUnitType.YEAR, 5, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 50, + DateTickUnitType.YEAR, 10, f7)); + units.add(new DateTickUnit(DateTickUnitType.YEAR, 100, + DateTickUnitType.YEAR, 20, f7)); + + return units; + } + + + /** + * Method to get a message from resource bundle. + * + * @param locale Locale used to specify the resource bundle. + * @param key Key to specify the required message. + * @param def Default string if resource is not existing. + * + * @return Message + */ + protected String getMessage(Locale locale, String key, String def) { + return RessourceFactory.getInstance().getRessource(locale, key, def); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#createSeriesName(String, + * String, String) + */ + protected String createSeriesName( + String breakPoint1, + String breakPoint2, + String breakPoint3 + ) { + log.debug("create seriesname of timeseries chart"); + return findValueTitle(parameters, breakPoint1) + + " " + + findValueTitle(measurements, breakPoint2) + + "m"; + } + + + /** + * Method to add gaps between two data points. The max valid space between + * two data points is calculated by calculateGapSize. + * + * @param results All data points in this dataset. + * @param series Series to be processed. + * @param startDate Date item where the scan for gaps should begin. + * @param endDate Date item where the scan should end. + * @param startPos Start position of this series in results. + * @param endPos End position of a series in results + */ + protected void addGaps( + Result[] results, + Series series, + Date startDate, + Date endDate, + int startPos, + int endPos + ) { + int gapID = results[startPos].getInteger("GAPID"); + long maxDiff = calculateGapSize( + startDate, endDate, startPos, endPos, gapID + ); + + if (log.isDebugEnabled()) { + log.debug("*****************************************************"); + log.debug("Values of gap detection."); + log.debug("Start date: " + startDate.toString()); + log.debug("End date: " + endDate.toString()); + long diff = endDate.getTime() - startDate.getTime(); + log.debug("Time difference (in ms): " + diff); + log.debug("Time difference (in h): " + (diff/(1000*60*60))); + log.debug("Configured gap size (in %): " + GAP_SIZE); + log.debug("Calculated gap size (in ms): " + maxDiff); + log.debug("Calculated gap size (in h): " + (maxDiff/(1000*60*60))); + log.debug("*****************************************************"); + } + + Date last = startDate; + for (int i = startPos+1; i < endPos; i++) { + Result res = results[i]; + Date now = res.getDate("XORDINATE"); + + if ((now.getTime() - last.getTime()) > maxDiff) { + // add gap, add 1 minute to last date and add null value + log.info( + "Gap between " + + last.toString() + " and " + now.toString() + ); + last.setTime(last.getTime() + 60000); + ((TimeSeries) series).addOrUpdate(new Minute(last), null); + } + + last = now; + } + } + + + /** + * Method to calculate the max space between two data points. + * + * @param start First date + * @param end Last date + * @param startPos Start position of the current series in the collection + * containing the bunch of series. + * @param endPos End position of the current series in the collection + * containing the bunch of series. + * @param gapID Gap id used to specify the time intervals. + * + * @return Min size of a gap. + */ + protected long calculateGapSize( + Date start, + Date end, + int startPos, + int endPos, + int gapID + ){ + long maxGap = (end.getTime() - start.getTime()) / 100 * GAP_SIZE; + long interval = getTimeGapValue(start, end, startPos, endPos, gapID); + + if (maxGap < interval) + maxGap = interval + 10; + + return maxGap; + } + + + /** + * Determine the interval size between two data points. + * + * @param dStart Start date + * @param dEnd End date + * @param pStart Index of start point in series used to specify the total + * amount of date items. + * @param pEnd Index of end point in series used to specify the total amount + * of date items. + * @param gapID Gap id used to determine gaps configured in a xml document. + * + * @return Interval size between two data points. + */ + protected long getTimeGapValue( + Date dStart, + Date dEnd, + int pStart, + int pEnd, + int gapID + ){ + long gap = 0; + + if (gapID < 0 || gapID >= 99) { + + if (gapID == -1) { + // no gaps in meshes + gap = NO_TIME_GAP; + } + else if (pEnd-pStart < 60) { + gap = (3/(pEnd-pStart)) * (dEnd.getTime() - dStart.getTime()); + } + } + else{ + Iterator it = timeGaps.iterator(); + + while (it.hasNext()) { + TimeGap tempTimeGap = (TimeGap) it.next(); + + if (tempTimeGap.getKey() == gapID){ + String unit = tempTimeGap.getUnit(); + int gapValue = tempTimeGap.getValue(); + + if (unit.equals(TimeGap.TIME_UNIT_MINUTE)) { + gap = gapValue * TimeGap.MINUTE_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_HOUR)) { + gap = gapValue * TimeGap.HOUR_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_DAY)) { + gap = gapValue * TimeGap.DAY_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_WEEK)) { + gap = gapValue * TimeGap.WEEK_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_MONTH)) { + gap = gapValue * (TimeGap.DAY_IN_MILLIS *30); + } + else if (unit.equals(TimeGap.TIME_UNIT_YEAR)) { + gap = gapValue * (TimeGap.DAY_IN_MILLIS *365); + } + break; + } + } + } + + return gap; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,359 @@ +package de.intevation.gnv.chart; + +import de.intevation.gnv.jfreechart.PolygonDataset; +import de.intevation.gnv.jfreechart.PolygonPlot; +import de.intevation.gnv.jfreechart.PolygonRenderer; +import de.intevation.gnv.jfreechart.PolygonSeries; + +import de.intevation.gnv.math.AttributedXYColumns; + +import de.intevation.gnv.raster.Palette; + +import java.awt.Color; +import java.awt.Paint; + +import java.text.NumberFormat; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; + +import org.jfree.chart.JFreeChart; + +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.SymbolAxis; +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.chart.plot.PlotOrientation; + +import org.jfree.chart.renderer.LookupPaintScale; + +import org.jfree.chart.title.PaintScaleLegend; +import org.jfree.chart.title.TextTitle; + +import org.jfree.data.Range; + +import org.jfree.ui.RectangleEdge; +import org.jfree.ui.RectangleInsets; + +/** + * This class represents a 2D chart containing polygon data. + * + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class VerticalCrossSectionChart +implements Chart +{ + /** + * Lookup class for retrieving a color which corresponds to a specific + * integer value. + */ + public static final class PalettePaintLookup + implements PolygonRenderer.PaintLookup + { + /** + * Object storing information about value ranges and its coresponding + * colors and descriptions. + */ + private Palette palette; + + /** + * Map containing some special Paint like ground fillcolor. + */ + private Map special; + + /** + * Constructor + * + * @param palette See {@link #palette} + */ + public PalettePaintLookup(Palette palette) { + this(palette, null); + } + + /** + * Constructor + * + * @param palette See {@link #palette} + * @param special See {@link #special} + */ + public PalettePaintLookup( + Palette palette, + Map special + ) { + this.palette = palette; + this.special = special; + } + + /** + * @param index Index of a Paint + * + * @return Paint object for a given index. + */ + public Paint getPaint(int index) { + if (special != null) { + Paint paint = special.get(index); + if (paint != null) { + return paint; + } + } + return index < 0 + ? Color.black + : palette.getColor(index); + } + } // class PalettePaintLookup + + /** + * This class is used to turn labels which represent a number into a + * specific format. + */ + public static class LocalizedLabelGenerator + extends PolygonRenderer.DefaultLabelGenerator + { + /** + * NumberFormat which is used to turn a number into a + * specific format. + */ + protected NumberFormat format; + + /** + * Constructor + */ + public LocalizedLabelGenerator() { + } + + /** + * Constructor + * + * @param format See {@link #format} + */ + public LocalizedLabelGenerator(NumberFormat format) { + this.format = format; + } + + /** + * If label is a Number, it is turned into a format + * specified by {@link #format}. + * + * @param label Label to format. + * + * @return String representation of label. + */ + @Override + protected String toString(Object label) { + return label instanceof Number + ? format.format(((Number)label).doubleValue()) + : super.toString(label); + } + } // class LocalizedLabelGenerator + + public static double MARGIN_TOP = 0.05d; + public static double MARGIN_BOTTOM = 0.00d; + public static double MARGIN_LEFT = 0.00d; + public static double MARGIN_RIGHT = 0.05d; + + /** + * JFreeChart object stored at this place after chart creation. + */ + protected JFreeChart chart; + + /** + * Stores {@link de.intevation.gnv.jfreechart.PolygonDataset} which is used + * to create a vertical cross chart. + */ + protected AttributedXYColumns columns; + + /** + * Map which contains colors to fill polygons draw by this chart. + */ + protected Map special; + + /** + * Object used to map value intervals to specific colors and descriptions. + */ + protected Palette palette; + + /** + * Locale object used for i18n support. + */ + protected Locale locale; + + /** + * Labels for decorating the chart. + */ + protected ChartLabels labels; + + /** + * Default Constructor + */ + public VerticalCrossSectionChart() { + } + + /** + * Constructor for VerticalCrossSectionChart creation. + * + * @param columns See {@link #columns} + * @param palette See {@link #palette} + * @param locale See {@link #locale} + * @param labels See {@link #labels} + */ + public VerticalCrossSectionChart( + AttributedXYColumns columns, + Palette palette, + Locale locale, + ChartLabels labels + ) { + this(columns, palette, null, locale, labels); + } + + /** + * Constructor for VerticalCrossSectionChart creation. + * + * @param columns See {@link #columns} + * @param palette See {@link #palette} + * @param special See {@link #special} + * @param locale See {@link #locale} + * @param labels See {@link #labels} + */ + public VerticalCrossSectionChart( + AttributedXYColumns columns, + Palette palette, + Map special, + Locale locale, + ChartLabels labels + ) { + this.columns = columns; + this.palette = palette; + this.special = special; + this.locale = locale; + this.labels = labels; + } + + /** + * This method is used to create a JFreeChart from this object. A 2D plot is + * drawn and a legend panel is created containing each value range. + * + * @return JFreeChart object + */ + protected JFreeChart createChart() { + + boolean legendB = false; + boolean tooltips = false; + boolean urls = false; + + PlotOrientation po = PlotOrientation.HORIZONTAL; + PolygonDataset data = columns.getPolygonDataset(); + + HashSet usedColors = new HashSet(); + + for (int i = data.getSeriesCount()-1; i >= 0; --i) { + PolygonSeries ps = data.getSeries(i); + Integer fill = (Integer)ps.getAttribute("fill"); + if (fill != null + && (special != null && !special.containsKey(fill))) { + usedColors.add(fill); + } + } + + NumberFormat format = NumberFormat.getInstance(locale); + format.setMinimumFractionDigits(0); + format.setMaximumFractionDigits(2); + + PolygonRenderer renderer = new PolygonRenderer( + new PalettePaintLookup(palette, special), + new LocalizedLabelGenerator(format)); + + ValueAxis domainAxis = new NumberAxis(this.labels.getDomainAxisLabel()); + ValueAxis rangeAxis = new NumberAxis(this.labels.getRangeAxisLabel()); + + PolygonPlot plot = new PolygonPlot( + data, + renderer, + domainAxis, + rangeAxis, + null); + + plot.setOutlinePaint(Color.WHITE); + + String [] labels = new String[usedColors.size()]; + + int colors = palette.getSize(); + LookupPaintScale lookupPaint = + new LookupPaintScale(-0.5d, labels.length-0.5d, Color.white); + + Color color = null; + + for (int i = 0, j = labels.length-1; i < colors && j >= 0; i++) { + if (usedColors.contains(i)) { + Palette.Entry entry = palette.getEntryByIndex(i); + color = entry.getColor(); + labels[j] = entry.getDescription(); + lookupPaint.add(j-0.5d, color); + --j; + } + } + + JFreeChart chart = new JFreeChart( + this.labels.getTitle(), + JFreeChart.DEFAULT_TITLE_FONT, + plot, + legendB); + + chart.removeLegend(); + chart.addSubtitle(new TextTitle(this.labels.getSubtitle())); + + SymbolAxis scale = new SymbolAxis(this.labels.getParameterName(), labels); + scale.setRange(-1.5d, labels.length+0.5d); + scale.setGridBandsVisible(false); + scale.setPlot(plot); + + PaintScaleLegend legend = new PaintScaleLegend( + lookupPaint, scale); + legend.setMargin(new RectangleInsets(3d, 10d, 3d, 10d)); + legend.setPosition(RectangleEdge.LEFT); + legend.setAxisOffset(5d); + + chart.addSubtitle(legend); + + // XXX Workaround, because Axes labels are cut at the + // left/right/top/bottom edge. The following lines add a white border + // between data area and plot border. + // see http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=22177&start=0&hilit=axis+labels+cut + ValueAxis xAxis = plot.getDomainAxis(); + Range xRange = xAxis.getRange(); + xRange = Range.expand(xRange, MARGIN_LEFT, MARGIN_RIGHT); + xAxis.setRange(xRange); + plot.setDomainAxis(xAxis); + + ValueAxis yAxis = plot.getRangeAxis(); + Range yRange = yAxis.getRange(); + yRange = Range.expand(yRange, MARGIN_BOTTOM, MARGIN_TOP); + yAxis.setRange(yRange); + plot.setRangeAxis(yAxis); + + chart.setPadding(new RectangleInsets(10d, 10d, 10d, 10d)); + + return chart; + } + + /** + * @see de.intevation.gnv.chart.Chart#generateChart() + */ + public JFreeChart generateChart() { + if (chart == null) { + chart = createChart(); + } + + return chart; + } + + /** + * Set the background paint of {@link #chart}. + * @param paint + */ + public void setBackgroundPaint(Paint paint) { + chart.setBackgroundPaint(paint); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,622 @@ +package de.intevation.gnv.chart; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.NumberAxis; + +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +import org.jfree.data.Range; + +import org.jfree.data.general.Series; + +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +/** + * This class is used to create xy charts of vertical profiles. + * + * @author Ingo Weinzierl + */ +public class VerticalProfileChart +extends AbstractXYLineChart +{ + /** + * Default axis identifier which is used if @see #getDependendAxisName does + * not return a value. The value of this field is {@value}. + */ + public static final String DEFAULT_AXIS = "KPOSITION"; + + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(VerticalProfileChart.class); + + /** + * Constant used for gap detection. Its value is {@value}. + */ + protected static int PERCENTAGE = 5; + + /** + * Constnat used for gap detection in @see #gridDetection. + */ + protected final double GAP_MAX_LEVEL = Math.sqrt(2.0); + + /** + * Constant used for gap detection in @see #addGaps. Its value is {@value}. + */ + protected final int GAP_MAX_VALUES = 60; + + /** + * Map to store max ranges of each parameter + * (org.jfree.chart.axis.Axis.setAutoRange(true) doesn't seem to work + * properly. + */ + protected Map values; + + static { + /* The percentage defining the width of a gap should be configured in + * conf.xml instead of being configured in a system property */ + PERCENTAGE = Integer.getInteger("chart.gap.percentage", PERCENTAGE); + } + + + /** + * Constructor used to create xy-charts. + * + * @param labels Labels used to be displayed in title, subtitle and so on. + * @param theme ChartTheme used to adjust the rendering of this chart. + * @param parameters Collection containing a bunch of parameters. + * @param measurements Collection containing a bunch of measurements. + * @param dates Collection containing a bunch of date objects. + * @param result Collection containing a bunch of Result + * objects which contain the actual data items to be displayed. + * @param timeGaps Collection with timegap definitions. + * @param locale Locale used to specify the format of labels, numbers, ... + * @param linesVisible Render lines between data points if true, otherwise + * not. + * @param shapesVisible Render vertices as points if true, otherwise not. + */ + public VerticalProfileChart( + ChartLabels labels, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Collection result, + Collection timeGaps, + Locale locale, + boolean linesVisible, + boolean shapesVisible + ) { + this.labels = labels; + this.theme = theme; + this.parameters = parameters; + this.measurements = measurements; + this.dates = dates; + this.resultSet = result; + this.timeGaps = timeGaps; + this.locale = locale; + this.PLOT_ORIENTATION = PlotOrientation.HORIZONTAL; + this.linesVisible = linesVisible; + this.shapesVisible = shapesVisible; + this.datasets = new HashMap(); + this.ranges = new HashMap(); + this.values = new HashMap(); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#initData() + */ + @Override + protected void initData() { + log.debug("init data for VerticalProfileChart"); + + String breakPoint1 = null; + String breakPoint2 = null; + String breakPoint3 = null; + + Iterator iter = resultSet.iterator(); + Result row = null; + String seriesName = null; + String parameter = null; + XYSeries series = null; + + int idx = 0; + int startPos = 0; + int endPos = 0; + double startValue = 0; + double endValue = 0; + + Result[] results = + (Result[]) resultSet.toArray(new Result[resultSet.size()]); + + while (iter.hasNext()) { + row = (Result) iter.next(); + + // add current data to plot and prepare for next one + if (!row.getString("GROUP1").equals(breakPoint1) || + !row.getString("GROUP2").equals(breakPoint2) || + !row.getString("GROUP3").equals(breakPoint3) + ) { + log.debug("prepare data/plot for next dataset"); + + if(series != null) { + gapDetection(results, series, startPos, endPos); + addSeries(series, parameter, idx); + + startPos = endPos +1; + } + + // prepare variables for next plot + breakPoint1 = row.getString("GROUP1"); + breakPoint2 = row.getString("GROUP2"); + breakPoint3 = row.getString("GROUP3"); + + seriesName = createSeriesName( + breakPoint1, + breakPoint2, + breakPoint3 + ); + parameter = findParameter(seriesName); + + log.debug("next dataset is '" + seriesName + "'"); + series = new XYSeries(seriesName); + } + + addValue(row, series); + Object x = getValue(row); + Double y = row.getDouble("YORDINATE"); + if (x != null && y != null) { + storeMaxRange(ranges, y, parameter); + storeMaxValue(values, x, parameter); + } + endPos++; + } + + if (results.length == 0) + return; + + gapDetection(results, series, startPos, endPos); + addSeries(series, parameter, idx); + + addDatasets(); + } + + + /** + * Extract the important value from Result object. + * + * @param row Result object which contains a required value. + * + * @return X-ordinate + */ + protected Object getValue(Result row) { + return row.getDouble("XORDINATE"); + } + + + /** + * General method to start a gap detection. The switch between standard gap + * detection method addGaps and a specialized method + * addGapsOnGrid is done by a parameter DATEID + * which is stored a each Result object. Specialized method is + * used if DATEID equals 2, otherwise the standard method is + * used. + * + * @param results Array of Result objects storing data of + * this chart. + * @param series Series used to add gaps. + * @param startPos Index of first element of series in results. + * @param endPos Index of last element of series in results. + */ + protected void gapDetection( + Result[] results, + Series series, + int startPos, + int endPos + ) { + double startValue = results[startPos].getDouble("XORDINATE"); + double endValue = results[endPos-1].getDouble("XORDINATE"); + if (results[0].getInteger("DATAID") == 2) + addGapsOnGrid(results, series, startPos, endPos); + else + addGaps(results, series, startValue, endValue, startPos, endPos); + } + + @Override + protected void prepareAxis(String seriesKey, int idx) { + super.prepareAxis(seriesKey, idx); + + XYPlot plot = chart.getXYPlot(); + NumberAxis domainAxis = (NumberAxis) plot.getRangeAxis(); + NumberAxis rangeAxis = (NumberAxis) plot.getDomainAxis(); + + Range domainRange = domainAxis.getRange(); + Range rangeRange = rangeAxis.getRange(); + log.debug("Domain axis range before: " + domainRange.toString()); + log.debug("Range axis range before: " + rangeRange.toString()); + + domainRange = Range.expand(domainRange, LOWER_MARGIN, UPPER_MARGIN); + rangeRange = Range.expand(rangeRange, LOWER_MARGIN, UPPER_MARGIN); + + double lower = domainRange.getLowerBound(); + double upper = domainRange.getUpperBound(); + + if (lower == upper) { + domainRange = new Range( + lower - (lower * 0.05d), + upper + (upper * 0.05d)); + } + + log.debug("Domain axis range after: " + domainRange.toString()); + log.debug("Range axis range after: " + rangeRange.toString()); + domainAxis.setRange(domainRange); + rangeAxis.setRange(rangeRange); + + plot.setRangeAxis(domainAxis); + } + + + /** + * Method to expand max range of a range axis identified by seriesKey. + * LOWER_MARGIN and UPPER_MARGIN are used to + * expand the range. + * + * @param seriesKey Key to identify the series stored at the current + * Dataset. + * @param idx Currently not used. + */ + protected void prepareRangeAxis(String seriesKey, int idx) { + XYPlot plot = chart.getXYPlot(); + NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); + + Range xRange = (Range) values.get(seriesKey); + xAxis.setRange(Range.expand(xRange, LOWER_MARGIN, UPPER_MARGIN)); + log.debug("Max X-Range of dataset is: " + xRange.toString()); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#addValue(Result, Series) + */ + @Override + protected void addValue(Result row, Series series) { + ((XYSeries) series).add( + row.getDouble("XORDINATE"), + row.getDouble("YORDINATE") + ); + } + + + /** + * @param parameter + * @see de.intevation.gnv.chart.AbstractXYLineChart#addSeries(Series, String, + * int) + */ + @Override + protected void addSeries(Series series, String parameter, int idx) { + log.debug("add series (" + parameter + ")to chart"); + + if (series == null) { + log.warn("no data to add"); + return; + } + + XYSeriesCollection xysc = null; + + if (datasets.containsKey(parameter)) + xysc = (XYSeriesCollection) datasets.get(parameter); + else + xysc = new XYSeriesCollection(); + + xysc.addSeries((XYSeries) series); + datasets.put(parameter, xysc); + } + + + /** + * Method to add processed datasets to plot. Each dataset is adjusted using + * prepareAxis and adjustRenderer methods. + */ + protected void addDatasets() { + Iterator iter = parameters.iterator(); + XYPlot plot = chart.getXYPlot(); + int idx = 0; + + XYSeriesCollection xysc = null; + KeyValueDescibeData data = null; + String key = null; + while (iter.hasNext()) { + data = (KeyValueDescibeData) iter.next(); + key = data.getValue(); + + if (datasets.containsKey(key)) { + xysc = (XYSeriesCollection)datasets.get(key); + plot.setDataset(idx, xysc ); + log.debug("Added " + key + " parameter to plot."); + prepareAxis(key, idx); + adjustRenderer( + idx++, + xysc.getSeriesCount(), + linesVisible, + shapesVisible + ); + } + } + } + + + /** + * Method used to store the max y-range of each parameter in this chart. + * + * @param values Map to store max values for each parameter. + * @param val Value used to be a Double. + * @param parameter Title used to identify a range object stored in values. + */ + protected void storeMaxValue(Map values, Object val, String parameter) { + double value = ((Double) val).doubleValue(); + Range range = null; + + range = values.containsKey(parameter) + ? (Range) values.get(parameter) + : new Range(value, value); + + double lower = range.getLowerBound(); + double upper = range.getUpperBound(); + + lower = value < lower ? value : lower; + upper = value > upper ? value : upper; + + values.put(parameter, new Range(lower, upper)); + } + + + /** + * @param locale + * @see de.intevation.gnv.chart.AbstractXYLineChart#localizeDomainAxis(Axis, + * Locale) + */ + @Override + protected void localizeDomainAxis(Axis axis, Locale locale) { + // call localizeRangeAxis from superclass which formats NumberAxis + super.localizeRangeAxis(axis, locale); + } + + + /** + * @see de.intevation.gnv.chart.AbstractXYLineChart#createSeriesName(String, + * String, String) + */ + @Override + protected String createSeriesName( + String breakPoint1, + String breakPoint2, + String breakPoint3 + ) { + log.debug("create seriesname of verticalprofile chart"); + return findValueTitle(parameters, breakPoint1) + + " " + + findValueTitle(measurements, breakPoint2) + + "m"; + } + + + /** + * Method used to add gaps between data points on grids. The real detection + * is done in gridDetection. + * + * @param results Array of Result objects storing the relevant + * values. + * @param series Series object where the gaps are added to. + * @param startPos Index of first element which should be used in gap + * detection. Other series are stored in results as well. + * @param endPos Index of last element which should be used in gap + * detection. + */ + protected void addGapsOnGrid( + Result[] results, + Series series, + int startPos, + int endPos + ) { + String axis = null; + + if (results.length > (startPos+1)) { + axis = getDependendAxisName( + results[startPos], + results[startPos+1] + ); + } + else { + axis = DEFAULT_AXIS; + } + + double range = 0; + int last = 0; + int current = 0; + + for (int i = startPos+1; i < endPos; i++) { + last = results[i-1].getInteger(axis); + current = results[i].getInteger(axis); + + boolean detected = gridDetection(last, current); + + if (detected) { + double xOld = results[i-1].getDouble("XORDINATE"); + double xNow = results[i].getDouble("XORDINATE"); + log.debug("Gap detected on grid between "+ xOld +" and "+ xNow); + ((XYSeries) series).add(xOld+0.0001, null); + } + } + } + + + /** + * Standarad method to add gaps. There are two different methods to detect + * gaps. simpleDetection is used if the number of data points + * in this chart is lower than GAP_MAX_VALUES. Otherwise + * specialDetection is used. A data point with + * null value is added where a gap should be. This lets + * JFreeChart break the current graph. + * + * @param results Array of Result objects storing the relevant + * values. + * @param series Series object where the gaps are added to. + * @param startValue First data point value in series. + * @param endValue Last data point value in series. + * @param startPos Index of first data point in results which contains all + * data points of all series. + * @param endPos Index of last data point in results which contains all data + * points of all series. + */ + protected void addGaps( + Result[] results, + Series series, + double startValue, + double endValue, + int startPos, + int endPos + ) { + + double last = 0; + double current = 0; + int num = results.length; + + for (int i = startPos+1; i < endPos; i++) { + boolean detected = false; + + last = results[i-1].getDouble("YORDINATE"); + current = results[i].getDouble("YORDINATE"); + + // gap detection for more than GAP_MAX_VALUES values + if (num > GAP_MAX_VALUES) + detected = simpleDetection(startValue, endValue, last, current); + // gap detection for less than GAP_MAX_VALUES values + else + detected = specialDetection( + startValue, + endValue, + last, + current, + num + ); + + if (detected) { + log.info("Gap between " + last + " and " + current); + ((XYSeries) series).add((last+current)/2, null); + } + } + } + + + /** + * Simple method to detect gaps. A gap is detected if the delta between two + * data points (current, last) is bigger than PERCENTAGE percent + * of delta of start and end. + *
+ * (smallDelta > delta / 100 * PERCENTAGE) + * + * @param start First data point value in a series. + * @param end Last data point value in a series. + * @param last Left value + * @param current Right value + * + * @return true, if a gap is detected between last and current - otherwise + * false. + */ + protected boolean simpleDetection( + double start, + double end, + double last, + double current + ) { + double delta = Math.abs(end - start); + double smallDelta = Math.abs(current - last); + + return (smallDelta > delta / 100 * PERCENTAGE); + } + + + /** + * Method to detect gaps between two data points. Following formula is used + * for detection:
+ * smallDelta > (3.0 / (count - 1) * delta)
+ * smallDelta = current - last
+ * delta = end - start + * + * @param start First data point value in a series. + * @param end Last data point value in a series. + * @param last Left value + * @param current Right value + * + * @param count + * @return true, if a gap is detected between last and current - otherwise + * false. + */ + protected boolean specialDetection( + double start, + double end, + double last, + double current, + int count + ) { + double delta = Math.abs(end - start); + double smallDelta = Math.abs(current - last); + + return (smallDelta > (3.0 / (count - 1) * delta)); + } + + + /** + * Method used to detect gaps between two data points grids. If the delta + * between current and last is bigger than GAP_MAX_LEVEL, a gap + * is detected. + * + * @param last Left value + * @param current Right value + * + * @return True, if a gap was detected - otherwise false. + */ + protected boolean gridDetection(double last, double current) { + if (log.isDebugEnabled()) { + log.debug("######################################################"); + log.debug("Parameters for gap detection"); + log.debug("Defined gap size for grids: " + GAP_MAX_LEVEL); + log.debug("1st value to compare: " + last); + log.debug("2nd value to compare: " + current); + log.debug("Difference: " + Math.abs(current - last)); + } + return (Math.abs(current - last) > GAP_MAX_LEVEL); + } + + + /** + * This method returns the key which is used to retrieve the y-value served + * by a Result object. + * + * @param first Result object - not used in this class. + * @param second Result object - not used in this class. + * + * @return the string "KPOSITION" + */ + protected String getDependendAxisName(Result first, Result second) { + return "KPOSITION"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,525 @@ +package de.intevation.gnv.chart; + +import de.intevation.artifactdatabase.Config; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Paint; + +import java.awt.geom.Ellipse2D; + +import org.apache.log4j.Logger; + +import org.jfree.chart.StandardChartTheme; + +import org.jfree.chart.plot.XYPlot; + +import org.jfree.chart.renderer.xy.AbstractXYItemRenderer; +import org.jfree.chart.renderer.xy.XYBarRenderer; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; + +import org.jfree.ui.RectangleInsets; + +import org.jfree.util.UnitType; + +import org.w3c.dom.Document; + +/** + * Implementation of JFreeChart's default implementation + * StandardChartTheme. This class takes an xml document with a + * bunch of parameters and turns it into a ChartTheme to change + * the appearance of charts. + * + * @author Ingo Weinzierl + */ +public class XMLChartTheme +extends StandardChartTheme +{ + /** + * Default color. + */ + private static final Color DEFAULT_COLOR = Color.BLACK; + + /** + * Logger used for logging with log4j. + */ + private Logger log = Logger.getLogger(XMLChartTheme.class); + + /** + * Field storing the visibility of the domain crosshair + */ + protected boolean domainCrosshairVisible; + + /** + * Field storing the visibility of the range crosshair + */ + protected boolean rangeCrosshairVisible; + + /** + * Field storing the visiblity of lines. + */ + protected boolean renderLines; + + /** + * Field storing the visibility of data points + */ + protected boolean renderShapes; + + /** + * Field storing the width of a data point + */ + protected int pointWidth; + + /** + * Field storing the height of a data point. + */ + protected int pointHeight; + + /** + * Field storing the base color of a bin in a histogram chart + */ + protected Paint histogramBasePaint; + + + /** + * Constructor + * + * @param name Name for this theme. + */ + public XMLChartTheme(String name) { + super(name); + } + + + /** + * Setter method for the visibility of the domain crosshair. + * + * @param visible True, if domain crosshair should be visible + */ + public void setDomainCrosshairVisible(boolean visible) { + this.domainCrosshairVisible = visible; + } + + + /** + * Getter method for retrieving the visibility of the domain crosshair. + * + * @return Visibility of the domain crosshair. + */ + public boolean getDomainCrosshairVisible() { + return domainCrosshairVisible; + } + + + /** + * Getter method for retrieving the visibility of the range crosshair. + * + * @return Visibility of the range crosshair. + */ + public boolean getRangeCrosshairVisible() { + return rangeCrosshairVisible; + } + + + /** + * Setter method for the visibility of the range crosshair. + * + * @param visible True, if range crosshair should be visible + */ + public void setRangeCrosshairVisible(boolean visible) { + this.rangeCrosshairVisible = visible; + } + + + /** + * Method to set the bin color of histograms. + * + * @param c Bin color + */ + public void setHistogramBasePaint(Color c) { + this.histogramBasePaint = c; + } + + + /** + * Getter method for retrieving the bin color. + * + * @return Bin color + */ + public Paint getHistogramBasePaint() { + return histogramBasePaint; + } + + + /** + * Take a given xml document and read the configuration of a chart + * appearance. + * + * @param document XML document + */ + public void applyXMLConfiguration(Document document) { + log.debug("create XMLChartTheme"); + + init(document); + } + + + /** + * Start parsing the different settings from document. + * + * @param document XML document + */ + private void init(Document document) { + log.debug("init XMLChartTheme parameters"); + + initChartParameters(document); + initTitleParameters(document); + initSubtitleParameters(document); + initPlotParameters(document); + initAxisParameters(document); + initLegendParameters(document); + initRenderer(document); + initHistogramColor(document); + } + + + /** + * Read parameters configuring the title of a chart. + * + * @param document XML document + */ + private void initTitleParameters(Document document) { + log.debug("init title parameters."); + + int size = getInt(document, "theme/title/font/size/@value"); + String type = getString(document, "theme/title/font/type/@value"); + boolean bold = getBool(document, "theme/title/font/bold/@value"); + + setExtraLargeFont(createFont(type, size, bold)); + + String color = getString(document, "theme/title/font/color/@value"); + Color c = decodeColor(color); + if (c != null) + setTitlePaint(c); + } + + + /** + * Read parameters configuring the subtitle of a chart. + * + * @param document XML document + */ + private void initSubtitleParameters(Document document) { + log.debug("init title parameters."); + + int size = getInt(document, "theme/subtitle/font/size/@value"); + String type = getString(document, "theme/subtitle/font/type/@value"); + boolean bold = getBool(document, "theme/subtitle/font/bold/@value"); + + setLargeFont(createFont(type, size, bold)); + + String col = getString(document, "theme/subtitle/font/color/@value"); + setSubtitlePaint(Color.decode(col)); + } + + + /** + * Read parameters configuring the background color of a chart. + * + * @param document XML document + */ + private void initChartParameters(Document document) { + log.debug("init chart parameters."); + + String bg = getString(document, "theme/chart/background/color/@value"); + Color c = decodeColor(bg); + if (c != null) + setChartBackgroundPaint(c); + } + + + /** + * Read parameters configuring the plot of a chart. + * + * @param document XML document + */ + private void initPlotParameters(Document document) { + log.debug("init plot parameters."); + + String tmp = null; + tmp = getString(document, "theme/plot/background/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setPlotBackgroundPaint(c); + + tmp = getString(document, "theme/plot/outline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setPlotOutlinePaint(c); + + tmp = getString(document, "theme/plot/domaingridline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setDomainGridlinePaint(c); + + tmp = getString(document, "theme/plot/rangegridline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setRangeGridlinePaint(c); + + boolean rangeCrosshairVisible = getBool( + document, "theme/plot/rangecrosshair/visible/@value"); + setRangeCrosshairVisible(rangeCrosshairVisible); + + boolean domainCrosshairVisible = getBool( + document, "theme/plot/domaincrosshair/visible/@value"); + setDomainCrosshairVisible(domainCrosshairVisible); + + int top = getInt(document, "theme/plot/offset/top/@value"); + int bottom = getInt(document, "theme/plot/offset/bottom/@value"); + int left = getInt(document, "theme/plot/offset/left/@value"); + int right = getInt(document, "theme/plot/offset/right/@value"); + setAxisOffset(new RectangleInsets( + UnitType.RELATIVE, + top, left, bottom, right) + ); + } + + + /** + * Read parameters configuring the axes of a plot. + * + * @param document XML document + */ + private void initAxisParameters(Document document) { + log.debug("init axis parameters."); + + String tmp = null; + tmp = getString(document, "theme/axis/label/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setAxisLabelPaint(c); + + tmp = getString(document, "theme/axis/ticklabel/color/@value"); + c = decodeColor(tmp); + if (c != null) + setTickLabelPaint(c); + } + + + /** + * Read parameters configuring the legend of a chart. + * + * @param document XML document + */ + private void initLegendParameters(Document document) { + log.debug("init legend parameters."); + + String tmp = null; + tmp = getString(document, "theme/legend/font/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setLegendItemPaint(c); + + tmp = getString(document, "theme/legend/background/color/@value"); + c = decodeColor(tmp); + if (c != null) + setLegendBackgroundPaint(c); + } + + + /** + * Read parameters configuring the renderer of a plot. + * + * @param document XML document + */ + private void initRenderer(Document document) { + log.debug("init renderer parameters."); + + pointWidth = getInt(document, "theme/plot/itemrenderer/width/@value"); + log.debug("Read point width of " + pointWidth); + pointHeight = getInt(document, "theme/plot/itemrenderer/height/@value"); + log.debug("Read point height of " + pointHeight); + renderLines = getBool( + document, "theme/plot/itemrenderer/renderLines/@value" + ); + renderShapes = getBool( + document, "theme/plot/itemrenderer/renderPoints/@value" + ); + } + + + /** + * Read base color of bins in histogram charts. + * + * @param document XML document + */ + private void initHistogramColor(Document document) { + log.debug("init histogram color"); + String tmp = getString(document, "theme/histogram/bar/color/@value"); + Color c = decodeColor(tmp); + + if (c != null) + setHistogramBasePaint(c); + } + + + /** + * Read a xpath expression and return the matched string. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string + */ + private static String getString(Document document, String xpath) { + return Config.getStringXPath(document, xpath); + } + + + /** + * Read a xpath and turn it into an integer. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string as integer representation. Return 0 if no integer + * have been found at xpath. + */ + private static int getInt(Document document, String xpath) { + String tmp = getString(document, xpath); + + if (tmp != null) + return Integer.parseInt(tmp); + else + return 0; + } + + + /** + * Read a xpath and turn it into a boolean. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string as boolean representation. Return false if no + * boolean have been found at xpath. + */ + private static boolean getBool(Document document, String xpath) { + String tmp = getString(document, xpath); + + if (tmp != null) + return Boolean.parseBoolean(tmp); + else + return false; + } + + + /** + * Turns a string into a color using {@link java.awt.Color}. + * + * @param color as string + * + * @return Color + */ + protected Color decodeColor(String color) { + try { + if (color == null) + return null; + + return Color.decode(color); + } + catch (NumberFormatException nfe) { + log.warn("Error while parsing color: " + color, nfe); + } + + return null; + } + + + /** + * Create a font with the given parameters. + * + * @param type Font type + * @param size Font size + * @param bold Font weight + * + * @return Font + */ + protected Font createFont(String type, int size, boolean bold) { + Font font = null; + if (bold) + font = new Font(type, Font.BOLD, size); + else + font = new Font(type, Font.PLAIN, size); + + return font; + } + + + /** + * Apply settings of this ChartTheme to the given + * XYPlot. + * + * @param plot XYPlot + */ + @Override + protected void applyToXYPlot(XYPlot plot) { + log.debug("apply theme parameter to XYPlot"); + + super.applyToXYPlot(plot); + plot.setDomainCrosshairVisible(this.domainCrosshairVisible); + plot.setRangeCrosshairVisible(this.rangeCrosshairVisible); + + AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) + plot.getRenderer(); + + if (renderer instanceof XYLineAndShapeRenderer) + applyToXYLineAndShapeRenderer(plot); + + if (renderer instanceof XYBarRenderer) + applyToXYBarRenderer(plot); + } + + + /** + * Apply settings of this ChartTheme to the + * XYLineAndShapeRenderer of the given XYPlot. + * + * @param plot XYPlot + */ + protected void applyToXYLineAndShapeRenderer(XYPlot plot) { + if (plot == null) + return; + + XYLineAndShapeRenderer renderer = + (XYLineAndShapeRenderer) plot.getRenderer(); + + Ellipse2D.Double point = new Ellipse2D.Double( + -(pointWidth/2), -(pointHeight/2), pointWidth, pointHeight + ); + + renderer.setSeriesShape(0, point); + renderer.setSeriesShapesVisible(0, renderShapes); + renderer.setSeriesLinesVisible(0, renderLines); + + plot.setRenderer(renderer); + } + + + /** + * Apply settings of this ChartTheme to the + * XYBarRenderer of the given XYPlot. + * + * @param plot XYPlot + */ + protected void applyToXYBarRenderer(XYPlot plot) { + if (plot == null) + return; + + XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer(); + + renderer.setSeriesPaint(0, histogramBasePaint); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/exception/TechnicalChartException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/exception/TechnicalChartException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.chart.exception; + +/** + * @author Tim Englich + * + */ +public class TechnicalChartException extends Exception { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -5325863742368006109L; + + /** + * Constructor + */ + public TechnicalChartException() { + } + + /** + * Constructor + * + * @param message + */ + public TechnicalChartException(String message) { + super(message); + } + + /** + * Constructor + * + * @param cause + */ + public TechnicalChartException(Throwable cause) { + super(cause); + } + + /** + * Constructor + * + * @param message + * @param cause + */ + public TechnicalChartException(String message, Throwable cause) { + super(message, cause); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Exceptions that are used to be thrown if an error occured while chart generation. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/chart/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Classes and interfaces to support creation of different chart types. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/ChartExportHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/ChartExportHelper.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,385 @@ +package de.intevation.gnv.exports; + +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.PageSize; +import com.lowagie.text.Rectangle; + +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfTemplate; +import com.lowagie.text.pdf.PdfWriter; + +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.gnv.chart.Chart; + +import java.awt.Graphics2D; +import java.awt.Transparency; + +import java.awt.geom.Rectangle2D.Double; + +import java.awt.geom.Rectangle2D; + +import java.awt.image.BufferedImage; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import javax.imageio.ImageIO; + +import org.apache.batik.svggen.SVGGraphics2D; +import org.apache.batik.svggen.SVGGraphics2DIOException; + +import org.apache.log4j.Logger; + +import org.jfree.chart.JFreeChart; + +/** + * This class is a helper class which supports some methods to export charts + * into specific formats. + * + * @author Ingo Weinzierl + */ +public class ChartExportHelper { + + /** + * Constant field to define A4 as default page size. + */ + private static final String DEFAULT_PAGE_SIZE = "A4"; + + /** + * Constant field to define UTF-8 as default encoding. + */ + private static final String DEFAULT_ENCODING = "UTF-8"; + + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(ChartExportHelper.class); + + + /** + * A method to export a JFreeChart as image to an + * OutputStream with a given format, width and height. + * + * @param out OutputStream + * @param chart JFreeChart object to be exported. + * @param format Format (e.g. png, gif, jpg) + * @param width Width, the image used to be + * @param height Height, the image used to be + * + * @throws IOException if writing image to OutputStream failed. + */ + public static void exportImage( + OutputStream out, + JFreeChart chart, + String format, + int width, + int height + ) + throws IOException + { + log.info("export chart as png"); + + ImageIO.write( + chart.createBufferedImage( + width, height, Transparency.BITMASK, null + ), + format, + out + ); + } + + + /** + * A method to export a JFreeChart histogram as image to an + * OutputStream with a given format, width and height. + * + * @param out OutputStream + * @param histograms Array of {@link de.intevation.gnv.chart.Chart} objects + * @param format A format (e.g. png, gif, jpg) + * @param width Width the image used to be + * @param height Height the image used to be + * + * @throws IOException if writing image to OutputStream failed. + */ + public static void exportHistograms( + OutputStream out, + Chart[] histograms, + String format, + int width, + int height) + throws IOException + { + log.info("export histograms"); + + int size = histograms.length; + BufferedImage image = new BufferedImage( + width, height*size, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + + for (int i = 0; i < size; i++) { + JFreeChart chart = histograms[i].generateChart(); + chart.draw(g, new Rectangle2D.Double(0.0D, i*height, width, height)); + } + g.finalize(); + + ImageIO.write(image, format, out); + } + + + /** + * A method to export a JFreeChart histogram as SVG to an + * OutputStream. + * + * @param out OutputStream + * @param histograms Array of {@link de.intevation.gnv.chart.Chart} + * @param encoding Encoding, defaults to {@link #DEFAULT_ENCODING} if null + * @param width Width the svg used to be + * @param height Height the svg used to be + */ + public static void exportHistogramsAsSVG( + OutputStream out, + Chart[] histograms, + String encoding, + int width, + int height + ) { + log.info("export histograms as svg"); + + if (encoding == null) + encoding = DEFAULT_ENCODING; + + org.w3c.dom.Document document = XMLUtils.newDocument(); + SVGGraphics2D graphics = new SVGGraphics2D(document); + + int size = histograms.length; + for (int i = 0; i < size; i++) { + JFreeChart chart = histograms[i].generateChart(); + chart.draw(graphics, new Rectangle2D.Double( + 0.0D, i*height,width,height)); + } + graphics.finalize(); + + try { + graphics.stream(new OutputStreamWriter(out, encoding)); + } + catch (SVGGraphics2DIOException svge) { + log.error("Error while writing svg export to output stream.", svge); + } + catch (UnsupportedEncodingException uee) { + log.error("Unsupported encoding: " + encoding, uee); + } + } + + + /** + * A method to export a JFreeChart as SVG to an + * OutputStream. + * + * @param out OutputStream + * @param chart JFreeChart to be exported + * @param encoding Encoding, defaults to {@link #DEFAULT_ENCODING} if null + * @param width Width the svg used to be + * @param height Height the svg used to be + */ + public static void exportSVG( + OutputStream out, + JFreeChart chart, + String encoding, + int width, + int height + ) { + log.info("export chart as svg"); + + if (encoding == null) + encoding = DEFAULT_ENCODING; + + org.w3c.dom.Document document = XMLUtils.newDocument(); + SVGGraphics2D graphics = new SVGGraphics2D(document); + + chart.draw(graphics, new Rectangle2D.Double(0.0D, 0.0D,width,height)); + + try { + graphics.stream(new OutputStreamWriter(out, encoding)); + } + catch (SVGGraphics2DIOException svge) { + log.error("Error while writing svg export to output stream.", svge); + } + catch (UnsupportedEncodingException uee) { + log.error("Unsupported encoding: " + encoding, uee); + } + } + + + /** + * A method to export a JFreeChart as PDF to an + * OutputStream. + * + * @param out OutputStream + * @param chart JFreeChart + * @param pageFormat String to specify a page format, {@link + * #DEFAULT_PAGE_SIZE} is used if no pageFormat is given + * @param landscape If this is true, the pdf is delivered in landscape + * format + * @param marginLeft Space to left border + * @param marginRight Space to right border + * @param marginTop Space to upper border + * @param marginBottom Space to lower border + */ + public static void exportPDF( + OutputStream out, + JFreeChart chart, + String pageFormat, + boolean landscape, + float marginLeft, + float marginRight, + float marginTop, + float marginBottom + ) { + log.info("export chart as pdf."); + + if (pageFormat == null) + pageFormat = DEFAULT_PAGE_SIZE; + + Rectangle page = PageSize.getRectangle(pageFormat); + int pageWidth = (int) (page.getRight(marginRight) - page.getLeft(marginLeft)); + int pageHeight = (int) (page.getTop(marginTop) - page.getBottom(marginBottom)); + + Document document = null; + if (landscape) { + document = new Document(page.rotate()); + log.debug("Create landscape pdf."); + } + else + document = new Document(page); + + try { + PdfWriter writer = PdfWriter.getInstance(document, out); + + document.addSubject(chart.getTitle().getText()); + document.addCreationDate(); + document.open(); + + PdfContentByte content = writer.getDirectContent(); + + int width = 0; + int height = 0; + if (landscape) { + width = pageHeight; + height = pageWidth; + } + else { + width = pageWidth; + height = pageHeight; + } + + PdfTemplate template = content.createTemplate(width, height); + Graphics2D graphics = template.createGraphics(width, height); + Rectangle2D area = new Rectangle2D.Double(0.0D, 0.0D,width,height); + + chart.draw(graphics, area); + graphics.dispose(); + content.addTemplate(template, marginLeft, marginBottom); + } + catch (DocumentException de) { + log.error("Error while exporting chart to pdf.", de); + } + finally { + document.close(); + } + } + + + /** + * A method to export JFreeChart histograms as PDF to an + * OutputStream. Each histogram contained in histograms is + * drawn to an own page in the resulting pdf. + * + * @param out OutputStream + * @param histograms JFreeChart histograms + * @param pageFormat String to specify a page format, {@link + * #DEFAULT_PAGE_SIZE} is used if no pageFormat is given + * @param landscape If this is true, the pdf is delivered in landscape + * format + * @param marginLeft Space to left border + * @param marginRight Space to right border + * @param marginTop Space to upper border + * @param marginBottom Space to lower border + */ + public static void exportHistogramsAsPDF( + OutputStream out, + Chart[] histograms, + String pageFormat, + boolean landscape, + float marginLeft, + float marginRight, + float marginTop, + float marginBottom + ) { + log.info("export histogram as pdf."); + + if (pageFormat == null) + pageFormat = DEFAULT_PAGE_SIZE; + + Rectangle page = PageSize.getRectangle(pageFormat); + int pageWidth = + (int) (page.getRight(marginRight) - page.getLeft(marginLeft)); + int pageHeight = + (int) (page.getTop(marginTop) - page.getBottom(marginBottom)); + + Document document = null; + if (landscape) { + document = new Document(page.rotate()); + log.debug("Create landscape pdf."); + } + else + document = new Document(page); + + try { + PdfWriter writer = PdfWriter.getInstance(document, out); + + document.addCreationDate(); + document.open(); + + PdfContentByte content = writer.getDirectContent(); + + int width = 0; + int height = 0; + if (landscape) { + width = pageHeight; + height = pageWidth; + } + else { + width = pageWidth; + height = pageHeight; + } + + int size = histograms.length; + for (int i = 0; i < size; i++) { + if (i > 0) { + document.newPage(); + } + + JFreeChart chart = histograms[i].generateChart(); + PdfTemplate template = content.createTemplate(width, height); + Graphics2D graphics = template.createGraphics(width, height); + Rectangle2D area = new Rectangle2D.Double( + 0.0D, 0.0D,width,height); + + chart.draw(graphics, area); + graphics.dispose(); + content.addTemplate(template, marginLeft, marginBottom); + } + } + catch (DocumentException de) { + log.error("Error while exporting chart to pdf.", de); + } + finally { + document.close(); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultDataCollector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultDataCollector.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,84 @@ +package de.intevation.gnv.exports; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.state.exception.StateException; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * This is the default implementation of {@link Export.DataCollector}. This + * class serves a method to extract required data from Result + * objects. + * + * @author Ingo Weinzierl + */ +public class DefaultDataCollector +implements Export.DataCollector +{ + /** + * Logger used to log via log4j. + */ + private Logger log = Logger.getLogger(DefaultDataCollector.class); + + /** + * ResultDescriptor used to extract specific attributes from + * Result object. + */ + protected ResultDescriptor rd; + + /** + * Atrribute names in Result object which should be used for + * data extraction. + */ + protected String [] names; + + + /** + * Constructor + * + * @param names See {@link #names} + */ + public DefaultDataCollector(String[] names) { + this.names = names; + } + + /** + * This method initializes the ResultDescriptor rd for a faster + * data extraction. + * + * @param res A Result object used to get its description. + */ + public void init(Result res) { + rd = res.getResultDescriptor(); + } + + /** + * This method is used to extract the required data specified by {@link + * #names}. + * + * @param result Result object. + * + * @return Extracted data. + */ + public String[] getData(Result result) + throws StateException { + + if (rd == null) + init(result); + + List entries = new ArrayList(); + + int[] indices = rd.getColumnIndices(names); + for (int i = 0; i < names.length; ++i) { + entries.add(result.getString(indices[i])); + } + + return (String[]) entries.toArray((new String[entries.size()])); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultExport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultExport.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.gnv.exports; + +import au.com.bytecode.opencsv.CSVWriter; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.exception.StateException; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import java.util.Collection; +import java.util.Iterator; + +import org.apache.log4j.Logger; + +/** + * This class is the default implementation of {@link Export}. + * + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public class DefaultExport +implements Export +{ + /** + * Logger used for logging via log4j. + */ + private static Logger log = Logger.getLogger(DefaultExport.class); + + /** + * DataCollector used to extract data from Result objects. + */ + protected Export.DataCollector collector; + + /** + * Constructor + * + * @param collector See {@link #collector} + */ + public DefaultExport(Export.DataCollector collector) { + this.collector = collector; + } + + /** + * This method writes data stored in result into a CSV document + * using writer. + * + * @param profile Profile used to specify the format and columns. + * @param result Collection storing the required data. + * @param writer CSVWriter to write the csv document. + * + * @throws StateException + */ + protected void writeData( + Profile profile, + Collection result, + CSVWriter writer + ) + throws StateException { + log.debug("create content for export."); + Iterator it = result.iterator(); + + String[] header = profile.getHeader(); + if (header != null) + writer.writeNext(header); + + while (it.hasNext()) { + Result res = it.next(); + + writer.writeNext(collector.getData(res)); + } + } + + /** + * This method takes a data Collection and writes it to + * outputStream using the the format specified by + * profile. + * + * @param profile used to specify the format and columns. + * @param outputStream OutputStream which is used for writing the export + * document to. + * @param result Collection storing the data. + * + * @throws IOException if writing to OutputStream failed. + * @throws UnsupportedEncodingException if the encoding was not accepted. + * @throws StateException if result is null. + */ + public void create( + Profile profile, + OutputStream outputStream, + Collection result + ) + throws + IOException, + UnsupportedEncodingException, + StateException + { + if (result == null) { + String msg = "No data given for generation of " + + profile.getType() + " file."; + log.error(msg); + throw new StateException(msg); + } + + CSVWriter writer = new CSVWriter( + new OutputStreamWriter( + outputStream, + profile.getEncoding()), + profile.getSeparator(), + profile.getQuoteCharacter(), + profile.getEscapeCharacter()); + + writeData(profile, result, writer); + + writer.close(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/DefaultProfile.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,151 @@ +package de.intevation.gnv.exports; + +/** + * This class is the default implementation of {@link Export.Profile} and + * serves information about the format used to create an export document. + * + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public class DefaultProfile +implements Export.Profile +{ + /** + * Used to collect the required data from Result object. + */ + protected Export.DataCollector collector; + + /** + * Column headers. + */ + protected String [] header; + + /** + * + */ + protected String [] names; + + /** + * Character used to separate columns. + */ + protected char separator; + + /** + * Escape character. + */ + protected char escapeCharacter; + + /** + * Quote character. + */ + protected char quoteCharacter; + + /** + * Format type. + */ + protected String type; + + /** + * Encoding used for export. + */ + protected String encoding; + + /** + * Constructor + */ + private DefaultProfile() { + } + + /** + * Constructor + * + * @param header See {@link #header} + * @param separator See {@link #separator} + * @param escapeCharacter See {@link #escapeCharacter} + * @param quoteCharacter See {@link #quoteCharacter} + * @param type See {@link #type} + * @param encoding See {@link #encoding} + */ + public DefaultProfile( + String [] header, + char separator, + char escapeCharacter, + char quoteCharacter, + String type, + String encoding + ) { + this.header = header; + this.separator = separator; + this.escapeCharacter = escapeCharacter; + this.quoteCharacter = quoteCharacter; + this.type = type; + this.encoding = encoding; + } + + /** + * Returns the given value. + * + * @param index Index + * @param value Value + * + * @return value + */ + public String toString(int index, String value) { + return value; + } + + /** + * Returns the separator. + * + * @return Separator + */ + public char getSeparator() { + return separator; + } + + /** + * Returns the escape character. + * + * @return Escape character + */ + public char getEscapeCharacter() { + return escapeCharacter; + } + + /** + * Returns the quote character. + * + * @return Quote character. + */ + public char getQuoteCharacter() { + return quoteCharacter; + } + + /** + * Returns the format type. + * + * @return Type. + */ + public String getType() { + return type; + } + + /** + * Returns the encoding. + * + * @return Encoding + */ + public String getEncoding() { + return encoding; + } + + /** + * Returns the column headers. + * + * @return header + */ + public String[] getHeader() { + return header; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/Export.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/Export.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,128 @@ +package de.intevation.gnv.exports; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.exception.StateException; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import java.util.Collection; + +/** + * This interface should be implemented by a class whose instances are intended + * to export a Collection of Results into a specific + * format (e.g. CSV or ODV). + * + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public interface Export { + + /** + * This interface provides some methods which describe the format used by an + * Export. + */ + public interface Profile { + /** + * + * @param column Column index. + * @param value A default value. + * @return A specific column as string. + */ + String toString(int column, String value); + + /** + * This method serves information about the character used to separate + * columns. + * + * @return Character used to separate + */ + char getSeparator(); + + /** + * This method serves information about the character used as escape + * character. + * + * @return Escape character + */ + char getEscapeCharacter(); + + /** + * This method serves informatin about the character used as quote + * character. + * + * @return Quote character + */ + char getQuoteCharacter(); + + /** + * This method serves information about the format. + * + * @return Format as string. + */ + String getType(); + + /** + * This method serves information about the encoding to be used. + * + * @return Encoding + */ + String getEncoding(); + + /** + * This method returns the header as array. + * + * @return Header as string array. + */ + String [] getHeader(); + } + + /** + * This interface should be implemeted to collect the required data from + * Result object. + */ + public interface DataCollector { + + /** + * This method serves the required data stored in a Result + * object. + * + * @param result Result object which contains the required + * data. + * @return String[] which contains all required data. + * + * @throws StateException + */ + String[] getData(Result result) + throws StateException; + } + + /** + * This method creates an export document specified by {@link Profile} which + * contains the data stored in result and writes it to + * outputStream. + * + * @param profile Profile used to specify the format of the resulting export + * document. + * @param outputStream Resulting export document is written to this + * OutputStream. + * @param result Collection which contains the data used to be written into + * the export document. + * + * @throws IOException if an error occured while writing the export document + * to OutputStream + * @throws UnsupportedEncodingException if the given encoding is not + * accepted + * @throws StateException if result is null + */ + public void create( + Profile profile, + OutputStream outputStream, + Collection result + ) + throws IOException, UnsupportedEncodingException, StateException; + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/ODVExport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/ODVExport.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,158 @@ +package de.intevation.gnv.exports; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.log4j.Logger; + +import au.com.bytecode.opencsv.CSVWriter; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.exception.StateException; + +/** + * This class is used to create a specific export document which is similar to + * an CSV document. + * + * @author Tim Englich + */ +public class ODVExport extends DefaultExport { + + /** + * Logger used for logging via log4j. + */ + private static Logger log = Logger.getLogger(ODVExport.class); + + /** + * Collection of parameters. + */ + private Collection parameters = null; + + /** + * The TimeStime which should be integrated in the Export to mark a + * TimeSeries. + */ + private String startTime = null; + + /** + * Constructor + * @param collector DataCollector used to extract the required data. + * @param parameters A collection of parameters to be displayed in the + * export. + * @param startTime The TimeStamp which should ne integrated in the export + * to mark a TimeSeries. If it should not be a TimeSeries this Value must + * be null. + */ + public ODVExport(DataCollector collector, Collection parameters, String startTime) { + super(collector); + this.parameters = parameters; + this.startTime = startTime; + } + + + @Override + protected void writeData(Profile profile, Collection result, + CSVWriter writer) throws StateException { + Iterator it = result.iterator(); + + String[] header = profile.getHeader(); + ArrayList headerList = new ArrayList(); + for (int i= 0; i < header.length; i++){ + headerList.add(header[i]); + } + + if (this.startTime != null){ + headerList.add("time_ISO8601"); + } + ArrayList paramids = new ArrayList(); + + Map> aggregatedRows = new HashMap>(); + + String currentParameterID = "N/N"; + + while (it.hasNext()) { + Result res = it.next(); + + String[] value = collector.getData(res); + StringArrayKey key = new StringArrayKey(value); + String parameterValue = res.getString("DATAVALUE"); + String parameterID = res.getString("PARAMETER"); + + if (!currentParameterID.equals(parameterID)){ + paramids.add(parameterID); + headerList.add(this.findParamTitle(parameters, parameterID)); + headerList.add("QF"); + currentParameterID = parameterID; + } + + Map aggregatedRow = aggregatedRows.get(key); + if (aggregatedRow!= null){ + aggregatedRow.put(parameterID, parameterValue); + }else{ + Map params = new HashMap(); + params.put(parameterID, parameterValue); + aggregatedRows.put(key, params); + } + } + + if (header != null){ + writer.writeNext(headerList.toArray(header)); + } + + Iterator rows = aggregatedRows.keySet().iterator(); + while (rows.hasNext()){ + StringArrayKey row = rows.next(); + Map params = aggregatedRows.get(row); + ArrayList rowList = new ArrayList(); + String[] rowArray = row.getValue(); + for (int i= 0; i < rowArray.length; i++){ + rowList.add(rowArray[i]); + } + if (this.startTime != null){ + String measurementtime = rowList.get(3).replace(' ','T'); + rowList.set(3, this.startTime.replace('.','-')); + rowList.add(measurementtime+":00.0"); + } + for (int i = 0; i < paramids.size();i++){ + String key = paramids.get(i); + String value = params.get(key); + if (value == null){ + value = ""; + } + rowList.add(value); + rowList.add("1"); + } + writer.writeNext(rowList.toArray(rowArray)); + } + } + + /** + * This method is used to search specific value coresponding to its key + * id and return its description. + * + * @param values Collection of parameters. + * @param id Key used to find the value. + * + * @return Description of searched value. + */ + protected String findParamTitle(Collection values, String id) { + log.debug("find description of dataset"); + + if (values != null){ + Iterator it = values.iterator(); + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + + if (id.equals(data.getKey())) + return data.getValue(); + } + } + return ""; + } + + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/ShapeDataCollector.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,80 @@ +package de.intevation.gnv.exports; + +import com.vividsolutions.jts.geom.Point; + +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.exception.StateException; + +import org.apache.log4j.Logger; + +/** + * This class is a specialization of DefaultDataCollector. The + * difference between these classes is, that this class extracts points served + * by a wkt string. + * + * @author Ingo Weinzierl + */ +public class ShapeDataCollector +extends DefaultDataCollector +{ + /** + * Logger used for logging with log4j. + */ + private Logger log = Logger.getLogger(ShapeDataCollector.class); + + /** + * WKTReader to parse points from wkt strings. + */ + protected WKTReader wktReader = new WKTReader(); + + /** + * Constructor + * + * @param names Attributes used to be extracted. + */ + public ShapeDataCollector(String[] names) { + super(names); + } + + /** + * This method takes point from wkt strings as well and split them into x + * and y coordinate. + * + * @see de.intevation.gnv.exports.Export.DataCollector#getData(Result) + */ + public String[] getData(Result result) + throws StateException { + + if (rd == null) + init(result); + + try { + String [] entries = new String[names.length+1]; + int j = 0; + for (int i = 0; i < names.length; i++) { + + if (names[i].equals("SHAPE")) { + Point p = (Point)wktReader.read(result.getString("SHAPE")); + + entries[j++] = ""+p.getX(); + entries[j++] = ""+p.getY(); + } + else { + entries[j++] = result.getString(names[i]); + } + } + + return entries; + } + catch (ParseException pe) { + log.error(pe, pe); + throw new StateException( + "Error occured while parsing a Point from WKT."); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/SimpleOdvDataCollector.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,109 @@ +package de.intevation.gnv.exports; + +import com.vividsolutions.jts.geom.Point; + +import com.vividsolutions.jts.io.ParseException; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.exception.StateException; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import java.util.Date; + +import org.apache.log4j.Logger; + +/** + * This class is a specialization of {@link ShapeDataCollector} and turns + * furthermore a given datetime string into a specific format. + * + * @author Ingo Weinzierl + */ +public class SimpleOdvDataCollector +extends ShapeDataCollector +{ + /** + * Logger used for logging with log4j. + */ + private static Logger log = Logger.getLogger(SimpleOdvDataCollector.class); + + /** + * Constant field which defines the source format of a given datetime. + */ + public static final String SRC_FORMAT = "yyyy.MM.dd HH:mm:ss"; + + /** + * Constant field which defines the target format of a given datetime. + */ + public static final String DEST_FORMAT = "yyyy-MM-dd HH:mm"; + + /** + * Source format. + */ + public static DateFormat srcFormat = new SimpleDateFormat(SRC_FORMAT); + + /** + * Target format. + */ + public static DateFormat destFormat = new SimpleDateFormat(DEST_FORMAT); + + /** + * Constructor + * + * @param names See {@link #names} + */ + public SimpleOdvDataCollector(String[] names) { + super(names); + } + + /** + * Given datetime values which corresponds to the attribute key 'TIMEVALUE' + * are transformed from {@link #SRC_FORMAT} into {@link #DEST_FORMAT}. + * + * @see de.intevation.gnv.exports.Export.DataCollector#getData(Result) + */ + public String[] getData(Result result) + throws StateException + { + if (rd == null) + init(result); + + try { + String [] entries = new String[names.length+1]; + int j = 0; + for (int i = 0; i < names.length; i++) { + + if (names[i].equals("SHAPE")) { + Point p = (Point)wktReader.read(result.getString("SHAPE")); + + entries[j++] = ""+p.getX(); + entries[j++] = ""+p.getY(); + } + // Change the datetime format from yyyy.MM.dd HH:mm:ss to + // yyyy-MM-dd HH:mm + else if (names[i].equals("TIMEVALUE")) { + Date source = srcFormat.parse(result.getString(names[i])); + entries[j++] = destFormat.format(source); + } + else { + entries[j++] = result.getString(names[i]); + } + } + + return entries; + } + catch (ParseException pe) { + log.error(pe, pe); + throw new StateException( + "Error occured while parsing source data."); + } + catch (java.text.ParseException pe) { + log.error(pe, pe); + throw new StateException( + "Error occured while parsing source data."); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/StringArrayKey.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/StringArrayKey.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,61 @@ +package de.intevation.gnv.exports; +/** + * A simple Key Class for generating an syntetic key using the + * values of the given Stringarray and not the Hash of the Stringarray + * + * @author Tim Englich + * + */ +public class StringArrayKey { + + /** + * The Stringarray which contains the Values. + */ + private String[] value = null; + + /** + * The Key which should be used to compare the Stringarrays. + */ + private String key = null; + + /** + * Constructor + * @param value the Value which should be used to generate the key + */ + public StringArrayKey(String[] value) { + this.value = value; + if (value != null){ + key = ""; + for (int i = 0; i < value.length; i++){ + key += value[i]; + } + } + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof StringArrayKey){ + return (((StringArrayKey)obj).key).equals(this.key); + } + return false; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.key.hashCode(); + } + + /** + * Returns the stored origin Values of the Key + * @return the stored origin Values of the Key + */ + public String[] getValue() { + return value; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/VerticalCrossODVExport.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,207 @@ +package de.intevation.gnv.exports; + +import com.vividsolutions.jts.geom.Coordinate; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import java.util.Collection; +import java.util.Date; + +import org.apache.log4j.Logger; + +import au.com.bytecode.opencsv.CSVWriter; +import de.intevation.gnv.state.exception.StateException; + + +public class VerticalCrossODVExport implements Export { + + /** + * Constant field which defines the source format of a given datetime. + */ + public static final String SRC_FORMAT = "yyyy.MM.dd HH:mm:ss"; + + /** + * Constant field which defines the target format of a given datetime. + */ + public static final String DEST_FORMAT = "yyyy-MM-dd HH:mm"; + + /** + * Source format. + */ + public static DateFormat srcFormat = new SimpleDateFormat(SRC_FORMAT); + + /** + * Target format. + */ + public static DateFormat destFormat = new SimpleDateFormat(DEST_FORMAT); + + /** + * Logger used for logging via log4j. + */ + private static Logger logger = + Logger.getLogger(VerticalCrossODVExport.class); + + /** + * The path in coordinates. + */ + protected Coordinate[] coordinates; + + /** + * + */ + protected double cellHeight; + + /** + * + */ + protected double cellWidth; + + /** + * The raster array storing the values for a specific coordinate in a + * specific depth. + */ + protected double[] raster; + + /** + * The raster width. + */ + protected int width; + + /** + * The raster height. + */ + protected int height; + + /** + * The date of this export. + */ + protected String time; + + /** + * The constructor used to create a new export helper object. + */ + public VerticalCrossODVExport( + Coordinate[] coordinates, + double cellHeight, + double cellWidth, + double[] raster, + String time, + int width, + int height) + { + this.coordinates = coordinates; + this.cellHeight = cellHeight; + this.cellWidth = cellWidth; + this.raster = raster; + this.width = width; + this.height = height; + this.time = time; + } + + + /** + * + * @param profile The Profile used to create column headers. + * @param outputStream The stream where the odv data are written to. + * @param result Not used here, might be null. + */ + public void create( + Profile profile, + OutputStream outputStream, + Collection result) + throws + IOException, + UnsupportedEncodingException, + StateException + { + CSVWriter writer = new CSVWriter( + new OutputStreamWriter(outputStream, profile.getEncoding()), + profile.getSeparator(), + profile.getQuoteCharacter(), + profile.getEscapeCharacter()); + + writer.writeNext(profile.getHeader()); + + writeData(writer, time, coordinates, cellHeight, cellWidth, raster); + + writer.close(); + } + + protected void writeData( + CSVWriter writer, + String time, + Coordinate[] coordinates, + double cellHeight, + double cellWidth, + double[] raster) + { + if (logger.isDebugEnabled()) { + logger.debug("+++++++ ODV Export information ++++++++++"); + logger.debug("+ raster width: " + width); + logger.debug("+ raster height: " + height); + logger.debug("+ cell height: " + cellHeight); + logger.debug("+ cell width: " + cellWidth); + logger.debug("+ items in raster: " + raster.length); + logger.debug("+ number of coordinates: " + coordinates.length); + logger.debug("+++++++++++++++++++++++++++++++++++++++++"); + } + + String datetime = null; + try { + Date tmp = srcFormat.parse(time); + datetime = destFormat.format(tmp); + } + catch (ParseException pe) { + logger.error(pe, pe); + } + + double maxDepth = 0; + String[] row = new String[10]; + for (int i = 0; i < width; i++) { + row[0] = "GNVExport"; + row[1] = "Station_" + i; + row[2] = "*"; + row[3] = datetime; + row[4] = Double.toString(coordinates[i].x); + row[5] = Double.toString(coordinates[i].y); + row[6] = "0"; + + double depth = cellHeight * 0.5d; + for (int j = i; j < raster.length; j += width, depth += cellHeight) { + if (j == (i+width)) { + row[0] = ""; + row[1] = ""; + row[2] = ""; + row[3] = ""; + row[4] = ""; + row[5] = ""; + row[6] = ""; + } + + double value = raster[j]; + + row[7] = Double.toString(depth); + row[8] = "1"; + row[9] = Double.toString(value); + + maxDepth = maxDepth >= depth ? maxDepth : depth; + + if (Double.isNaN(value)) { + break; + } + + writer.writeNext(row); + } + } + + logger.info("Detected max depth: " + maxDepth); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/exports/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/exports/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Handle different types of data exports (e.g. chart, csv, odv). + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/histogram/HistogramHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/histogram/HistogramHelper.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,219 @@ +package de.intevation.gnv.histogram; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * This class supports some helper methods for histogram charts. + * + * @author Ingo Weinzierl + */ +public class HistogramHelper { + + /** + * Logger used for logging with log4j. + */ + private static Logger logger = Logger.getLogger(HistogramHelper.class); + + + /** + * Disabled HistogramHelper constructor. This is a helper class and no + * instance should be instantiated from this class. + */ + private HistogramHelper() { + } + + + /** + * This function prepare some input data and turns it into an array which is + * taken by {@link de.intevation.gnv.chart.DefaultHistogram}. + * + * @param input A collection with the data used to be displayed in a + * histogram + * @param parameters A collection with a bunch of parameters + * @param measurements A collection with a bunch of measurements + * @param dates A collection with a bunch of dates + * + * @return Object[][] containing raw data which can be used to create + * histograms + */ + public static Object[][] prepareHistogramData( + Collection input, + Collection parameters, + Collection measurements, + Collection dates + ) { + List names = new ArrayList(); + List data = new ArrayList(); + + if (logger.isDebugEnabled()) { + logger.debug("############ prepare histogram data ##########"); + logger.debug("Input data size: " + input.size()); + } + + if (input == null) { + return new Object[0][0]; + } + + String break1, break2, break3; + int b1Idx = -1; + int b2Idx = -1; + int b3Idx = -1; + int yIdx = -1; + try { + Iterator iter = input.iterator(); + + if (iter.hasNext()) { + Result row = (Result) iter.next(); + Result previousRow = row; + + if (b1Idx == -1) { + ResultDescriptor rd = row.getResultDescriptor(); + b1Idx = rd.getColumnIndex("GROUP1"); + b2Idx = rd.getColumnIndex("GROUP2"); + b3Idx = rd.getColumnIndex("GROUP3"); + yIdx = rd.getColumnIndex("YORDINATE"); + + if (b1Idx == -1 || b2Idx == -1 || b3Idx == -1 || yIdx == -1) { + return new Object[0][0]; + } + } + break1 = row.getString(b1Idx); + break2 = row.getString(b2Idx); + break3 = row.getString(b3Idx); + + List values = new ArrayList(); + while (iter.hasNext()) { + + // found new series + if (!break1.equals(row.getString(b1Idx)) + || !break2.equals(row.getString(b2Idx)) + || !break3.equals(row.getString(b3Idx)) + ) { + + // get parameter name + String name = generateName( + break1, break2, break3, + parameters, measurements, dates + ); + + // add values and parameter name + data.add((Double[]) values.toArray(new Double[values.size()])); + names.add(name); + + if (logger.isDebugEnabled()) { + logger.debug(" --- series name: " + name); + logger.debug(" --- series items: " + values.size()); + } + + values.clear(); + + Double yValue = row.getDouble(yIdx); + if (yValue != null) + values.add(yValue); + + // set new conditions to find new series + break1 = row.getString(b1Idx); + break2 = row.getString(b2Idx); + break3 = row.getString(b3Idx); + + previousRow = row; + row = (Result) iter.next(); + } else { + + Double value = row.getDouble(yIdx); + if (value != null) + values.add(value); + + row = (Result) iter.next(); + } + } + + Double yValue = row.getDouble(yIdx); + if (yValue != null) + values.add(yValue); + + String name = generateName( + break1, break2, break3, parameters, measurements, dates); + + if (logger.isDebugEnabled()) { + logger.debug(" --- series name: " + name); + logger.debug(" --- series items: " + values.size()); + } + + data.add((Double[]) values.toArray(new Double[values.size()])); + names.add(name); + } + } + catch (Exception e) { + logger.error(e.getMessage(), e); + } + + int series = data.size(); + logger.debug(" === Found total: " + series); + Object[][] obj = new Object[series][2]; + for (int i = 0; i < series; i++) { + obj[i][0] = names.get(i); + obj[i][1] = (Double[]) data.get(i); + } + + return obj; + } + + + /** + * This method generates a string made up of parameter name and a + * measurement. + * + * @param break1 Id of a parameter. + * @param break2 Id of a measurement. + * @param break3 Id of a date. + * @param parameters A collection with a bunch of parameters. + * @param measurements A collection with a bunch of measurements. + * @param dates A collection with a bunch of dates. + * + * @return Concatenated string (${parametername} + ${measurement} + m). + */ + protected static String generateName( + String break1, String break2, String break3, + Collection parameters, Collection measurements, Collection dates) + { + return findValueTitle(parameters,break1) + " " + + findValueTitle(measurements,break2) + "m"; + } + + + /** + * Find a value with the given id and return its description. + * + * @param values A collection which contains the value we are searching for + * @param id Id of the value + * + * @return String representation of the value. An empty string is returned + * if no value have been found with the given id. + */ + protected static String findValueTitle(Collection values, String id) { + if (values != null) { + Iterator it = values.iterator(); + + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + + if (id.equals(data.getKey())) { + return data.getValue(); + } + } + } + return ""; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/histogram/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/histogram/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Helper classes used while histogram creation. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/CompactXYItems.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/CompactXYItems.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,199 @@ +package de.intevation.gnv.jfreechart; + +import java.io.Serializable; + +/** + * This class is used to represent geometries (e.g. point, line, polygon). Each + * geometry is made up of multiple xy points stored in a single array. A line + * composed by start- and endpoint is stored in the following order in that + * array: [x1, y1, x2, y2]. + * + * @author Sascha Teichmann + * @author Ingo Weinzierl + */ +public class CompactXYItems +implements Serializable +{ + /** + * Array storing the xy items. + */ + protected double [] data; + + /** + * Constructs a new CompactXYItems object with the given data. + * + * @param data An array with xy values. + */ + public CompactXYItems(double [] data) { + this.data = data; + } + + /** + * Retrieves the x coordinate of the point with the given index. + * + * @param index Index + * @return X coordinate. + */ + public double getX(int index) { + return data[index << 1]; + } + + /** + * Retrieves the y coordinate of the point with the given index. + * + * @param index Index + * @return Y coordinate. + */ + public double getY(int index) { + return data[(index << 1)+1]; + } + + /** + * Write the tupel of xy-values at a specific index into the given array. + * + * @param index Index used to specify the xy-value. + * @param xy the xy coordinate is written into this array with the following + * order: [x,y] + */ + public void get(int index, double [] xy) { + xy[0] = data[index = (index << 1) + 1]; + xy[1] = data[index + 1]; + } + + /** + * + * @return the data array. + */ + public double [] getData() { + return data; + } + + /** + * + * @param data + */ + public void setData(double [] data) { + this.data = data; + } + + /** + * + * @return the number of data points. + */ + public int size() { + return data.length >> 1; + } + + /** + * Retrieves the bounding box spaned by the coordinates in the data array. + * + * @param bbox + * @return the calculated bounding box. + */ + public double [] calculateBoundingBox(double [] bbox) { + for (int i = 0; i < data.length;) { + double x = data[i++]; + double y = data[i++]; + if (x < bbox[0]) bbox[0] = x; + if (y < bbox[1]) bbox[1] = y; + if (x > bbox[2]) bbox[2] = x; + if (y > bbox[3]) bbox[3] = y; + } + return bbox; + } + + /** + * + * @return the coordinates as string. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < data.length;) { + if (i > 0) sb.append("; "); + sb.append('('); + sb.append(data[i++]); + sb.append(", "); + sb.append(data[i++]); + sb.append(')'); + } + return sb.toString(); + } + + + /** + * + * @return the lowest x value. + */ + public double getMinX() { + double lower = Double.POSITIVE_INFINITY; + + for (int i = 0; i < data.length; i += 2) { + double x = data[i]; + + if (!Double.isNaN(x)) { + lower = Math.min(lower, x); + } + } + + return lower; + } + + + /** + * + * @return the highest x value. + */ + public double getMaxX() { + double upper = Double.NEGATIVE_INFINITY; + + for (int i = 0; i < data.length; i += 2) { + double x = data[i]; + + if (!Double.isNaN(x)) { + upper = Math.max(upper, x); + } + } + + return upper; + } + + + /** + * + * @return the lowest y value. + */ + public double getMinY() { + double lower = Double.POSITIVE_INFINITY; + + for (int i = 1; i < data.length; i += 2) { + double y = data[i]; + + if (!Double.isNaN(y)) { + lower = Math.min(lower, y); + } + } + + return lower; + } + + + /** + * + * @return the highest y value. + */ + public double getMaxY() { + double upper = Double.NEGATIVE_INFINITY; + + for (int i = 1; i < data.length; i += 2) { + double y = data[i]; + + if (!Double.isNaN(y)) { + upper = Math.max(upper, y); + } + } + + return upper; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/LevelOrderIndices.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/LevelOrderIndices.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.gnv.jfreechart; + +import java.util.LinkedList; + +/** + * @author Sascha L. Teichmann + */ +public class LevelOrderIndices +{ + public interface Visitor { + + Object visit(int index); + } + + + protected int from; + + protected int to; + + + public LevelOrderIndices() { + } + + + public LevelOrderIndices(int to) { + this(0, to); + } + + + public LevelOrderIndices(int from, int to) { + this.from = Math.min(from, to); + this.to = Math.max(from, to); + } + + + public Object visit(Visitor visitor) { + LinkedList queue = new LinkedList(); + + queue.add(new int [] { from, to }); + + while (!queue.isEmpty()) { + int [] pair = queue.remove(); + + int mid = (pair[0] + pair[1]) >> 1; + + Object result = visitor.visit(mid); + + if (result != null) { + return result; + } + + if (mid-1 >= pair[0]) { + queue.add(new int [] { pair[0], mid-1 }); + } + + if (mid+1 <= pair[1]) { + pair[0] = mid+1; + queue.add(pair); + } + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,164 @@ +package de.intevation.gnv.jfreechart; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.jfree.data.Range; + +import org.jfree.data.general.AbstractSeriesDataset; + +/** + * An implementation of {@link org.jfree.data.xy.XYDataset} to create 2D charts. + * This dataset contains several PolygonSeries and is used by + * PolygonRenderer to draw its items into a 2D chart. + * + * @author Ingo Weinzierl + */ +public class PolygonDataset +extends AbstractSeriesDataset +{ + /** + * PolygonSeries included in this Dataset + */ + private List data; + + + /** + * Constructor. + */ + public PolygonDataset() { + data = new ArrayList(); + } + + /** + * Constructs a new PolygonDataset containing multiple PolygonSeries. + * + * @param series A collection containing some PolygonSeries. + */ + public PolygonDataset(Collection series) { + data = new ArrayList(series); + } + + /** + * Constructs a PolygonDataset with a single PolygonSeries. + * + * @param series A PolygonSeries. + */ + public PolygonDataset(PolygonSeries series) { + this(); + + if (series != null) { + data.add(series); + } + } + + + /** + * + * @param series + */ + public void addSeries(PolygonSeries series) { + if (series == null) + throw new IllegalArgumentException("Null 'series' argument."); + + data.add(series); + } + + /** + * + * @param series + */ + public void addAllSeries(Collection series) { + data.addAll(series); + } + + /** + * Retrieves the x-axis range of all PolygonSeries in this dataset. + * + * @return range of the x-axis. + */ + public Range getDomainBounds() { + double lower = Double.POSITIVE_INFINITY; + double upper = Double.NEGATIVE_INFINITY; + int seriesCount = getSeriesCount(); + + for (int s = 0; s < seriesCount; s++) { + PolygonSeries series = getSeries(s); + + Range domainRange = series.getDomainBounds(); + double minX = domainRange.getLowerBound(); + if (!Double.isNaN(minX)) { + lower = Math.min(lower, minX); + } + + double maxX = domainRange.getUpperBound(); + if (!Double.isNaN(maxX)) { + upper = Math.max(upper, maxX); + } + } + + return new Range(lower, upper); + } + + + /** + * Retrieves the y-axis range of all PolygonSeries in this dataset. + * + * @return the y-axis range. + */ + public Range getRangeBounds() { + double lower = Double.POSITIVE_INFINITY; + double upper = Double.NEGATIVE_INFINITY; + int seriesCount = getSeriesCount(); + + for (int i = 0; i < seriesCount; i++) { + PolygonSeries series = getSeries(i); + + Range range = series.getRangeBounds(); + double minX = range.getLowerBound(); + if (!Double.isNaN(minX)) { + lower = Math.min(lower, minX); + } + + double maxX = range.getUpperBound(); + if (!Double.isNaN(maxX)) { + upper = Math.max(upper, maxX); + } + } + + return new Range(lower, upper); + } + + + /** + * Returns the number of series in this dataset. + * + * @return the number of series in this dataset. + */ + public int getSeriesCount() { + return data.size(); + } + + + /** + * Returns the key for a series. + * + * @param index Index of a specific series. + * @return the series key of the series with the given index. + */ + public Comparable getSeriesKey(int index) { + return ((PolygonSeries)data.get(index)).getKey(); + } + + + /** + * + * @param idx Index. + * @return the series with the given index. + */ + public PolygonSeries getSeries(int idx) { + return (PolygonSeries)data.get(idx); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,505 @@ +package de.intevation.gnv.jfreechart; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Shape; + +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.AxisCollection; +import org.jfree.chart.axis.AxisLocation; +import org.jfree.chart.axis.AxisSpace; +import org.jfree.chart.axis.AxisState; +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.chart.plot.Plot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.PlotRenderingInfo; +import org.jfree.chart.plot.PlotState; + +import org.jfree.data.Range; + +import org.jfree.ui.RectangleEdge; +import org.jfree.ui.RectangleInsets; + +import org.jfree.util.ObjectList; + +/** + * A class for plotting polygons into a 2D chart. This plot makes use of + * PolygonRenderer. + * + * @author Ingo Weinzierl + */ +// TODO implement cloneable +public class PolygonPlot +extends Plot +{ + public static final String PLOT_TYPE = "PolygonPlot"; + + public static final PlotOrientation DEFAULT_PLOT_ORIENTATION = + PlotOrientation.VERTICAL; + + private PolygonDataset dataset; + private transient PolygonRenderer renderer; + + private PlotOrientation orientation; + + private RectangleInsets axisOffset; + + private ObjectList domainAxisLocation; + private ObjectList rangeAxisLocation; + private ObjectList domainAxes; + private ObjectList rangeAxes; + + + /** + * Constructs a new PolygonPlot with a dataset and a renderer. + * + * @param dataset Dataset containing polygons. + * @param renderer The renderer used to draw polygons. + */ + public PolygonPlot(PolygonDataset dataset, PolygonRenderer renderer) { + this(dataset, renderer, null, null, PlotOrientation.HORIZONTAL); + } + + + /** + * @param dataset Dataset containing polygons. + * @param renderer The renderer used to draw polygons. + * @param orientation The orientation used for this plot. + */ + public PolygonPlot( + PolygonDataset dataset, + PolygonRenderer renderer, + PlotOrientation orientation + ) { + this(dataset, renderer, null, null, orientation); + } + + + /** + * @param dataset Dataset containing polygons. + * @param renderer The renderer used to draw polygons. + * @param domainAxis The x axis. + * @param rangeAxis The y axis. + * @param orientation The orientation used for this plot. + */ + public PolygonPlot( + PolygonDataset dataset, + PolygonRenderer renderer, + ValueAxis domainAxis, + ValueAxis rangeAxis, + PlotOrientation orientation + ) { + super(); + + this.dataset = dataset; + this.renderer = renderer; + this.domainAxes = new ObjectList(); + this.rangeAxes = new ObjectList(); + this.domainAxisLocation = new ObjectList(); + this.rangeAxisLocation = new ObjectList(); + this.axisOffset = RectangleInsets.ZERO_INSETS; + + if (orientation != null) + this.orientation = orientation; + else + this.orientation = DEFAULT_PLOT_ORIENTATION; + + if (domainAxis != null) { + this.domainAxes.set(0, domainAxis); + domainAxis.setPlot(this); + } + domainAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT); + + if (rangeAxis != null) { + this.rangeAxes.set(0, rangeAxis); + rangeAxis.setPlot(this); + } + rangeAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT); + + configureDomainAxis(); + configureRangeAxis(); + } + + + public void configureDomainAxis() { + // we just have 1 dataset + Range domainAxisRange = getDataset().getDomainBounds(); + + for (int i = 0; i < domainAxes.size(); i++) { + ValueAxis axis = (ValueAxis) domainAxes.get(i); + + if (axis != null) { + axis.configure(); + axis.setRange(domainAxisRange); + } + } + } + + public ValueAxis getDomainAxis() { + return getDomainAxis(0); + } + + public void setDomainAxis(ValueAxis axis) { + domainAxes.set(0, axis); + } + + public ValueAxis getDomainAxis(int index) { + return index < domainAxes.size() + ? (ValueAxis)domainAxes.get(index) + : null; + } + + public ValueAxis getRangeAxis() { + return getRangeAxis(0); + } + + public void setRangeAxis(ValueAxis axis) { + rangeAxes.set(0, axis); + } + + public ValueAxis getRangeAxis(int index) { + return index < rangeAxes.size() + ? (ValueAxis)rangeAxes.get(index) + : null; + } + + public void configureRangeAxis() { + // we just have 1 dataset + Range rangeAxisRange = getDataset().getRangeBounds(); + + for (int i = 0; i < rangeAxes.size(); i++) { + ValueAxis axis = (ValueAxis) rangeAxes.get(i); + + if (axis != null) { + axis.configure(); + axis.setRange(rangeAxisRange); + } + } + } + + public PolygonDataset getDataset(){ + return this.dataset; + } + + public String getPlotType() { + return PLOT_TYPE; + } + + public void setDataset(PolygonDataset dataset) { + this.dataset = dataset; + } + + + /** + * This is the major method to draw the into a given Graphic2D object. + * + * @param g2 Graphics object where the plot is drawn into. + * @param area The bounds for drawing this plot. + * @param anchor An anchor point. + * @param parentState The plot state. + * @param info + */ + public void draw( + Graphics2D g2, + Rectangle2D area, + Point2D anchor, + PlotState parentState, + PlotRenderingInfo info + ) { + Graphics2D savedG2 = g2; + Rectangle2D savedDataArea = area; + + if (info != null) { + info.setPlotArea(area); + info.setDataArea(area); + } + + AxisSpace space = calculateAxisSpace(g2, area); + Rectangle2D dataArea = space.shrink(area, null); + + // draw background and outline + drawBackground(g2, area); + drawOutline(g2, area); + + Shape savedClip = g2.getClip(); + g2.clip(area); + + Composite originalComposite = g2.getComposite(); + g2.setComposite(AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, + getForegroundAlpha() + )); + + // draw axis + drawAxes(g2, area, dataArea, info); + + if (!isEmptyOrNull(dataset)) { + // draw data + drawPolygons(savedG2, dataArea, info); + drawLabels(savedG2, dataArea, info); + } + + g2.setClip(savedClip); + g2.setComposite(originalComposite); + } + + + /** + * Method to draw the axis for this plot. + * + * @param g2 + * @param plotArea + * @param dataArea + * @param plotState + */ + private void drawAxes( + Graphics2D g2, + Rectangle2D plotArea, + Rectangle2D dataArea, + PlotRenderingInfo plotState + ) { + AxisCollection axisCollection = new AxisCollection(); + + for (int i = 0; i < domainAxes.size(); i++) { + ValueAxis axis = (ValueAxis) domainAxes.get(i); + if (axis != null) + axisCollection.add(axis, getDomainAxisEdge(i)); + } + + for (int i = 0; i < rangeAxes.size(); i++) { + ValueAxis axis = (ValueAxis) rangeAxes.get(i); + if (axis != null) + axisCollection.add(axis, getRangeAxisEdge(i)); + } + + Map axisStateMap = new HashMap(); + + // draw the top axes + double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset( + dataArea.getHeight()); + Iterator iterator = axisCollection.getAxesAtTop().iterator(); + while (iterator.hasNext()) { + ValueAxis axis = (ValueAxis) iterator.next(); + AxisState info = axis.draw(g2, cursor, plotArea, dataArea, + RectangleEdge.TOP, plotState); + cursor = info.getCursor(); + axisStateMap.put(axis, info); + } + + // draw the bottom axes + cursor = dataArea.getMaxY() + + this.axisOffset.calculateBottomOutset(dataArea.getHeight()); + iterator = axisCollection.getAxesAtBottom().iterator(); + while (iterator.hasNext()) { + ValueAxis axis = (ValueAxis) iterator.next(); + AxisState info = axis.draw(g2, cursor, plotArea, dataArea, + RectangleEdge.BOTTOM, plotState); + cursor = info.getCursor(); + axisStateMap.put(axis, info); + } + + // draw the left axes + cursor = dataArea.getMinX() + - this.axisOffset.calculateLeftOutset(dataArea.getWidth()); + iterator = axisCollection.getAxesAtLeft().iterator(); + while (iterator.hasNext()) { + ValueAxis axis = (ValueAxis) iterator.next(); + AxisState info = axis.draw(g2, cursor, plotArea, dataArea, + RectangleEdge.LEFT, plotState); + cursor = info.getCursor(); + axisStateMap.put(axis, info); + } + + // draw the right axes + cursor = dataArea.getMaxX() + + this.axisOffset.calculateRightOutset(dataArea.getWidth()); + iterator = axisCollection.getAxesAtRight().iterator(); + while (iterator.hasNext()) { + ValueAxis axis = (ValueAxis) iterator.next(); + AxisState info = axis.draw(g2, cursor, plotArea, dataArea, + RectangleEdge.RIGHT, plotState); + cursor = info.getCursor(); + axisStateMap.put(axis, info); + } + } + + + /** + * Put some labels at data items into the plot. Uses PolygonRenderer to do + * this job. + * + * @param g2 + * @param area + * @param info + */ + private void drawLabels( + Graphics2D g2, + Rectangle2D area, + PlotRenderingInfo info + ) { + renderer.drawLabels(g2, this, area, dataset); + } + + + /** + * Plot the polygons. Uses PolygonRenderer to do this job. + * + * @param g2 + * @param area + * @param info + */ + private void drawPolygons( + Graphics2D g2, + Rectangle2D area, + PlotRenderingInfo info + ) { + renderer.drawPolygons(g2, this, area, dataset); + } + + + private AxisSpace calculateAxisSpace(Graphics2D g2, Rectangle2D plotArea) { + AxisSpace space = new AxisSpace(); + space = calculateRangeAxisSpace(g2, plotArea, space); + Rectangle2D tmpPlotArea = space.shrink(plotArea, null); + space = calculateDomainAxisSpace(g2, plotArea, space); + + return space; + } + + + private AxisSpace calculateDomainAxisSpace( + Graphics2D g2, + Rectangle2D plotArea, + AxisSpace space + ) { + if (space == null) + space = new AxisSpace(); + + for (int i = 0; i < domainAxes.size(); i++) { + Axis axis = (Axis) domainAxes.get(i); + + if (axis != null) { + RectangleEdge edge = getDomainAxisEdge(i); + space = axis.reserveSpace(g2, this, plotArea, edge, space); + } + } + + return space; + } + + + private AxisSpace calculateRangeAxisSpace( + Graphics2D g2, + Rectangle2D plotArea, + AxisSpace space + ) { + if (space == null) + space = new AxisSpace(); + + for (int i = 0; i < rangeAxes.size(); i++) { + Axis axis = (Axis) rangeAxes.get(i); + + if (axis != null) { + RectangleEdge edge = getRangeAxisEdge(i); + space = axis.reserveSpace(g2, this, plotArea, edge, space); + } + } + + return space; + } + + + public RectangleEdge getDomainAxisEdge() { + return Plot.resolveDomainAxisLocation( + getDomainAxisLocation(), orientation + ); + } + + + public RectangleEdge getDomainAxisEdge(int idx) { + AxisLocation location = getDomainAxisLocation(idx); + RectangleEdge result = Plot.resolveDomainAxisLocation( + location, orientation + ); + + if (result == null) + result = RectangleEdge.opposite(getDomainAxisEdge()); + + return result; + } + + + public RectangleEdge getRangeAxisEdge() { + return Plot.resolveRangeAxisLocation( + getRangeAxisLocation(), orientation + ); + } + + + public RectangleEdge getRangeAxisEdge(int idx) { + AxisLocation location = getRangeAxisLocation(idx); + RectangleEdge result = Plot.resolveRangeAxisLocation( + location, + orientation + ); + + if (result == null) + result = RectangleEdge.opposite(getRangeAxisEdge()); + + return result; + } + + + public AxisLocation getDomainAxisLocation() { + return (AxisLocation) domainAxisLocation.get(0); + } + + + public AxisLocation getDomainAxisLocation(int idx) { + if (idx < domainAxisLocation.size()) + return (AxisLocation) domainAxisLocation.get(idx); + + return null; + } + + + public AxisLocation getRangeAxisLocation() { + return (AxisLocation) rangeAxisLocation.get(0); + } + + + public AxisLocation getRangeAxisLocation(int idx) { + if (idx < rangeAxisLocation.size()) + return (AxisLocation) rangeAxisLocation.get(idx); + + return null; + } + + + /** + * @return true, if dataset is null or if it does not contain any + * PolygonSeries, otherwise false. + */ + private boolean isEmptyOrNull(PolygonDataset dataset) { + if (dataset != null) { + int seriesCount = dataset.getSeriesCount(); + for (int s = 0; s < seriesCount; s++) { + PolygonSeries series = dataset.getSeries(s); + if (series.getItemCount() > 0) { + return false; + } + } + } + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,304 @@ +package de.intevation.gnv.jfreechart; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Shape; + +import java.awt.geom.GeneralPath; + +import java.awt.geom.Rectangle2D.Double; + +import java.awt.geom.Rectangle2D; + +import java.util.ArrayList; + +import org.apache.log4j.Logger; + +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.data.Range; + +import org.jfree.text.TextUtilities; + +import org.jfree.ui.RectangleEdge; + +/** + * This renderer is used to draw polygons into a Graphics object. + * + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class PolygonRenderer +{ + private static Logger log = Logger.getLogger( + PolygonRenderer.class); + + /** + * This interfaces describes a single method to retrieve a Paint object + * for a given index. + */ + public interface PaintLookup { + + /** + * + * @param index Index. + * @return Paint + */ + Paint getPaint(int index); + + } // interface PaintLookup + + /** + * This class is used to generate labels for a given series. + */ + public static class DefaultLabelGenerator + implements PolygonSeriesLabelGenerator + { + /** + * Construts an empty DefaultLabelGenerator. + */ + public DefaultLabelGenerator() { + } + + /** + * + * @param series A PolygonSeries. + * @return The label of series. + */ + public String generateLabel(PolygonSeries series) { + Object label = series.getAttribute("label"); + return label != null + ? toString(label) + : null; + } + + /** + * + * @param label Object + * @return String representaton of label. + */ + protected String toString(Object label) { + return label.toString(); + } + } // class DefaultLabelGenerator + + /** + * Constructor. + */ + public static final PolygonSeriesLabelGenerator + DEFAULT_LABEL_GENERATOR_INSTANCE = new DefaultLabelGenerator(); + + protected PaintLookup lookup; + + protected PolygonSeriesLabelGenerator labelGenerator; + + + public PolygonRenderer(PaintLookup lookup) { + this(lookup, null); + } + + + public PolygonRenderer( + PaintLookup lookup, + PolygonSeriesLabelGenerator labelGenerator + ) { + this.lookup = lookup; + this.labelGenerator = labelGenerator; + } + + /** + * This method draws polygons of each series in dataset into + * the given graphics object. If a polygon has no attribute 'fill', we + * expect that it is a line, otherwise the polygon is filled. + * + */ + public void drawPolygons( + Graphics2D graphics, + PolygonPlot plot, + Rectangle2D area, + PolygonDataset dataset + ) { + int seriesCount = dataset.getSeriesCount(); + for (int i = 0; i < seriesCount; i++) { + PolygonSeries series = dataset.getSeries(i); + Integer colorIdx = (Integer)series.getAttribute("fill"); + + if (colorIdx != null) { + Paint paint = lookup.getPaint(colorIdx.intValue()); + graphics.setPaint(paint != null ? paint : Color.black); + graphics.fill(constructShape(plot, area, series, true)); + } + else { + Number lineWidth = (Number)series.getAttribute("line.width"); + BasicStroke stroke = new BasicStroke( + lineWidth != null ? lineWidth.floatValue() : 1f); + graphics.setStroke(stroke); + graphics.setPaint(Color.black); + graphics.draw(constructShape(plot, area, series, false)); + } + } + } + + /** + * Draw labels at each item of a series in the given dataset. If the series + * has no label attritue, no label is drawn. + * + */ + public void drawLabels( + final Graphics2D graphics, + final PolygonPlot plot, + final Rectangle2D area, + PolygonDataset dataset + ) { + if (labelGenerator == null) { + return; + } + + final ArrayList bboxes = new ArrayList(); + + Font font = graphics.getFont(); + font = font.deriveFont(Font.PLAIN, Math.max(8, font.getSize()-3)); + graphics.setFont(font); + FontMetrics metrics = graphics.getFontMetrics(font); + + for (int i = dataset.getSeriesCount()-1; i >= 0; --i) { + PolygonSeries series = dataset.getSeries(i); + + String label = labelGenerator.generateLabel(series); + if (label == null) { + continue; + } + + final Rectangle2D box = TextUtilities.getTextBounds( + label, graphics, metrics); + + for (int j = series.getItemCount()-1; j >= 0; --j) { + final CompactXYItems ring = series.getItem(j); + LevelOrderIndices loi = new LevelOrderIndices(ring.size()-1); + Rectangle2D r = (Rectangle2D)loi.visit( + new LevelOrderIndices.Visitor() + { + ValueAxis da = plot.getDomainAxis(); + ValueAxis ra = plot.getRangeAxis(); + RectangleEdge de = plot.getDomainAxisEdge(); + RectangleEdge re = plot.getRangeAxisEdge(); + Rectangle2D.Double r = new Rectangle2D.Double( + 0d, 0d, box.getWidth(), box.getHeight()); + + public Object visit(int index) { + r.x = da.valueToJava2D(ring.getX(index), area, de) + - 0.5*box.getWidth(); + r.y = ra.valueToJava2D(ring.getY(index), area, re) + + 0.5*box.getHeight(); + + for (Rectangle2D b: bboxes) { + if (b.intersects(r)) { + return null; + } + } + return r; + } + }); + + if (r != null) { + bboxes.add(r); + graphics.drawString( + label, (float)r.getX(), (float)r.getY()); + } + } // for all items in series + } // for all series + } + + /** + * Creates a shape made up of the CompactXYItems object stored in the given + * series. + * + * @param plot The plot. + * @param area The boundary. + * @param series The series storing the items. + * @param close Specifies if the polygon should be closed or not. + * @return the constructed shape. + */ + protected Shape constructShape( + PolygonPlot plot, + Rectangle2D area, + PolygonSeries series, + boolean close + ) { + ValueAxis da = plot.getDomainAxis(); + ValueAxis ra = plot.getRangeAxis(); + RectangleEdge de = plot.getDomainAxisEdge(); + RectangleEdge re = plot.getRangeAxisEdge(); + + CompactXYItems [] rings = series.getRings(); + GeneralPath path = new GeneralPath(); + + for (int i = 0; i < rings.length; ++i) { + + CompactXYItems ring = rings[i]; + + double [] data = ring.getData(); + + if (data.length >= 2) { + path.moveTo( + (float)da.valueToJava2D(data[0], area, de), + (float)ra.valueToJava2D(data[1], area, re)); + } + for (int j = 2; j < data.length;) { + path.lineTo( + (float)da.valueToJava2D(data[j++], area, de), + (float)ra.valueToJava2D(data[j++], area, re)); + } + if (close) { + path.closePath(); + } + } + return path; + } + + /** + * Retrieves the bounding box of a dataset. + */ + public Rectangle2D getBoundingBox(PolygonDataset dataset) { + Rectangle2D bbox = null; + + for (int i = 0, N = dataset.getSeriesCount(); i < N; i++) { + Range domain = dataset.getSeries(i).getDomainBounds(); + Range range = dataset.getSeries(i).getRangeBounds(); + + double x = domain.getLowerBound(); + double y = range.getLowerBound(); + double w = Math.abs(domain.getUpperBound() - x); + double h = Math.abs(range.getUpperBound() - y); + + if (bbox == null) { + bbox = new Rectangle2D.Double(x, y, w, h); + } + else { + bbox.add(new Rectangle2D.Double(x, y, w, h)); + } + } + + return bbox; + } + + /** + * + * @return the bounds of a series. + */ + public Rectangle2D getBounds(PolygonSeries series) { + + Range domain = series.getDomainBounds(); + Range range = series.getRangeBounds(); + + return new Rectangle2D.Double( + domain.getLowerBound(), range.getLowerBound(), + domain.getUpperBound(), range.getUpperBound() + ); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,222 @@ +package de.intevation.gnv.jfreechart; + +import java.util.HashMap; +import java.util.Map; + +import org.jfree.data.Range; + +import org.jfree.data.general.Series; + +/** + * This class represents a series of polygon items. + * + * @author Sascha Teichmann + * @author Ingo Weinzierl + */ +public class PolygonSeries +extends Series +{ + /** + * Polygons. + */ + protected CompactXYItems [] rings; + + /** + * A map containing attribues. + */ + protected Map attributes; + + /** + * The unique key of this series. + */ + private static long uniqueKey; + + /** + * + * @return a unique key. + */ + protected synchronized static Long createUniqueKey() { + return new Long(uniqueKey++); + } + + /** + * Constructor to create an empty PolygonSeries with a unique key. + */ + public PolygonSeries() { + this(createUniqueKey(), null); + } + + /** + * + * @param key The key used for this series. + * @param rings Polygons. + */ + public PolygonSeries(Comparable key, CompactXYItems [] rings) { + this(key, null, rings, new HashMap()); + } + + /** + * + * @param key The key used for this series. + * @param description A description of this series. + * @param rings Polygons. + */ + public PolygonSeries( + Comparable key, + String description, + CompactXYItems[] rings + ) { + this(key, description, rings, new HashMap()); + } + + /** + * + * @param key The key used for this series. + * @param description A description of this series. + * @param rings Polygons. + * @param attributes Some attribues. + */ + public PolygonSeries( + Comparable key, + String description, + CompactXYItems [] rings, + Map attributes + ) { + super(key, description); + this.rings = rings; + this.attributes = attributes; + } + + + public void setRings(CompactXYItems [] rings) { + this.rings = rings; + } + + + public CompactXYItems [] getRings() { + return rings; + } + + + public void addRing(CompactXYItems newRing) { + if (rings == null) { + rings = new CompactXYItems [] { newRing }; + } + else { + CompactXYItems [] nRings = new CompactXYItems[rings.length + 1]; + System.arraycopy(rings, 0, nRings, 0, rings.length); + nRings[rings.length] = newRing; + rings = nRings; + } + } + + + public void addRings(CompactXYItems [] newRings) { + if (newRings == null || newRings.length == 0) { + return; + } + if (rings == null || rings.length == 0) { + rings = newRings; + } + else { + CompactXYItems [] both = + new CompactXYItems[rings.length + newRings.length]; + System.arraycopy(rings, 0, both, 0, rings.length); + System.arraycopy(newRings, 0, both, rings.length, newRings.length); + rings = both; + } + } + + + public Object getAttribute(Object key) { + return attributes.get(key); + } + + + public Object setAttribute(Object key, Object value) { + return attributes.put(key, value); + } + + + public int getItemCount() { + return rings != null ? rings.length : 0; + } + + + public CompactXYItems getItem(int idx) { + return rings[idx]; + } + + + public Object removeAttribute(Object key) { + return attributes.remove(key); + } + + + public boolean hasAttribute(Object key) { + return attributes.containsKey(key); + } + + + /** + * + * @return the range of the x axis. + */ + public Range getDomainBounds() { + double upper = Double.NEGATIVE_INFINITY; + double lower = Double.POSITIVE_INFINITY; + int count = getItemCount(); + + for (int i = 0; i < count; i++) { + CompactXYItems items = getItem(i); + double minX = items.getMinX(); + double maxX = items.getMaxX(); + + if (!Double.isNaN(minX)) { + lower = Math.min(lower, minX); + } + + if (!Double.isNaN(maxX)) { + upper = Math.max(upper, maxX); + } + } + + if (lower > upper) { + return null; + } + + return new Range(lower, upper); + } + + + /** + * + * @return the range of the y axis. + */ + public Range getRangeBounds() { + double upper = Double.NEGATIVE_INFINITY; + double lower = Double.POSITIVE_INFINITY; + int count = getItemCount(); + + for (int i = 0; i < count; i++) { + CompactXYItems items = getItem(i); + double minY = items.getMinY(); + double maxY = items.getMaxY(); + + if (!Double.isNaN(minY)) { + lower = Math.min(lower, minY); + } + + if (!Double.isNaN(maxY)) { + upper = Math.max(upper, maxY); + } + } + + if (lower > upper) { + return null; + } + + return new Range(lower, upper); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeriesLabelGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeriesLabelGenerator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,17 @@ +package de.intevation.gnv.jfreechart; + +/** + * This interface describes a single method generating labels by given Series. + * + * @author Sascha L. Teichmann + */ +public interface PolygonSeriesLabelGenerator +{ + /** + * + * @param series The given series. + * @return A label for this series. + */ + String generateLabel(PolygonSeries series); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +This package contains classes and interfaces used to create 2D charts. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/layer/LayerArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/layer/LayerArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,42 @@ +package de.intevation.gnv.layer; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; + +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.gnv.artifacts.GNVArtifactBase; + +/** + * Artifact used for Product Layer. + * @author Tim Englich + */ +public class LayerArtifact extends GNVArtifactBase{ + + /** + * the logger, used to log exceptions and additionally information + */ + private static Logger log = Logger.getLogger(LayerArtifact.class); + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 409054207294748753L; + + /** + * Constructor + */ + public LayerArtifact() { + super(); + log.debug("LayerArtifact.Constructor"); + this.name = "layer"; + } + + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("LayerArtifact.setup"); + super.setup(identifier, factory, context, data); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/layer/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/layer/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes providing specific artifacts representing +Layer. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,202 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; + +import com.vividsolutions.jts.index.strtree.STRtree; + +import java.awt.Dimension; + +import java.io.Serializable; + +import java.util.Arrays; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Does an area interpolation for "Horizontalschnitte". + * + * @author Sascha L. Teichmann + */ +public class AreaInterpolation +implements Serializable +{ + private static Logger log = Logger.getLogger(AreaInterpolation.class); + + /** + * The generated raster. + */ + protected double [] raster; + + /** + * The width of the raster. + */ + protected int width; + /** + * The height of the raster. + */ + protected int height; + + /** + * Default constructor. + */ + public AreaInterpolation() { + } + + /** + * Returns the width of the generated raster. + * @return the width of the raster. + */ + public int getWidth() { + return width; + } + + /** + * Returns the height of the raster. + * @return The height of the raster. + */ + public int getHeight() { + return height; + } + + /** + * The generated raster. + * @return the raster. + */ + public double [] getRaster() { + return raster; + } + + /** + * Epsilon for numerical stability. + */ + public static final double EPS = 1e-6d; + + + /** + * Fills a raster by interpolating the input values. + * @param points The attributed input values. + * @param boundingBox The world area where to interpolate. + * @param samples The width and height of the raster. + * @param depth The callback to query the depth at a given point. + * @param extrapolationRounds Number of extrapolation point layers + * to generate before doing the interpolation. + * @return true if the interpolation succeeds else false. + */ + public boolean interpolate( + List points, + Envelope boundingBox, + Dimension samples, + XYDepth depth, + int extrapolationRounds + ) { + boolean debug = log.isDebugEnabled(); + + if (points == null || points.isEmpty()) { + log.warn("no points to interpolate"); + return false; + } + + List cells = GridCell.pointsToGridCells( + points, + Interpolation2D.relevantArea( + boundingBox, + points), + extrapolationRounds); + + if (cells.isEmpty()) { + log.warn("no cells to interpolate"); + return false; + } + + int W = samples.width; + int H = samples.height; + + double cellWidth = boundingBox.getWidth() / W; + double cellHeight = boundingBox.getHeight() / H; + + STRtree spatialIndex = new STRtree(); + + for (GridCell cell: cells) { + spatialIndex.insert(cell.getEnvelope(), cell); + } + + if (debug) { + log.debug("width: " + boundingBox.getWidth()); + log.debug("height: " + boundingBox.getHeight()); + log.debug("sample width: " + W); + log.debug("sample height: " + H); + log.debug("cell width: " + cellWidth); + log.debug("cell height: " + cellHeight); + } + + Envelope queryBuffer = new Envelope(); + Coordinate center = new Coordinate(); + GridCell.CellFinder finder = new GridCell.CellFinder(); + + double [] raster = new double[W*H]; + Arrays.fill(raster, Double.NaN); + + double minX = boundingBox.getMinX(); + double minY = boundingBox.getMinY(); + + long startTime = System.currentTimeMillis(); + + int pos = 0; + for (int j = 0; j < H; ++j) { + + double y = j*cellHeight + 0.5d*cellHeight + minY; + double x = 0.5d*cellWidth + minX; + + for (int end = pos + W; pos < end; ++pos, x += cellWidth) { + + queryBuffer.init(x - EPS, x + EPS, y - EPS, y + EPS); + center.x = x; center.y = y; + finder.prepare(center); + spatialIndex.query(queryBuffer, finder); + + GridCell found = finder.found; + + if (found == null || depth.depth(center) > 0d) { + continue; + } + + double z1 = Interpolation2D.interpolate( + found.p1.x, found.p1.z, + found.p2.x, found.p2.z, + center.x); + double z2 = Interpolation2D.interpolate( + found.p3.x, found.p3.z, + found.p4.x, found.p4.z, + center.x); + double y1 = Interpolation2D.interpolate( + found.p1.x, found.p1.y, + found.p2.x, found.p2.y, + center.x); + double y2 = Interpolation2D.interpolate( + found.p3.x, found.p3.y, + found.p4.x, found.p4.y, + center.x); + raster[pos] = Interpolation2D.interpolate( + y1, z1, + y2, z2, + center.y); + } + } + + long stopTime = System.currentTimeMillis(); + + if (debug) { + log.debug("interpolation took: " + + (stopTime - startTime)/1000f + " secs"); + } + + this.raster = raster; + this.width = W; + this.height = H; + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedPoint2ds.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedPoint2ds.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,155 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; + +import de.intevation.gnv.utils.Pair; + +import java.io.Serializable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Stores the results of an area interpolation. + * Used to generate the final products. + * + * @author Sascha L. Teichmann + */ +public class AttributedPoint2ds +implements Serializable +{ + /** + * The list of input points. + */ + protected List points; + + /** + * The map of input attributes that are need to generate + * the products. + */ + protected Map attributes; + + /** + * The interpolation result. + */ + protected AreaInterpolation interpolation; + + /** + * The JTS multi line strings to be written by GeoTools later. + */ + protected List> lineStrings; + + /** + * The JTS multi polygons to be written by GeoTools later. + */ + protected Map polygons; + + /** + * Default constructor. + */ + public AttributedPoint2ds() { + } + + /** + * Constructor to create a AttributedPoint2ds with a list + * of input points. + * + * @param points The input points. + */ + public AttributedPoint2ds(List points) { + this.points = points; + } + + /** + * Returns an attribute from the map of external attributes. + * @param key The key of the attribute. + * @return The attribute or null if the attribute was not found. + */ + public Object getAttribute(Object key) { + return attributes != null + ? attributes.get(key) + : null; + } + + /** + * Stores an attribute under a given key in + * the map of external attributes. + * @param key The key of the attribute. + * @param value The attribute value. + */ + public void setAttribute(Object key, Object value) { + if (attributes == null) { + attributes = new HashMap(); + } + attributes.put(key, value); + } + + /** + * Returns the input points. + * @return The input points. + */ + public List getPoints() { + return points; + } + + /** + * Sets the input points. + * @param points The input points. + */ + public void setPoints(List points) { + this.points = points; + } + + /** + * Sets the area interpolation result. + * @param interpolation The new interpolation result. + */ + public void setInterpolation(AreaInterpolation interpolation) { + this.interpolation = interpolation; + } + + /** + * Returns the area interpolation result. + * @return The interpolation result. + */ + public AreaInterpolation getInterpolation() { + return interpolation; + } + + /** + * Sets the produced JTS multi polygons. + * @param polygons The multi polygons. + */ + public void setPolygons(Map polygons) { + this.polygons = polygons; + } + + /** + * Returns the JTS multi polygons. + * @return The polygons. + */ + public Map getPolygons() { + return polygons; + } + + /** + * Set the produced JTS multi line strings. + * @param lineStrings The line strings. + */ + public void setLineStrings( + List> lineStrings + ) { + this.lineStrings = lineStrings; + } + + /** + * Returns the produced JTS multi line strings. + * @return The line strings. + */ + public List> getLineStrings() { + return lineStrings; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,144 @@ +package de.intevation.gnv.math; + +import de.intevation.gnv.jfreechart.PolygonDataset; + +import java.io.Serializable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Stores the results of a 3D interpolation. Used to generate the final + * products. + * + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class AttributedXYColumns +implements Serializable +{ + /** + * The list of height value column. + */ + protected List columns; + + /** + * The extra input attributes which are not relevant + * for the interpolation but for generating the results. + */ + protected Map attributes; + + /** + * The interpolation result. + */ + protected Interpolation3D interpolation; + + /** + * Dataset to be used in a {@link de.intevation.gnv.jfreechart.PolygonPlot}. + */ + protected PolygonDataset dataset; + + /** + * Default constructor. + */ + public AttributedXYColumns() { + } + + /** + * Constructor to create a AttributedXYColumns instance only + * with the height value columns. + * @param columns The height value columns. + */ + public AttributedXYColumns(List columns) { + this(columns, null); + } + + /** + * Constructor to create a AttributedXYColumns with + * height value columns and the attributes to be used to + * generate the results. + * @param columns The height value columns. + * @param attributes The external attributes. + */ + public AttributedXYColumns( + List columns, + Map attributes + ) { + this.columns = columns; + this.attributes = attributes; + } + + /** + * Gets an attribute. + * @param key The key of the attribute. + * @return The attribute or null if no such attribue is found. + */ + public Object getAttribute(Object key) { + return attributes != null + ? attributes.get(key) + : null; + } + + /** + * Puts an attribute to the map of external attributes. + * @param key The key of the attribute. + * @param value The value of the attribute. + */ + public void setAttribute(Object key, Object value) { + if (attributes == null) { + attributes = new HashMap(); + } + attributes.put(key, value); + } + + /** + * Returns the list of height value columns. + * @return The list of height value columns. + */ + public List getXYColumns() { + return columns; + } + + /** + * Sets the list of height value columns. + * @param columns The new list of height value columns. + */ + public void setXYColumns(List columns) { + this.columns = columns; + } + + /** + * Sets the interpolation result. + * @param interpolation The new interpolation result. + */ + public void setInterpolation(Interpolation3D interpolation) { + this.interpolation = interpolation; + } + + /** + * Gets the interpolation results. + * @return The interpolation results. + */ + public Interpolation3D getInterpolation() { + return interpolation; + } + + /** + * Sets the generated polygon data set to be used in a + * {@link de.intevation.gnv.jfreechart.PolygonPlot}. + * @param dataset The polygon data set. + */ + public void setPolygonDataset(PolygonDataset dataset) { + this.dataset = dataset; + } + + /** + * Returns the polygon data set. + * @return The polygon data set. + */ + public PolygonDataset getPolygonDataset() { + return dataset; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/ConstantFunction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/ConstantFunction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,37 @@ +package de.intevation.gnv.math; + +import org.apache.commons.math.analysis.UnivariateRealFunction; + +/** + * Models a constant function to be used in function evaluation. + * + * @author Sascha L. Teichmann + */ +public class ConstantFunction +implements UnivariateRealFunction +{ + /** + * The constant value. + */ + protected double value; + + /** + * Defaut constructor. + */ + public ConstantFunction() { + } + + /** + * Constructor to create a ConstantFunction with + * a given constant value. + * @param value The constant value. + */ + public ConstantFunction(double value) { + this.value = value; + } + + public double value(double x) { + return value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/ConstantXYDepth.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/ConstantXYDepth.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Instances of the implementation return a constant value. + * + * @author Sascha L. Teichmann + */ +public class ConstantXYDepth +implements XYDepth +{ + /** + * The constant depth. + */ + protected double depth; + + /** + * Default constructor. The constant depth = 0. + */ + public ConstantXYDepth() { + } + + /** + * Construtor to create a ConstantXYDepth with a given depth. + * @param depth The constant depth. + */ + public ConstantXYDepth(double depth) { + this.depth = depth; + } + + public double depth(Coordinate coordinate) { + return depth; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,408 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.algorithm.CGAlgorithms; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +import com.vividsolutions.jts.index.ItemVisitor; + +import java.io.Serializable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Spans a rectangle of points to be used in spatial indexing. + * + * @author Sascha L. Teichmann + */ +public class GridCell +implements Serializable +{ + private static Logger log = Logger.getLogger(GridCell.class); + + /** + * Callback for {@link com.vividsolutions.jts.index.SpatialIndex} + * to find a GridCell which contains a given point. + */ + public static final class CellFinder + implements ItemVisitor + { + /** + * Stores the found GridCell. + */ + public GridCell found; + + /** + * The query point. + */ + protected Point point; + + /** + * Default constructor. + */ + public CellFinder() { + } + + /** + * Prepares a spatial index lookup. + * @param center The query point. + */ + public void prepare(Coordinate center) { + found = null; + point = GEOMETRY_FACTORY.createPoint(center); + } + + /** + * Called by the spatial index as a 2nd order filter. + * @param item The GridCell to test. + */ + public void visitItem(Object item) { + if (found == null) { + GridCell cell = (GridCell)item; + if (cell.contains(point)) { + found = cell; + } + } + } + } // class CellFinder + + /** + * The first point. + */ + public Point2d p1; + /** + * The second point. + */ + public Point2d p2; + /** + * The third point. + */ + public Point2d p3; + /** + * The fourth point. + */ + public Point2d p4; + + /** + * Polygon created from the four points. + */ + protected Polygon polygon; + + /** + * Geometry factory to create the query points and the polygons. + */ + public static final GeometryFactory GEOMETRY_FACTORY + = new GeometryFactory(); + + /** + * Default constructor. + */ + public GridCell() { + } + + /** + * Constructor to create a GridCell out of four given points.. + * @param p1 The first point. + * @param p2 The second point. + * @param p3 The thrid point. + * @param p4 The fourth point. + */ + public GridCell(Point2d p1, Point2d p2, Point2d p3, Point2d p4) { + this.p1 = p1; + this.p2 = p2; + this.p3 = p3; + this.p4 = p4; + createPolygon(); + } + + /** + * Creates the polygon from the four points. + */ + protected void createPolygon() { + Coordinate [] coords = new Coordinate [] { p1, p2, p3, p4, p1 }; + if (!CGAlgorithms.isCCW(coords)) { + for (int i = 0, j = coords.length-1; i < j; ++i, --j) { + Coordinate c = coords[i]; + coords[i] = coords[j]; + coords[j] = c; + } + } + LinearRing shell = GEOMETRY_FACTORY + .createLinearRing(coords); + + if (!shell.isValid()) { + log.warn("linear ring is not valid"); + } + + polygon = GEOMETRY_FACTORY.createPolygon(shell, null); + } + + /** + * Returns the envelope of the four point polygon. + * @return the envelope. + */ + public Envelope getEnvelope() { + return polygon.getEnvelopeInternal(); + } + + /** + * Test if a given point is inside this grid cell. + * @param coord + * @return true, if this grid cell contains the given point - otherwise + * false. + */ + public boolean contains(Geometry coord) { + return polygon.contains(coord); + } + + /** + * Converts a list of points to a list of grid cells. + * @param points This list of points. + * @return This list of grid cells. + */ + public static List pointsToGridCells( + List points + ) { + return pointsToGridCells(points, null); + } + + /** + * Converts a list of points to a list of grid cells. + * Points that are not in a relevant area are ignored. + * @param points The list of points. + * @param relevantArea The relevant area. + * @return The list of grid cells. + */ + public static List pointsToGridCells( + List points, + Envelope relevantArea + ) { + return pointsToGridCells(points, relevantArea, 0); + } + + private static final int NEIGHBORS [][] = { + { -1, -1 }, // 0 + { -1, 0 }, // 1 + { -1, +1 }, // 2 + { 0, +1 }, // 3 + { +1, +1 }, // 4 + { +1, 0 }, // 5 + { +1, -1 }, // 6 + { 0, -1 } // 7 + }; + + /** + * Generate points by extrapolating border points. + * @param rows (i, j) indexed map of points. + * @param minI min known i. + * @param maxI max known i. + * @param minJ min known j. + * @param maxJ max known j. + * @param rounds Deternine how many extra rings should be generated. + * @param relevantArea The relevant area. + * @return number of newly generated points. + */ + public static int extrapolate( + HashMap> rows, + int minI, int maxI, + int minJ, int maxJ, + int rounds, + Envelope relevantArea + ) { + Point2d [] neighbors = new Point2d[NEIGHBORS.length]; + Point2d [] positions = new Point2d[NEIGHBORS.length]; + + int total = 0; + + ArrayList> prio = + new ArrayList>(NEIGHBORS.length); + + for (int i = 0; i < NEIGHBORS.length; ++i) { + prio.add(new ArrayList()); + } + + while (rounds-- > 0) { + for (int i = minI; i <= maxI; ++i) { + for (int j = minJ; j <= maxJ; ++j) { + Point2d p = get(rows, i, j); + if (p != null) { + continue; + } + + int count = 0; + + for (int k = 0; k < neighbors.length; ++k) { + neighbors[k] = positions[k] = null; + int dij [] = NEIGHBORS[k]; + Point2d n1 = get(rows, i+ dij[0], j+ dij[1]); + Point2d n2 = get(rows, i+2*dij[0], j+2*dij[1]); + if (n1 != null && n2 != null) { + ++count; + } + } + + if (count > 0) { + prio.get(count-1).add(new IJKey(i, j)); + } + } // for all columns + } // for all rows + + int N = 0; + + for (int l = NEIGHBORS.length-1; l >= 0; --l) { + ArrayList list = prio.get(l); + for (IJKey ij: list) { + int i = ij.i; + int j = ij.j; + for (int k = 0; k < neighbors.length; ++k) { + neighbors[k] = positions[k] = null; + int dij [] = NEIGHBORS[k]; + Point2d n1 = get(rows, i+ dij[0], j+ dij[1]); + Point2d n2 = get(rows, i+2*dij[0], j+2*dij[1]); + if (n1 != null && n2 != null) { + neighbors[k] = n1; + positions[k] = n1.extrapolate(-1d, n2); + } + } + + Point2d avg = Point2d.average(positions); + + if (avg != null && avg.near(positions) + && (relevantArea == null + || relevantArea.contains(avg.x, avg.y))) { + avg.i = i; + avg.j = j; + avg.inverseDistanceWeighting(neighbors); + put(rows, avg, i, j); + } + } + N += list.size(); + list.clear(); + } + + if (N == 0) { + break; + } + total += N; + } // for all rounds + + return total; + } + + /** + * Converts a list of points to a list of grid cells. + * @param points The list of points. + * @param relevantArea The relevant area. If a point is + * not inside this area it is ignored during the build process. + * @param extrapolationRounds Number of extra point rings. + * 0 = no extrpolation. + * @return The list of grid cells. + */ + public static List pointsToGridCells( + List points, + Envelope relevantArea, + int extrapolationRounds + ) { + int minI = Integer.MAX_VALUE; + int maxI = Integer.MIN_VALUE; + int minJ = Integer.MAX_VALUE; + int maxJ = Integer.MIN_VALUE; + + HashMap> rows = + new HashMap>(); + + int culled = 0; + + for (Point2d p: points) { + + if (relevantArea != null && !relevantArea.contains(p.x, p.y)) { + ++culled; + continue; + } + + if (p.i < minI) minI = p.i; + if (p.i > maxI) maxI = p.i; + if (p.j < minJ) minJ = p.j; + if (p.j > maxJ) maxJ = p.j; + + HashMap row = rows.get(p.i); + + if (row == null) { + rows.put(p.i, row = new HashMap()); + } + + row.put(p.j, p); + } + + ArrayList cells = new ArrayList(points.size()); + + int extrapolated = extrapolate( + rows, + minI, maxI, + minJ, maxJ, + extrapolationRounds, + relevantArea); + + for (int i = minI + 1; i <= maxI; ++i) { + HashMap row1 = rows.get(i-1); + HashMap row2 = rows.get(i); + + if (row1 == null || row2 == null) { + continue; + } + + for (int j = minJ + 1; j < maxJ; ++j) { + Point2d p1 = row1.get(j-1); + Point2d p2 = row1.get(j); + Point2d p3 = row2.get(j); + Point2d p4 = row2.get(j-1); + + if (p1 != null && p2 != null && p3 != null && p4 != null) { + cells.add(new GridCell(p1, p2, p3, p4)); + } + } + } // for all rows + + if (log.isDebugEnabled()) { + log.debug("culled points: " + culled); + log.debug("extrapolated points: " + extrapolated); + log.debug("min/max i: " + minI + " / " + maxI); + log.debug("min/max j: " + minJ + " / " + maxJ); + log.debug("cells found: " + cells.size()); + } + + return cells; + } + + private static Point2d get( + HashMap> rows, + int i, int j + ) { + HashMap row = rows.get(i); + return row != null ? row.get(j) : null; + } + + private static void put( + HashMap> rows, + Point2d point, + int i, int j + ) { + Integer I = Integer.valueOf(i); + HashMap row = rows.get(I); + if (row == null) { + rows.put(I, row = new HashMap()); + } + row.put(j, point); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/HeightValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/HeightValue.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,83 @@ +package de.intevation.gnv.math; + +import java.io.Serializable; + +import java.util.Comparator; + +/** + * An attributed height value. It holds a z value, a parameter value + * and a layer index. + * + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class HeightValue +implements Serializable +{ + /** + * Comparator to sort HeightValues by their z value + * in reversed order. + */ + public static final Comparator INV_Z_COMPARATOR = new Comparator() { + public int compare(Object a, Object b) { + HeightValue ha = (HeightValue)a; + HeightValue hb = (HeightValue)b; + if (ha.z > hb.z) return -1; + if (ha.z < hb.z) return +1; + return 0; + } + }; + + /** + * The height value. + */ + public double z; + + /** + * The parameter value. + */ + public double v; + + /** + * The layer index; + */ + public int k; + + /** + * Constructor to create a HeightValue with a given height, + * parameter value and layer index. + * @param z The height. + * @param v The parameter value. + * @param k The layer index. + */ + public HeightValue(double z, double v, int k) { + this.z = z; + this.v = v; + this.k = k; + } + + /** + * Return the height of this HeightValue. + * @return the height. + */ + public double getZ() { + return z; + } + + /** + * Return the parameter value of this HeightValue. + * @return The parameter value. + */ + public double getV() { + return v; + } + + /** + * Returns the layer index of this HeightValue. + * @return The layer index. + */ + public double getK() { + return k; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/IJKey.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/IJKey.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,73 @@ +package de.intevation.gnv.math; + +import java.io.Serializable; + +/** + * Tuple (i, j) to model a pair of integers. Useful to store index pairs + * in maps. + * @author Sascha L. Teichmann + */ +public class IJKey +implements Serializable +{ + /** + * i component of the tuple. + */ + public int i; + /** + * j component of the tuple. + */ + public int j; + + /** + * Default constructor. + */ + public IJKey() { + } + + /** + * Constructor to set i and j. + * @param i The i component. + * @param j The j component. + */ + public IJKey(int i, int j) { + this.i = i; + this.j = j; + } + + /** + * Orders i and j by their values. + */ + public void sort() { + if (i > j) { + int t = i; + i = j; + j = t; + } + } + + /** + * Hashes i and j into a common value. + * @return the hash code. + */ + @Override + public int hashCode() { + return (i << 16) | j; + } + + /** + * IJKeys are considered equal if the i and j components + * are equal. + * @param obj The other IJKey + * @return true if the IJKeys are equal else false. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof IJKey)) { + return false; + } + IJKey other = (IJKey)obj; + return i == other.i && j == other.j; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation2D.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation2D.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,337 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; + +import com.vividsolutions.jts.index.strtree.STRtree; + +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Interpolates along a given line string. This used to generate + * "horizontale Schnittprofile". + * + * @author Sascha L. Teichmann + */ +public final class Interpolation2D +{ + private static Logger log = Logger.getLogger(Interpolation2D.class); + + /** + * If the number of input points are over this threshold + * some culling strategies are applied to reduce the amount of points. + */ + public static final int CULL_POINT_THRESHOLD = Integer.getInteger( + "gnv.interpolation2d.cull.point.threshold", 1000); + + /** + * Numerical stability epsilon. + */ + public static final double EPS = 1e-6d; + + /** + * Callback to send the interpolated values back to the + * caller without building large temporary strcutures. + */ + public interface Consumer { + /** + * Sends an interpolated point back to the called. + * The interpolated parameter is stored in the z component. + * @param point The interpolated point. + * @param success true if interpolation at the point + * succeed, else false. + */ + void interpolated(Coordinate point, boolean success); + } // interface Consumer + + private Interpolation2D() { + } + + /** + * Calculates the relevant area for a given line string. + * @param path The line string. + * @param points The sample points. + * @return The relevant area. + */ + public static final Envelope relevantArea( + List path, + List points + ) { + return relevantArea(path, points, CULL_POINT_THRESHOLD); + } + + /** + * Calculates the relevant area for a given bounding box. + * @param pathBBox The bounding box. + * @param points The sample points. + * @return The relevant area. + */ + public static final Envelope relevantArea( + Envelope pathBBox, + List points + ) { + return relevantArea(pathBBox, points, CULL_POINT_THRESHOLD); + } + + /** + * Calculates the relevant area for a given bounding box. + * @param pathBBox The bounding box. + * @param points The sample points. + * @param threshold If the number of sample points + * are below this threshold no relevant area is calculated. + * @return The relevant area. + */ + public static final Envelope relevantArea( + Envelope pathBBox, + List points, + int threshold + ) { + return points.size() < threshold + ? null + : relevantArea( + pathBBox, + pointsBoundingBox(points)); + } + + /** + * Calculates the relevant area for a given line string. + * @param path The line string. + * @param points The sample points. + * @param threshold If the number of sample points + * are below this threshold no relevant area is calculated. + * @return The relevant area. + */ + public static final Envelope relevantArea( + List path, + List points, + int threshold + ) { + return points.size() < threshold || path.isEmpty() + ? null + : relevantArea( + pointsBoundingBox(path), + pointsBoundingBox(points)); + } + + /** + * Heuristic function to define a 'relevant area'. + * @param pathBBox The bounding box of the line line string. + * @param pointsBBox The bounding box of the sample points. + * @return The relevant area. + */ + public static final Envelope relevantArea( + Envelope pathBBox, + Envelope pointsBBox + ) { + double pathArea = pathBBox.getWidth()*pathBBox.getHeight(); + double pointsArea = pointsBBox.getWidth()*pointsBBox.getHeight(); + + if (pathArea > 0.8d*pointsArea) { return null; } + + double nArea = 1.44d * pathArea; + if (nArea < 0.1d*pointsArea) nArea = 0.1d*pointsArea; + double w = pathBBox.getWidth(); + double h = pathBBox.getHeight(); + double [] d = solveQuadratic(1d, w+h, pathArea - nArea); + + if (d == null) { return null; } + + double extra = pos(d); + + pathBBox.expandBy(extra); + + return pathBBox; + } + + /** + * Solves quadratic equation a*x*x + b*x + c = 0. + * @param a a-coefficent. + * @param b b-coefficent + * @param c c-coefficent. + * @return the solution of the equation, or null if not solvable. + */ + public static final double [] solveQuadratic( + double a, double b, double c + ) { + double d = b*b - 4d*a*c; + if (d < 0d) { return null; } + + d = Math.sqrt(d); + a = 1d/(2d*a); + b = -b; + + return new double [] { a*(b + d), a*(b - d) }; + } + + /** + * Return the element of a two element array which + * is greater or equal zero. + * @param x The two values. + * @return The value which is greater or equal zero. + */ + public static final double pos(double [] x) { + return x[0] >= 0 ? x[0] : x[1]; + } + + + /** + * Calculates the bounding box of a given line string. + * @param path The line string. + * @return The bounding box. + */ + public static Envelope pointsBoundingBox( + List path + ) { + int N = path.size(); + Envelope area = new Envelope(path.get(N-1)); + + for (int i = N-2; i >= 0; --i) { + area.expandToInclude(path.get(i)); + } + + return area; + } + + /** + * Interpolates linearly a number of coordinates and parameter values along + * a given line string path. The results are issued to a consumer. + * @param path The line string path. + * @param points The sample points. + * @param from Start point as a scalar value linear + * referenced on the line string. + * @param to End point of as a scalar value linear + * referenced on the line string. + * @param steps Number of points to be interpolated. + * @param metrics The used metric. + * @param consumer The callback to retrieve the result points. + */ + public static void interpolate( + List path, + List points, + double from, + double to, + int steps, + Metrics metrics, + Consumer consumer + ) { + boolean debug = log.isDebugEnabled(); + + int N = path.size(); + int M = points.size(); + + if (debug) { + log.debug("Size of path: " + N); + log.debug("Size of points: " + M); + } + + if (M < 1 || N < 2) { // nothing to do + return; + } + + List cells = GridCell.pointsToGridCells( + points, relevantArea(path, points)); + + if (cells.isEmpty()) { + log.warn("no cells found"); + return; + } + + // put into spatial index to speed up finding neighbors. + STRtree spatialIndex = new STRtree(); + + for (GridCell cell: cells) { + spatialIndex.insert(cell.getEnvelope(), cell); + } + + LinearToMap linearToMap = new LinearToMap( + path, from, to, metrics); + + double dP = (to - from)/steps; + + Coordinate center = new Coordinate(); + Envelope queryBuffer = new Envelope(); + GridCell.CellFinder finder = new GridCell.CellFinder(); + + int missedInterpolations = 0; + int interpolations = 0; + + for (double p = from; p <= to; p += dP) { + if (!linearToMap.locate(p, center)) { + continue; + } + queryBuffer.init( + center.x - EPS, center.x + EPS, + center.y - EPS, center.y + EPS); + + finder.prepare(center); + spatialIndex.query(queryBuffer, finder); + + GridCell found = finder.found; + + if (found == null) { + consumer.interpolated(center, false); + ++missedInterpolations; + continue; + } + + Point2d n0 = found.p1; + Point2d n1 = found.p2; + Point2d n2 = found.p3; + Point2d n3 = found.p4; + + double z1 = interpolate( + n0.x, n0.z, + n1.x, n1.z, + center.x); + double z2 = interpolate( + n2.x, n2.z, + n3.x, n3.z, + center.x); + double y1 = interpolate( + n0.x, n0.y, + n1.x, n1.y, + center.x); + double y2 = interpolate( + n2.x, n2.y, + n3.x, n3.y, + center.x); + center.z = interpolate( + y1, z1, + y2, z2, + center.y); + consumer.interpolated(center, true); + ++interpolations; + } + + if (debug) { + log.debug("interpolations: " + + interpolations + " / " + missedInterpolations); + } + } + + /** + * Linear interpolate a value between (x1, y1) and (x2, y2) at + * a given x-value. + * @param x1 x component of first point. + * @param y1 y component of first point. + * @param x2 x component of second point. + * @param y2 y component of second point. + * @param x The x value. + * @return The intepolated result. + */ + public static final double interpolate( + double x1, double y1, + double x2, double y2, + double x + ) { + if (x2 == x1) { + return (y1 + y2)*0.5d; + } + double m = (y2-y1)/(x2-x1); + double b = y1 - m*x1; + return m*x + b; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,343 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; + +import com.vividsolutions.jts.index.strtree.STRtree; + +import java.awt.Dimension; + +import java.io.Serializable; + +import java.util.Arrays; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Interpolates parameter values along a given line string from surface + * to the sea ground to generate "Profilschnitte". + * + * @author Sascha L. Teichmann + */ +public class Interpolation3D +implements Serializable +{ + private static Logger log = Logger.getLogger(Interpolation3D.class); + + /** + * The default width of the interpolation: {@value} + */ + public static final int DEFAULT_WIDTH = 1024; + + /** + * The default height of the interpolation: {@value} + */ + public static final int DEFAULT_HEIGHT = 768; + + /** + * Epsilon for numerical stability. + */ + public static final double EPS = 1e-6d; + + /** + * The width of the interpolation. + */ + protected int width; + + /** + * The height of the interpolation. + */ + protected int height; + + /** + * The cell width of the interpolation in world units. + */ + protected double cellWidth; + + /** + * The cell height of the interpolation in world units. + */ + protected double cellHeight; + + /** + * The coordinates of the interpolation. + */ + protected Coordinate[] coordinates; + + /** + * The generated raster. + */ + protected double [] raster; + + /** + * The sea ground depth along the line string. + */ + protected double [] depths; + + /** + * Default constructor. + */ + public Interpolation3D() { + this(DEFAULT_WIDTH, DEFAULT_HEIGHT); + } + + /** + * Constructor to create a Interpolation3D with a given size. + * @param size The size of the interpolation. + */ + public Interpolation3D(Dimension size) { + this(size.width, size.height); + } + + /** + * Constructor to create a Interpolation3D with a given size. + * @param width The width of the interpolation. + * @param height the height of the interpolation. + */ + public Interpolation3D(int width, int height) { + this.width = width; + this.height = height; + } + + /** + * Returns the raster height of the interpolation. + * @return The raster height of the interpolation. + */ + public int getHeight() { + return height; + } + + /** + * Returns the raster width of the interpolation. + * @return The raster width of the interpolation. + */ + public int getWidth() { + return width; + } + + /** + * Returns the cell width of the interpolation in world units. + * @return The cell width of the interpolation in world units. + */ + public double getCellWidth() { + return cellWidth; + } + + /** + * Returns the cell height of the interpolation in world units. + * @return The cell height of the interpolation in world units. + */ + public double getCellHeight() { + return cellHeight; + } + + /** + * Returns the coordinates used for the interpolation. + * @return the coordinates used for the interpolation. + */ + public Coordinate[] getCoordinates() { + return coordinates; + } + + /** + * Returns the generated raster. + * @return The generated raster. + */ + public double [] getRaster() { + return raster; + } + + /** + * Returns the depths along the line string path. + * @return The depth along the line string path. + */ + public double [] getDepths() { + return depths; + } + + /** + * Returns the deepest depth along the line string path. + * @return The deepest depth along the line string path. + */ + public double getMaxDepth() { + double maxDepth = Double.MAX_VALUE; + for (int i = depths!=null?depths.length-1:0; i >= 0; --i) { + double d = depths[i]; + if (!Double.isNaN(d) && d < maxDepth) { + maxDepth = d; + } + } + return maxDepth; + } + + /** + * Interpolates parameters along a given line string path from the surface + * to the sea ground. + * @param path The line string path. + * @param points The sample points. + * @param from Start point in scalar terms of the line string. + * @param to End point in scalar terms of the line string. + * @param metrics The used metric. + * @param xyDepth The callback to query the depth at a given point. + * @return true if the interpolation succeeds, else false. + */ + public boolean interpolate( + List path, + List points, + double from, + double to, + Metrics metrics, + XYDepth xyDepth + ) { + boolean debug = log.isDebugEnabled(); + + int N = path.size(); + int M = points.size(); + + if (debug) { + log.debug("Size of path: " + N); + log.debug("Size of points: " + M); + } + + if (M < 1 || N < 2) { // nothing to do + return false; + } + + List cells = GridCell.pointsToGridCells( + points, Interpolation2D.relevantArea(path, points)); + + if (cells.isEmpty()) { + log.warn("no cells found"); + return false; + } + + // put into spatial index to speed up finding neighbors. + STRtree spatialIndex = new STRtree(); + + for (GridCell cell: cells) { + spatialIndex.insert(cell.getEnvelope(), cell); + } + + LinearToMap linearToMap = new LinearToMap( + path, from, to, metrics); + + double [] depths = new double[width]; + Arrays.fill(depths, Double.NaN); + + Coordinate[] coordinates = new Coordinate[width]; + + double cellWidth = (to - from)/width; + + double maxDepth = Double.MAX_VALUE; + + int i = 0; + Coordinate center = new Coordinate(); + for (double p = cellWidth*0.5; i < depths.length; ++i, p += cellWidth) { + if (linearToMap.locate(p, center)) { + coordinates[i] = (Coordinate) center.clone(); + double depth = xyDepth.depth(center); + depths[i] = depth; + if (depth < maxDepth) { + maxDepth = depth; + } + } + } + + if (maxDepth == Double.MAX_VALUE) { + log.warn("no depth found -> no interpolation"); + return false; + } + + double cellHeight = Math.abs(maxDepth)/height; + + if (debug) { + log.debug("max depth found: " + maxDepth); + log.debug("cell size: " + cellWidth + " x " + cellHeight); + } + + double [] raster = new double[width*height]; + Arrays.fill(raster, Double.NaN); + + Envelope queryBuffer = new Envelope(); + GridCell.CellFinder finder = new GridCell.CellFinder(); + + i = 0; + for (double p = cellWidth*0.5; i < depths.length; ++i, p += cellWidth) { + double depth = depths[i]; + if (Double.isNaN(depth) || depth >= 0d) { + continue; + } + linearToMap.locate(p, center); + + queryBuffer.init( + center.x - EPS, center.x + EPS, + center.y - EPS, center.y + EPS); + + finder.prepare(center); + spatialIndex.query(queryBuffer, finder); + + GridCell found = finder.found; + + if (found == null) { + continue; + } + + XYColumn n0 = (XYColumn)found.p1; + XYColumn n1 = (XYColumn)found.p2; + XYColumn n2 = (XYColumn)found.p3; + XYColumn n3 = (XYColumn)found.p4; + + if (n0.prepare(xyDepth) + && n1.prepare(xyDepth) + && n2.prepare(xyDepth) + && n3.prepare(xyDepth) + ) { + double y1 = Interpolation2D.interpolate( + n0.x, n0.y, + n1.x, n1.y, + center.x); + double y2 = Interpolation2D.interpolate( + n2.x, n2.y, + n3.x, n3.y, + center.x); + double z = -cellHeight*0.5; + for (int j = i; + j < raster.length && z >= depth; + z -= cellHeight, j += width) { + + double v0 = n0.value(z); + double v1 = n1.value(z); + double v2 = n2.value(z); + double v3 = n3.value(z); + + double z1 = Interpolation2D.interpolate( + n0.x, v0, + n1.x, v1, + center.x); + double z2 = Interpolation2D.interpolate( + n2.x, v2, + n3.x, v3, + center.x); + double value = Interpolation2D.interpolate( + y1, z1, + y2, z2, + center.y); + raster[j] = value; + } + // XXX: Adjusted depth to create no gap + // between last value and ground. + depths[i] = z+0.5d*cellHeight; + } // down the x/y column + } // all along the track + + this.coordinates = coordinates; + this.depths = depths; + this.raster = raster; + this.cellWidth = cellWidth; + this.cellHeight = cellHeight; + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,21 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Implementations of this interface interpolate coordinates + * a line at a given point determined by a factor t (0 <= t <= 1).
+ * If t = 0 the start point of the line is used.
+ * If t = 1 the start point of the line is used. + * @author Sascha L. Teichmann + */ +public interface Interpolator +{ + /** + * Interpolates a point along a line with a given factor between 0 and 1. + * @param t The factor. + * @param v The result of the interpolation is stored in this coordinate. + */ + void interpolate(double t, Coordinate v); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/L1Comparator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/L1Comparator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,70 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +import java.util.Comparator; + +/** + * Compares two coordinates a and b by their L1(Manhattan) distance + * relative to a reference point r. + * da = L1(a, r)
+ * db = L1(b, r)
+ * -1 if da < db, +1 if da > db, 0 else. + * @author Sascha L. Teichmann + */ +public class L1Comparator +implements Comparator +{ + private Coordinate ref; + + /** + * Default constructor. + */ + public L1Comparator() { + } + + /** + * Constructor to create a L1Comparator with a given reference point. + * @param ref The reference point. + */ + public L1Comparator(Coordinate ref) { + this.ref = ref; + } + + /** + * Explicitly sets the reference point. + * @param ref The reference point. + */ + public void setReference(Coordinate ref) { + this.ref = ref; + } + + /** + * Compares to coordinate by their L1 distance to the reference point. + * @param a The first coordinate. + * @param b The second coordinate. + * @return -1 if L1(a, ref) < L1(b, ref), + * +1 if L1(a, ref) > L1(b, ref), 0 else. + */ + public int compare(Object a, Object b) { + Coordinate pa = (Coordinate)a; + Coordinate pb = (Coordinate)b; + double da = L1(ref, pa); + double db = L1(ref, pb); + if (da < db) return -1; + if (da > db) return +1; + return 0; + } + + /** + * Computes the L1 distance between two points a and b:
+ * L1(a, b) = abs(a.x - b.x) + abs(a.y - b.y) + * @param a The first point. + * @param b The second point. + * @return The L1 distance. + */ + public static double L1(Coordinate a, Coordinate b) { + return Math.abs(a.x - b.x) + Math.abs(a.y - b.y); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearFunction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearFunction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,87 @@ +package de.intevation.gnv.math; + +import org.apache.commons.math.FunctionEvaluationException; + +import org.apache.commons.math.analysis.UnivariateRealFunction; + +import org.apache.commons.math.optimization.fitting.ParametricRealFunction; + +/** + * Models a linear function to be usable in the fitting framework of + * the Apache Commons Mathematics Library. + * + * @author Sascha L. Teichmann + */ +public class LinearFunction +implements ParametricRealFunction +{ + /** + * Instance to prevent needless creations of instances. + */ + public static final LinearFunction INSTANCE = new LinearFunction(); + + /** + * Specialized class to be useful in function evaluating + * in the Apache Commons Mathematics Library. + */ + public static class Univariate + implements UnivariateRealFunction + { + /** + * The linear scaling factor. + */ + protected double m; + /** + * The linear offset. + */ + protected double b; + + /** + * Default constructor. + */ + public Univariate() { + } + + /** + * Constructor to create a Univariate with the linear parameters + * of the line between (x1, y1) and (x2, y2). + * @param x1 The x coordinate of the first point. + * @param y1 The y coordinate of the first point. + * @param x2 The x coordinate of the second point. + * @param y2 The y coordinate of the second point. + */ + public Univariate(double x1, double y1, double x2, double y2) { + if (y1 == y2) { + m = 0d; + b = (x1 + x2)*0.5d; + } + else { + m = (x1 - x2)/(y1 - y2); + b = y1 - m*x1; + } + } + + public double value(double x) { + return m*x + b; + } + } // class Univariate + + /** + * Default constructor. + */ + public LinearFunction() { + } + + public double value(double x, double [] parameters) + throws FunctionEvaluationException + { + return x*parameters[0] + parameters[1]; + } + + public double [] gradient(double x, double [] parameters) + throws FunctionEvaluationException + { + return new double [] { x, 1f }; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearMetrics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearMetrics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,73 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Implements {@link de.intevation.gnv.math.Metrics} + * for linear interpolations and distance measurements. + * @author Sascha L. Teichmann + */ +public final class LinearMetrics +implements Metrics +{ + /** + * Instance to prevent needless creations of instances. + */ + public static final Metrics INSTANCE = + new LinearMetrics(); + + /** + * Implements the corresponding linear interpolator. + */ + public static final class LinearInterpolator + implements Interpolator + { + private double mx; + private double bx; + private double my; + private double by; + + /** + * Constructor to create a linear interpolator between two + * given points. + * @param p1 The first point. + * @param p2 The second point. + */ + public LinearInterpolator(Coordinate p1, Coordinate p2) { + + /* + I) p1.x = 0*m + bx + II) p2.x = 1*m + bx + + bx = p1.x + + p2.x = m + p1.x + + mx = p2.x - p1.x + */ + + bx = p1.x; + mx = p2.x - bx; + + by = p1.y; + my = p2.y - by; + } + + public void interpolate(double t, Coordinate v) { + v.x = t*mx + bx; + v.y = t*my + by; + } + } // class LinearInterpolator + + private LinearMetrics() { + } + + public double distance(Coordinate p1, Coordinate p2) { + return p1.distance(p2); + } + + public Interpolator getInterpolator(Coordinate p1, Coordinate p2) { + return new LinearInterpolator(p1, p2); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/LinearToMap.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,274 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Given a list of line segments instances of this class are able + * to span a metric system between a start and an end point + * represented as scalar values to 2D coordinate on the + * course of the segments. + * + * @author Sascha L. Teichmann + */ +public class LinearToMap +{ + /** + * Represents a segment of the line string. + */ + public static final class Range { + private Range next; + + private double from; + private double to; + private double b; + + private Coordinate p1; + private Coordinate p2; + + private Interpolator interpolator; + + /** + * Default constructor. + */ + public Range() { + } + + /** + * Constructor to create a segment that maps + * a coordinate pair to two scalar values. + * Interpolations inside this segment are done with + * a given interpolator. + * @param from Start point of the segment. + * @param to End point of the segment. + * @param interpolator The interpolator. + * @param p1 The scalar value mapped to the start point. + * @param p2 The scalar value mappend to the end point. + */ + public Range( + double from, + double to, + Interpolator interpolator, + Coordinate p1, + Coordinate p2 + ) { + this.from = from; + this.to = to; + this.interpolator = interpolator; + this.p1 = p1; + this.p2 = p2; + + b = from == to + ? 0d + : 1.0d/(to - from); + } + + /** + * Interpolated a coordinate on the segment given a scalar value + * between the start and end point of the range. + * @param x The scalar value. + * @param v The interpolated value is stored here. + */ + public void eval(double x, Coordinate v) { + interpolator.interpolate((x - from)*b, v); + } + + /** + * Checks if a given value is inside this segment. + * @param x The value to test + * @return true if inside, else false. + */ + public boolean inside(double x) { + return x >= from && x <= to; + } + + /** + * Returns the start point of this segment. + * @return The start point. + */ + public Coordinate startPoint() { + return p1; + } + + /** + * Return the end point of this segment. + * @return The end point. + */ + public Coordinate endPoint() { + return p2; + } + } // class Range + + /** + * The head of the internal range list. + */ + protected Range head; + + /** + * The last accessed segment. Used to accelerate + * the access of the right segment. + */ + protected Range last; + + /** + * Default constructor. + */ + public LinearToMap() { + } + + /** + * Constructor to create a LinearToMap that maps + * given scalar values to coordinates of a given + * list of line segments. + * @param path The list of line segments. + * @param from The start value mapped to the start point + * of the first line segment. + * @param to The end value mapped to the end point of + * the last line segment. + * @param metrics The metric used to span the 2D space. + */ + public LinearToMap( + List path, + double from, + double to, + Metrics metrics + ) { + double diagramLength = Math.abs(to - from); + + double worldLength = length(path, metrics); + + double rangeStart = from; + + Range last = null; + + for (int i = 1, N = path.size(); i < N; ++i) { + Coordinate p1 = path.get(i-1); + Coordinate p2 = path.get(i); + double segmentLength = metrics.distance(p1, p2); + + double relativeLength = segmentLength / worldLength; + + double rangeLength = diagramLength * relativeLength; + + double rangeEnd = rangeStart + rangeLength; + + Range range = new Range( + rangeStart, rangeEnd, + metrics.getInterpolator(p1, p2), + p1, p2); + + if (last == null) { + last = head = range; + } + else { + last.next = range; + last = range; + } + rangeStart = rangeEnd; + } + } + + /** + * Returns a segment on which a given value is found. + * @param diagramX The value. + * @return The segment or null if no matching segment was found. + */ + protected Range locateRange(double diagramX) { + + if (last != null && last.inside(diagramX)) { + return last; + } + + Range current = head; + while (current != null) { + if (current.inside(diagramX)) { + return last = current; + } + current = current.next; + } + + return null; + } + + /** + * Interpolates a coordinate at a given scalar position. + * @param diagramX The scalar position. + * @param v The interpolated coordinate is stored here. + * @return true if the scalar position is inside the + * spanned range of the line string, else false. + */ + public boolean locate(double diagramX, Coordinate v) { + Range range = locateRange(diagramX); + if (range == null) { + return false; + } + range.eval(diagramX, v); + return true; + } + + /** + * Returns the length of a given line string using + * a given metric. + * @param path The line string. + * @param metrics The used metric. + * @return The length of the line string. + */ + public static double length( + List path, + Metrics metrics + ) { + double sum = 0d; + for (int i = path.size()-1; i >= 1; --i) { + Coordinate p1 = path.get(i); + Coordinate p2 = path.get(i-1); + sum += metrics.distance(p1, p2); + } + return sum; + } + + /** + * Return the number of segments in this map. + * @return the number of segments. + */ + public int numRanges() { + int count = 0; + Range current = head; + while (current != null) { + ++count; + current = current.next; + } + return count; + } + + /** + * Returns an iterator over all segments of this map. + * @return The iterator. + */ + public Iterator ranges() { + return new Iterator() { + + Range current = head; + + public boolean hasNext() { + return current != null; + } + + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + Range x = current; + current = current.next; + return x; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/Metrics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Metrics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Implementations provides the ability to calculate the distance between + * two points ans support for interpolating points between two points. + * + * @author Sascha L. Teichmann + */ +public interface Metrics +{ + /** + * Calculates the distance between two given points. + * @param p1 The first point. + * @param p2 The second point. + * @return The distance. + */ + double distance(Coordinate p1, Coordinate p2); + + /** + * Return an interpolator which allows interpolations between + * two given points. + * @param p1 The first point. + * @param p2 The second point. + * @return The interpolator. + */ + Interpolator getInterpolator(Coordinate p1, Coordinate p2); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/Point2d.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Point2d.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,286 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; + +import java.util.Comparator; + +import org.apache.log4j.Logger; + +/** + * Point which besides the x, y, z coodinates has an index i, j pair + * to model neighborhood. + * @author Sascha L. Teichmann + */ +public class Point2d +extends Coordinate +{ + private static Logger log = Logger.getLogger(Point2d.class); + + /** + * Numerical tolerance epsilon: {@value} + */ + public static final double EPSILON = 1e-3d; + + /** + * Compares two Point2ds by their x coordinates + */ + public static final Comparator X_COMPARATOR = new Comparator() { + public int compare(Object a, Object b) { + double xa = ((Coordinate)a).x; + double xb = ((Coordinate)b).x; + if (xa < xb) return -1; + if (xa > xb) return +1; + return 0; + } + }; + + /** + * Compares two Point2ds by their y coordinates. + */ + public static final Comparator Y_COMPARATOR = new Comparator() { + public int compare(Object a, Object b) { + double ya = ((Coordinate)a).y; + double yb = ((Coordinate)b).y; + if (ya < yb) return -1; + if (ya > yb) return +1; + return 0; + } + }; + + /** + * The i index of this Point2d. + */ + public int i; + /** + * The j index of this Point2d. + */ + public int j; + + /** + * Default constructor. + */ + public Point2d() { + } + + /** + * Constructor setting x and y coordinate. + * @param x The x coordinate. + * @param y The y coordinate. + */ + public Point2d(double x, double y) { + super(x, y); + } + + /** + * Constructor setting x, y and i, j. + * @param x The x coordinate. + * @param y The y coordinate. + * @param i The i index. + * @param j The j index. + */ + public Point2d(double x, double y, int i, int j) { + super(x, y); + this.i = i; + this.j = j; + } + + /** + * Constructor setting x, y, z and i, j. + * @param x The x coordinate. + * @param y The y coordinate. + * @param z The z coordinate. + * @param i The i index. + * @param j The j index. + */ + public Point2d(double x, double y, double z, int i, int j) { + super(x, y, z); + this.i = i; + this.j = j; + } + + /** + * Calculates the L1 distance to another Point2d. + * @param other The other Point2d. + * @return The L1 distance. + */ + public double L1(Point2d other) { + return L1Comparator.L1(this, other); + } + + /** + * Creates an envelope around this Point2d with + * the numerical tolerance of {@link #EPSILON}. + * @return The envelope. + */ + public Envelope envelope() { + return envelope(EPSILON); + } + + /** + *Creates an envelope around this Point2d with + * a given tolerance. + * @param epsilon The tolerance in all directions. + * @return The envelope. + */ + public Envelope envelope(double epsilon) { + return new Envelope( + x-epsilon, x+epsilon, + y-epsilon, y+epsilon); + } + + /** + * Given this and another Point2d it looks if there is + * a gap between the in points in i index direction. + * @param other The other Point2d. + * @return true if there is is a gap, else false. + */ + public boolean hasIGap(Point2d other) { + return Math.abs(i - other.i) > 1; + } + + /** + * Given this and another Point2d it looks if there is + * a gap between the in points in j index direction. + * @param other The other Point2d. + * @return true if there is is a gap, else false. + */ + public boolean hasJGap(Point2d other) { + return Math.abs(j - other.j) > 1; + } + + /** + * Given this and another Point2d a new Point2d is + * created via {@link #newPoint() }. The x, y coordinate + * of the new point is on the line of this and the other + * given point at a given scaling point. + * @param t The scaling factor. + * @param other The other point. + * @return The new Point2d. + */ + public Point2d extrapolate(double t, Point2d other) { + if (other == null) { + return null; + } + Point2d p = newPoint(); + p.x = t*(other.x - x) + x; + p.y = t*(other.y - y) + y; + return p; + } + + /** + * Creates a new Point2d or an instance of a subclass. + * Override this in subclasses. + * @return The new Point2d. + */ + public Point2d newPoint() { + return new Point2d(0d, 0d); + } + + /** + * Creates a new Point2d or an instance of a subclass + * at a given coordinate. + * Override this in subclasses. + * @param x The x coordinate. + * @param y The y coordinate. + * @return The new point. + */ + public Point2d newPoint(double x, double y) { + return new Point2d(x, y); + } + + /** + * Sets the z value to the inverse distance weighting (IDW) value + * of the z values of a set of given points. + * @param ps The points from wich the z values are taken + * to calculate the IDW. + */ + public void inverseDistanceWeighting(Point2d [] ps) { + + double sum = 0d; + + double [] d = new double[ps.length]; + + for (int i = 0; i < ps.length; ++i) { + Point2d p = ps[i]; + if (p != null) { + double di = distance(p); + if (di < 1e-5d) { z = p.z; return; } + di = 1d/di; + d[i] = di; + sum += di; + } + } + + if (sum == 0d) { + return; + } + + double v = 0d; + + for (int i = 0; i < ps.length; ++i) { + Point2d p = ps[i]; + if (p != null) { + v += p.z*d[i]; + } + } + z = v/sum; + } + + /** + * Creates a new point via {@link #newPoint() } with the + * x,y coordinates of the center of a given set of + * coordinates. + * @param ps The points from which the x,y coordinates are + * taken to calculate the center. + * @return The new center point. + */ + public static Point2d average(Point2d [] ps) { + + Point2d p = null; + int count = 0; + + for (int i = 0; i < ps.length; ++i) { + Point2d t = ps[i]; + if (t != null) { + ++count; + if (p == null) { + p = t.newPoint(t.x, t.y); + } + else { + p.x += t.x; + p.y += t.y; + } + } + } + + if (p != null) { + double s = 1d/count; + p.x *= s; + p.y *= s; + } + + return p; + } + + /** + * Checks if this Point2d is near to at least one point + * out of a given set of points. Near is defined by an + * euclidian distance small than {@link #EPSILON}. + * @param ps The set of points to be tested. + * @return true if this Point2d is near to one of the given + * points, else false. + */ + public boolean near(Point2d [] ps) { + + for (int i = 0; i < ps.length; ++i) { + Point2d p = ps[i]; + if (p != null && distance(p) > EPSILON) { + return false; + } + } + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import de.intevation.gnv.geobackend.sde.datasources.RasterObject; + +import de.intevation.gnv.utils.WKTUtils; + +import java.lang.ref.SoftReference; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; + +/** + * This implementation uses the geo backend to query a depth via + * a raster layer stored in the database. + * + * @author Tim Englich + * @author Sascha L. Teichmann + */ +public class QueriedXYDepth +implements XYDepth +{ + private static Logger log = Logger.getLogger(QueriedXYDepth.class); + + private static final String queryID = "rasterQuery"; + + private QueryExecutor queryExecutor; + + private ArrayList> rasterData; + + private RasterObject last; + + private int interpolation; + + /** + * Default construtor. Interpolation method is bilinear. + */ + public QueriedXYDepth() { + this(RasterObject.BILINEAR); + } + + /** + * Constructor to create a QueriedXYDepth with a given interpolation + * method. + * @param interpolation The interpolation method. + */ + public QueriedXYDepth(int interpolation) { + this.interpolation = interpolation; + rasterData = new ArrayList>(); + queryExecutor = QueryExecutorFactory.getInstance().getQueryExecutor(); + } + + public double depth(Coordinate coordinate) { + double resultValue = Double.NaN; + + RasterObject ro = getRasterObject(coordinate); + + if (ro == null) { + try { + String[] filterValues = + new String[] { WKTUtils.toWKT(coordinate) }; + Collection result = queryExecutor.executeQuery( + queryID, filterValues); + for (Result row: result) { + if ((ro = (RasterObject)row.getObject(0)) != null) { + rasterData.add( + new SoftReference(last = ro)); + } + break; + } + } catch (QueryException e) { + log.error(e, e); + } + } + return ro != null + ? ro.getValue(coordinate, interpolation) + : Double.NaN; + } + + private RasterObject getRasterObject(Coordinate coordinate) { + if (last != null && last.contains(coordinate)) { + return last; + } + for (int i = rasterData.size()-1; i >= 0; --i) { + SoftReference ref = rasterData.get(i); + RasterObject ro = ref.get(); + if (ro != null && ro.contains(coordinate)) { + return last = ro; + } + } + return null; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/XYColumn.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/XYColumn.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,169 @@ +package de.intevation.gnv.math; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.math.FunctionEvaluationException; +import org.apache.commons.math.MathException; + +import org.apache.commons.math.analysis.UnivariateRealFunction; + +import org.apache.commons.math.analysis.interpolation.SplineInterpolator; +import org.apache.commons.math.analysis.interpolation.UnivariateRealInterpolator; + +import org.apache.log4j.Logger; + +/** + * A column of discrete attributed height values located at a point. + * Values between the discrete height values are interpolated. + * + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class XYColumn +extends Point2d +implements UnivariateRealFunction +{ + private static Logger log = Logger.getLogger(XYColumn.class); + + /** + * The list of discrete height values. + */ + protected List values; + + /** + * The curve used to interpolate the points between the + * discrete height values. + */ + protected transient UnivariateRealFunction curve; + + /** + * Default constructor. + */ + public XYColumn() { + values = new ArrayList(); + } + + /** + * Constructor to create an XYColumn with a given (x, y) coordinate + * and an (i, j) index tuple. + * @param x The x coordinate. + * @param y The y coordinate. + * @param i The i component. + * @param j The j component. + */ + public XYColumn(double x, double y, int i, int j) { + super(x, y, i, j); + values = new ArrayList(); + } + + /** + * Adds a given height value to the list of height values. + * @param value The height value. + */ + public void add(HeightValue value) { + values.add(value); + } + + /** + * Returns the list of height values. + * @return The list of height values. + */ + public List getValues() { + return values; + } + + public double value(double depth) { + try { + if (curve != null) { + HeightValue h = values.get(0); + // extrapolate beyond boundaries by repeating + if (depth > h.z) return h.v; + h = values.get(values.size()-1); + if (depth < h.z) return h.v; + return curve.value(depth); + } + } + catch (FunctionEvaluationException fee) { + log.error("evaluation failed", fee); + } + + return Double.NaN; + } + + /** + * Prepares this XYColumn to be queried. A given XYDepth + * object is used to fill the values to a certain depth. + * @param xyDepth To figure out the depth a the cordinate. + * @return true if preparation succeeds else false. + */ + public boolean prepare(XYDepth xyDepth) { + if (curve == null) { + int N = values.size(); + if (N == 0) { + log.error("no points for interpolation"); + return false; + } + + if (N == 1) { + // only one value -> constant function + curve = new ConstantFunction(values.get(0).v); + } + else { // more than on value + double depth = xyDepth.depth(this); + Collections.sort(values, HeightValue.INV_Z_COMPARATOR); + + // if there is no value at 0 repeat first value + HeightValue first = values.get(0); + if (first.z < 0d) { + values.add(0, new HeightValue(0d, first.v, first.k-1)); + ++N; + } + + // if there is no value at depth repeat last value + HeightValue last = values.get(N-1); + if (last.z > depth) { + values.add(new HeightValue(depth, last.v, last.k+1)); + ++N; + } + if (N < 3) { // interpolate linear + first = values.get(0); + last = values.get(N-1); + curve = new LinearFunction.Univariate( + first.z, first.v, + last.z, last.v); + } + else { // higher degree interpolation + double [] z = new double[N]; + double [] v = new double[N]; + for (int i = 0; i < N; ++i) { + HeightValue h = values.get(N-1-i); + z[i] = h.z; + v[i] = h.v; + } + try { + curve = getInterpolator().interpolate(z, v); + } + catch (MathException me) { + log.error("interpolation failed", me); + return false; + } + } + } + } + return true; + } + + /** + * Returns the interpolator used to interpolate the values between + * the discrete height values. This class returns an instance of + * {@link org.apache.commons.math.analysis.interpolation.SplineInterpolator}. + * Override this if you want to use another kind of interpolation. + * @return The interpolator to be used. + */ + protected UnivariateRealInterpolator getInterpolator() { + return new SplineInterpolator(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/XYDepth.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/XYDepth.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.gnv.math; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Interface to encapsulate the query of the depth at a given point. + * @author Sascha L. Teichmann + */ +public interface XYDepth +{ + /** + * Returns the depth at a given coordinate. Negative + * values are below the water surface. + * @param coordinate The coordinate where to take the depth. + * @return The depth at the queried coordinate. NaN is no + * depth is available at the given point. + */ + double depth(Coordinate coordinate); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/math/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Classes and interface to do the different kinds of cross sections. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.profile.horizontal; + +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class HorizontalProfileArtifact extends GNVArtifactBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(HorizontalProfileArtifact.class); + /** + * + */ + private static final long serialVersionUID = -721831166719594662L; + + /** + * Constructor + */ + public HorizontalProfileArtifact() { + super(); + log.debug("HorizontalProfileArtifact.Constructor"); + this.name = "horizontalProfile"; + } + + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactBase#setup(java.lang.String, + * de.intevation.artifacts.ArtifactFactory, java.lang.Object, + * org.w3c.dom.Document) + */ + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("HorizontalProfileArtifact.setup"); + super.setup(identifier, factory, context, data); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileInstantaneousPointArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileInstantaneousPointArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.gnv.profile.horizontal; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class HorizontalProfileInstantaneousPointArtifact extends + HorizontalProfileArtifact { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(HorizontalProfileInstantaneousPointArtifact.class); + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -6700816287500004553L; + + /** + * Constructor + */ + public HorizontalProfileInstantaneousPointArtifact() { + super(); + log.debug("HorizontalProfileInstantaneousPointArtifact.Constructor"); + super.name = super.name + "InstantaneousPoint"; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,29 @@ +package de.intevation.gnv.profile.horizontal; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class HorizontalProfileMeshArtifact extends HorizontalProfileArtifact { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(HorizontalProfileMeshArtifact.class); + + /** + * The UID of this class + */ + private static final long serialVersionUID = -8291547966693867205L; + + /** + * Constructor + */ + public HorizontalProfileMeshArtifact() { + super(); + log.debug("VerticalProfileMeshArtifact.Constructor"); + super.name = super.name + "Mesh"; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshCrossArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/HorizontalProfileMeshCrossArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ +package de.intevation.gnv.profile.horizontal; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class HorizontalProfileMeshCrossArtifact extends + HorizontalProfileMeshArtifact { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 3955589051619129854L; + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(HorizontalProfileMeshCrossArtifact.class); + + /** + * Constructor + */ + public HorizontalProfileMeshCrossArtifact() { + super(); + log.debug("HorizontalProfileMeshCrossArtifact.Constructor"); + super.name = super.name + "Cross"; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontal/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes providing specific artifacts representing +'Horizontalprofile'. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontalcrosssection/HorizontalCrossSectionMeshArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,64 @@ +package de.intevation.gnv.profile.horizontalcrosssection; + +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class HorizontalCrossSectionMeshArtifact extends GNVArtifactBase { + /** + * + */ + private static final long serialVersionUID = -2687278172203755640L; + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(HorizontalCrossSectionMeshArtifact.class); + + + /** + * Constructor + */ + public HorizontalCrossSectionMeshArtifact() { + super(); + log.debug("HorizontalCrossSectionMeshArtifact.Constructor"); + this.name = "horizontalCrossSectionMesh"; + } + + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactBase#setup(java.lang.String, + * de.intevation.artifacts.ArtifactFactory, java.lang.Object, + * org.w3c.dom.Document) + */ + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("HorizontalCrossSectionMeshArtifact.setup"); + super.setup(identifier, factory, context, data); + } + + + /** + * This method is called just before an artifact is exported. It removes all + * data which should not serialized into an export. + * + * @param context CallContext object. + */ + @Override + public void cleanup(Object context) { + if (current != null) + current.cleanup(context); + + super.cleanup(context); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontalcrosssection/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/horizontalcrosssection/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes providing specific artifacts representing +'Horizontalschnitte'. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.profile.vertical; + +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class VerticalProfileArtifact extends GNVArtifactBase { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(VerticalProfileArtifact.class); + + /** + * The UID of this class + */ + private static final long serialVersionUID = -8291547966693867205L; + + /** + * Constructor + */ + public VerticalProfileArtifact() { + super(); + log.debug("VerticalProfileArtifact.Constructor"); + this.name = "verticalProfile"; + } + + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactBase#setup(java.lang.String, + * de.intevation.artifacts.ArtifactFactory, java.lang.Object, + * org.w3c.dom.Document) + */ + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("VerticalProfileArtifact.setup"); + super.setup(identifier, factory, context, data); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileInstantaneousPointArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileInstantaneousPointArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ +package de.intevation.gnv.profile.vertical; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class VerticalProfileInstantaneousPointArtifact extends + VerticalProfileArtifact { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(VerticalProfileInstantaneousPointArtifact.class); + + /** + * The UID of this class + */ + private static final long serialVersionUID = -8291547966693867205L; + + /** + * Constructor + */ + public VerticalProfileInstantaneousPointArtifact() { + super(); + log.debug("VerticalProfileInstantaneousPointArtifact.Constructor"); + super.name = super.name + "InstantaneousPoint"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileMeshArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/VerticalProfileMeshArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.gnv.profile.vertical; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class VerticalProfileMeshArtifact extends VerticalProfileArtifact { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(VerticalProfileMeshArtifact.class); + + /** + * The UID of this class + */ + private static final long serialVersionUID = -8291547966693867205L; + + /** + * Constructor + */ + public VerticalProfileMeshArtifact() { + super(); + log.debug("VerticalProfileMeshArtifact.Constructor"); + super.name = super.name + "Mesh"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/vertical/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes that provide specific artifacts representing +'Vertikalprofile'. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/verticalcrosssection/VerticalCrossSectionMeshArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.profile.verticalcrosssection; + +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class VerticalCrossSectionMeshArtifact extends GNVArtifactBase { + /** + * + */ + private static final long serialVersionUID = -2687278172203755640L; + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(VerticalCrossSectionMeshArtifact.class); + + + /** + * Constructor + */ + public VerticalCrossSectionMeshArtifact() { + super(); + log.debug("VerticalCrossSectionMeshArtifact.Constructor"); + this.name = "verticalCrossSectionMesh"; + } + + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactBase#setup(java.lang.String, + * de.intevation.artifacts.ArtifactFactory, java.lang.Object, + * org.w3c.dom.Document) + */ + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("VerticalCrossSectionMeshArtifact.setup"); + super.setup(identifier, factory, context, data); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/profile/verticalcrosssection/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/profile/verticalcrosssection/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes that provide specific artifacts representing +'Profilschnitte'. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/AbstractProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/AbstractProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,60 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.raster.Vectorizer.RingsHandler; + +/** + * Abstract base class for producing multi polygons and + * multi line strings. This base class stores a bounding box + * of world coordinates which helps to transform the index + * spaced egde data into real world coordinates. + * + * @author Sascha L. Teichmann + */ +public abstract class AbstractProducer +implements RingsHandler +{ + /** + * min x coord of the world. + */ + protected double minX; + + /** + * min y coord of the world. + */ + protected double minY; + + /** + * max x coord of the world. + */ + protected double maxX; + + /** + * max y coord of the world. + */ + protected double maxY; + + /** + * Default constructor. + */ + public AbstractProducer() { + } + + /** + * Constructor to create an Abstract producer with a + * given world bounding box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public AbstractProducer( + double minX, double minY, + double maxX, double maxY + ) { + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/DemuxRingsHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/DemuxRingsHandler.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,57 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.raster.Vectorizer.Edge; +import de.intevation.gnv.raster.Vectorizer.RingsHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * Ring Handler that demultiplexes to a list of other ring handlers. + * Handy if you want to pipe the polygons and line strings produced + * by the Vectorize to more than one handler at once. + * + * @author Sascha L. Teichmann + */ +public class DemuxRingsHandler +implements RingsHandler +{ + /** + * The list of internal ring handlers. + */ + protected ArrayList handlers; + + /** + * Default constructor. + */ + public DemuxRingsHandler() { + handlers = new ArrayList(); + } + + /** + * Add a ring handler to the list of handlers. + * @param handler The handler to add to the internal list. + */ + public void addHandler(RingsHandler handler) { + handlers.add(handler); + } + + public void handleRings( + List rings, + int value, + int width, + int height + ) { + for (RingsHandler handler: handlers) { + handler.handleRings(rings, value, width, height); + } + } + + /** + * Empties the internal list of ring handlers. + */ + public void clear() { + handlers.clear(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/ExternalIndexConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/ExternalIndexConverter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.gnv.raster; + +import org.apache.log4j.Logger; + +/** + * Converts the interal color index of a polygon to the external index + * defined by the corresponding palette entry. + * + * @author Sascha L. Teichmann + */ +public class ExternalIndexConverter +implements JTSMultiPolygonProducer.ValueConverter +{ + private static Logger log = Logger.getLogger( + ExternalIndexConverter.class); + + /** + * The palette where to find the color indices. + */ + protected Palette palette; + + /** + * Default constructor. + */ + public ExternalIndexConverter() { + } + + /** + * Constrcutor to create an ExternalIndexConverter with + * a given palette. + * @param palette The palette where to find the color indices. + */ + public ExternalIndexConverter(Palette palette) { + this.palette = palette; + } + + /** + * Maps the color index of a polygon to the external index + * defined by the corresponing palette entry. + * @param value The value to convert + * @return The mapped value or the original value if + * no corresponing palette entry was found. + */ + public Integer convert(Integer value) { + if (value == null) { + return value; + } + + int v = value.intValue(); + + if (v == -1) { + return value; + } + + Palette.Entry entry = palette.getEntryByIndex(v); + + if (entry == null) { + log.warn("cannot find palette entry for index: " + v); + return value; + } + + return Integer.valueOf(entry.getExternalIndex()); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/Filter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Filter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.gnv.raster; + +import org.w3c.dom.Element; + +/** + * Interface to model transformations of rasters. + * @author Sascha L. Teichmann + */ +public interface Filter +{ + /** + * Allows the creation of filters parameterized from XML elements. + */ + public interface Factory { + + /** + * Setup the factory with a given XML element. + * @param element + */ + void init(Element element); + + /** + * Created a new Filter with this factory. + * @return The new created Filter. + */ + Filter create(); + + } // interface Factory + + /** + * Apply this filter to a given raster. The original raster is + * unmodified and a new raster is created. + * @param raster The original raster. + * @return The new raster. + */ + Raster filter(Raster raster); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.raster; + +/** + * Generates label attributes for iso lines. It takes the + * neighboring palette ranges and calculates the mid point + * between these two ranges. + * @author Sascha L. Teichmann + */ +public class IsoAttributeGenerator +implements IsoProducer.AttributeGenerator +{ + /** + * The palette where to look for the ranges. + */ + protected Palette palette; + + /** + * Default constructor. + */ + public IsoAttributeGenerator() { + } + + /** + * Constructor to create an IsoAttributeGenerator with + * a given lookup palette. + * @param palette The palette. + */ + public IsoAttributeGenerator(Palette palette) { + this.palette = palette; + } + + public Object generateAttribute(int neighbor1, int neighbor2) { + Palette.Entry e1 = palette.getEntryByIndex(neighbor1); + Palette.Entry e2 = palette.getEntryByIndex(neighbor2); + + if (e1 == null || e2 == null) { + return null; + } + + double e1t = e1.getFrom(); + double e2f = e2.getTo(); + + return Double.valueOf(e2f >= e1t + ? 0.5d*(e1t+e2f) + : 0.5d*(e2.getTo()+e1.getFrom())); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,144 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.jfreechart.CompactXYItems; +import de.intevation.gnv.jfreechart.PolygonSeries; + +import de.intevation.gnv.math.IJKey; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import gnu.trove.TDoubleArrayList; +import gnu.trove.TIntObjectHashMap; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; + +/** + * Vectorizer backend to generate iso lines which are able to be visualized + * via {@link de.intevation.gnv.jfreechart.PolygonPlot} as line strings + * and custom labels on the chart. + * + * @author Sascha L. Teichmann + */ +public class IsoPolygonSeriesProducer +extends IsoProducer +{ + private static Logger log = Logger.getLogger( + IsoPolygonSeriesProducer.class); + + /** + * The line width of the line string used in the chart. + */ + public static final Float LINE_WIDTH = Float.valueOf(0.1f); + + /** + * Constructor to create an IsoPolygonSeriesProducer with a + * given world bounding box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public IsoPolygonSeriesProducer( + double minX, double minY, + double maxX, double maxY + ) { + super(minX, minY, maxX, maxY); + } + + /** + * Returns a collection of series with line strings + * with no AttributeGenerator. + * @return The collection with line strings. + */ + public Collection getSeries() { + return getSeries(null); + } + + /** + * Returns a collection of series with line strings. + * The label attributes are generated with a given generator. + * @param attributeGenerator The attribute generator. Maybe null + * if no attributes should be generated. + * @return The collection with the line strings. + */ + public Collection getSeries( + AttributeGenerator attributeGenerator + ) { + ArrayList series = new ArrayList(); + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + TDoubleArrayList vertices = new TDoubleArrayList(); + + for (IJKey key: joinPairs()) { + PolygonSeries ps = new PolygonSeries(); + + // process complete + ArrayList completeList = complete.get(key); + if (completeList != null) { + for (Edge head: completeList) { + Edge current = head; + do { + vertices.add(m1*(current.a % width) + b1); + vertices.add(m2*(current.a / width) + b2); + } + while ((current = current.next) != head); + // add head again to close shape + vertices.add(m1*(head.a % width) + b1); + vertices.add(m2*(head.a / width) + b2); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + vertices.reset(); + } + } + + // process open + TIntObjectHashMap map = commonOpen.get(key); + + if (map != null) { + for (Edge head: headList(map)) { + + head = Vectorizer.simplify(head, width); + Edge current = head, last = head; + do { + vertices.add(m1*(current.a % width) + b1); + vertices.add(m2*(current.a / width) + b2); + last = current; + } + while ((current = current.next) != null); + // add b from tail + vertices.add(m1*(last.b % width) + b1); + vertices.add(m2*(last.b / width) + b2); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + vertices.reset(); + } // for all in common open + } // if map defined for key + + if (ps.getItemCount() > 0) { + series.add(ps); + if (attributeGenerator != null) { + Object attribute = attributeGenerator + .generateAttribute(key.i, key.j); + + if (attribute != null) { + ps.setAttribute("label", attribute); + } + } + ps.setAttribute("line.width", LINE_WIDTH); + } + } // for all pairs + + return series; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,190 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.math.IJKey; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import gnu.trove.TIntHashSet; +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TObjectProcedure; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +/** + * Vectorizer backend to generate iso lines as line strings + * and custom labels on the chart. + * + * @author Sascha L. Teichmann + */ +public class IsoProducer +extends AbstractProducer +{ + /** + * Iso lines separate two neighbors. This interface decouples + * the generation of a suitable label for these to neighbors. + */ + public interface AttributeGenerator { + + /** + * Generate attribute show as label for two given neighbors. + * @param neighbor1 The first neighbor. + * @param neighbor2 The second neighbor. + * @return The label attribute. + */ + Object generateAttribute(int neighbor1, int neighbor2); + + } // interface AttributeGenerator + + /** + * Internal map of open edge to neighbor attributes. + */ + protected HashMap open; + /** + * Internal map to associate neighbors with open edges. + */ + protected HashMap commonOpen; + /** + * Internal map to associate neighbors with complete rings. + */ + protected HashMap> complete; + + /** + * Width of the index space. + */ + protected int width; + /** + * Height of the index space. + */ + protected int height; + + /** + * Constructor with a given world bounding box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public IsoProducer( + double minX, double minY, + double maxX, double maxY + ) { + super(minX, minY, maxX, maxY); + + open = new HashMap(); + commonOpen = new HashMap(); + complete = new HashMap>(); + } + + public void handleRings( + List rings, + int value, + int width, + int height + ) { + if (value == -1) { + return; + } + this.width = width; + this.height = height; + + Integer v = Integer.valueOf(value); + + for (Edge head: rings) { + Edge current = head; + do { + Integer neighbor = open.remove(current); + + if (neighbor != null) { + IJKey pair = new IJKey(value, neighbor.intValue()); + pair.sort(); + + TIntObjectHashMap co = commonOpen.get(pair); + + if (co == null) { + commonOpen.put(pair, co = new TIntObjectHashMap()); + } + + Edge edge = new Edge(current); + + Edge otherA = (Edge)co.remove(edge.a); + if (otherA != null) { + otherA.chain(edge, edge.a); + } + + Edge otherB = (Edge)co.remove(edge.b); + if (otherB != null) { + otherB.chain(edge, edge.b); + } + + if (edge.isComplete()) { + ArrayList list = complete.get(pair); + if (list == null) { + complete.put(pair, list = new ArrayList()); + } + list.add(Vectorizer.simplify(edge, width)); + } + else { + if (otherA == null) { + co.put(edge.a, edge); + } + if (otherB == null) { + co.put(edge.b, edge); + } + } + } + else { + Edge edge = new Edge(current.b, current.a); + open.put(edge, v); + } + + current = current.next; + } + while (current != head); + } // for all rings + + } // handleRings + + /** + * Join the pairs of neighbors i,j to have a distinct set. + * @return The distinct pairs of neighbors. + */ + protected HashSet joinPairs() { + HashSet pairs = new HashSet(); + pairs.addAll(complete .keySet()); + pairs.addAll(commonOpen.keySet()); + return pairs; + } + + /** + * Filter out the head list from the open edge lists. + * @param map Map of end and head lists. + * @return list of only head lists. + */ + protected static ArrayList headList(TIntObjectHashMap map) { + final ArrayList headList = new ArrayList(); + map.forEachValue(new TObjectProcedure() { + TIntHashSet headSet = new TIntHashSet(); + public boolean execute(Object value) { + Edge head = ((Edge)value).head(); + if (headSet.add(head.a)) { + headList.add(head); + } + return true; + } + }); + return headList; + } + + /** + * Reset internal data structures to save some memory. + */ + public void clear() { + open.clear(); + complete.clear(); + commonOpen.clear(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,239 @@ +package de.intevation.gnv.raster; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.TopologyException; + +import de.intevation.gnv.math.IJKey; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import de.intevation.gnv.utils.Pair; + +import gnu.trove.TIntObjectHashMap; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Vectorizer backend to generated iso lines in form of + * JTS multi linestrings. + * + * @author Sascha L. Teichmann + */ +public class JTSMultiLineStringProducer +extends IsoProducer +{ + private static Logger log = Logger.getLogger( + JTSMultiLineStringProducer.class); + + /** + * The JTS geometry factory of this producer. + */ + protected GeometryFactory geometryFactory; + + /** + * The polygon used to clip the produced multe line strings. + */ + protected Polygon clip; + + /** + * Constructor to create a JTSMultiLineStringProducer with + * a given clipping polygon and a world bounding box. + * @param clip The clipping polygon. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public JTSMultiLineStringProducer( + Polygon clip, + double minX, double minY, + double maxX, double maxY + ) { + this( + clip, + // XXX: Geotools crashes if only using a 2d packed data format! + JTSMultiPolygonProducer.createDefaultGeometryFactory(3), + minX, minY, + maxX, maxY); + } + + /** + * Constructor to create a JTSMultiLineStringProducer with + * a given clipping polygon, a geometry factory + * and a world bounding box. + * @param clip The clipping polygon. + * @param geometryFactory The geometry factory. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public JTSMultiLineStringProducer( + Polygon clip, + GeometryFactory geometryFactory, + double minX, double minY, + double maxX, double maxY + ) { + super(minX, minY, maxX, maxY); + this.clip = clip; + this.geometryFactory = geometryFactory; + } + + /** + * Clips a given line string against the clippin polygon. The + * result is stored in the given list of line strings. + * @param lineString The line string to be clipped. + * @param lineStrings The result line string list. + */ + protected void clipLineString( + LineString lineString, + ArrayList lineStrings + ) { + if (clip == null) { + lineStrings.add(lineString); + return; + } + + if (!lineString.intersects(clip)) { + return; + } + + try { + Geometry result = lineString.intersection(clip); + + if (result instanceof LineString) { + lineStrings.add((LineString)result); + } + else if (result instanceof MultiLineString) { + MultiLineString mls = (MultiLineString)result; + for (int i = 0, N = mls.getNumGeometries(); i < N; ++i) { + Geometry g = mls.getGeometryN(i); + if (g instanceof LineString) { + lineStrings.add((LineString)g); + } + else { + log.warn("cannot handle geometry " + g.getClass()); + } + } + } + else { + log.warn("cannot handle " + result.getClass()); + } + } + catch (TopologyException te) { + log.error(te.getLocalizedMessage(), te); + lineStrings.add(lineString); + } + } + + /** + * Returns a list of pairs attribute -> multi line string. + * All line strings produced are grouped by there attribute + * which is generated with the given attribute generator. + * @param attributeGenerator The attribute generator. + * @return The list of attribute/multi line strings. + */ + public List> getMultiLineStrings( + AttributeGenerator attributeGenerator + ) { + ArrayList> multiLineStrings = + new ArrayList>(); + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + ArrayList coordinates = new ArrayList(); + + for (IJKey key: joinPairs()) { + ArrayList lineStrings = new ArrayList(); + + // process complete + ArrayList completeList = complete.get(key); + if (completeList != null) { + for (Edge head: completeList) { + Edge current = head; + do { + coordinates.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + } + while ((current = current.next) != head); + // add head again to close shape + coordinates.add(new Coordinate( + m1*(head.a % width) + b1, + m2*(head.a / width) + b2)); + + clipLineString( + geometryFactory.createLineString( + coordinates.toArray( + new Coordinate[coordinates.size()])), + lineStrings); + + coordinates.clear(); + } + } + + // process open + TIntObjectHashMap map = commonOpen.get(key); + + if (map != null) { + for (Edge head: headList(map)) { + + head = Vectorizer.simplify(head, width); + Edge current = head, last = head; + do { + coordinates.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + last = current; + } + while ((current = current.next) != null); + // add b from tail + coordinates.add(new Coordinate( + m1*(last.b % width) + b1, + m2*(last.b / width) + b2)); + + clipLineString( + geometryFactory.createLineString( + coordinates.toArray( + new Coordinate[coordinates.size()])), + lineStrings); + + coordinates.clear(); + } // for all in common open + } // if map defined for key + + if (!lineStrings.isEmpty()) { + MultiLineString multiLineString = + geometryFactory.createMultiLineString( + lineStrings.toArray( + new LineString[lineStrings.size()])); + lineStrings.clear(); + Object attribute = attributeGenerator != null + ? attributeGenerator.generateAttribute(key.i, key.j) + : key; + multiLineStrings.add(new Pair( + attribute, + multiLineString)); + } + } // for all pairs + + return multiLineStrings; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,303 @@ +package de.intevation.gnv.raster; + +import com.vividsolutions.jts.algorithm.CGAlgorithms; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.PrecisionModel; +import com.vividsolutions.jts.geom.TopologyException; + +import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.log4j.Logger; + +/** + * Vectorizer backend to generated polygons in form of + * JTS multi multi polygons. + * + * @author Sascha L. Teichmann + */ +public class JTSMultiPolygonProducer +extends AbstractProducer +{ + private static Logger log = Logger.getLogger( + JTSMultiPolygonProducer.class); + + /** + * The reference system of used coordinates: {@value} + */ + public static final int SRID_WGS84 = 4326; + + /** + * Interface to decouple the conversion of the internal + * index scheme of the polygons to an external one. + */ + public interface ValueConverter { + + /** + * Maps integer index schemes. + * @param value The input value. + * @return The resulting index. + */ + Integer convert(Integer value); + + } // interface ValueConverter + + /** + * The JTS geometry factory. + */ + protected GeometryFactory geometryFactory; + + /** + * The clipping polygon. + */ + protected Polygon clip; + + /** + * Internal map to map the internal polygons indices to a + * list of generated polygons. + */ + protected HashMap> valueToPolygons; + + /** + * Default constructor. + */ + public JTSMultiPolygonProducer() { + } + + /** + * Constructor to create a JTSMultiPolygonProducer with a + * given clipping polygon and a world bounding box. + * @param clip The clipping polygon. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public JTSMultiPolygonProducer( + Polygon clip, + double minX, double minY, + double maxX, double maxY + ) { + this( + clip, + createDefaultGeometryFactory(), + minX, minY, + maxX, maxY); + } + + /** + * Constructor to create a JTSMultiPolygonProducer with a + * given clipping polygon, a geometry factory and a world bounding box. + * @param clip The clipping polygon. + * @param geometryFactory The geometry factory. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public JTSMultiPolygonProducer( + Polygon clip, + GeometryFactory geometryFactory, + double minX, double minY, + double maxX, double maxY + ) { + super(minX, minY, maxX, maxY); + this.clip = clip; + this.geometryFactory = geometryFactory; + valueToPolygons = new HashMap>(); + } + + /** + * Creates a 3D geometry factory via + * {@link #createDefaultGeometryFactory(int)}. + * @return The new geometry factory. + */ + public static GeometryFactory createDefaultGeometryFactory() { + return createDefaultGeometryFactory(3); + } + + /** + * Creates a geometry factory with a given dimension. + * @param dim The dimension. + * @return The new geometry factory. + */ + public static GeometryFactory createDefaultGeometryFactory(int dim) { + return new GeometryFactory( + new PrecisionModel( + PrecisionModel.FLOATING), + SRID_WGS84, + new PackedCoordinateSequenceFactory( + PackedCoordinateSequenceFactory.DOUBLE, + dim)); + } + + public void handleRings( + List rings, + int value, + int width, + int height + ) { + if (value == -1) { + return; + } + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + ArrayList vertices = new ArrayList(); + + LinearRing shell = null; + ArrayList holes = new ArrayList(); + + for (Edge head: rings) { + Edge current = head; + do { + vertices.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + } + while ((current = current.prev) != head); + vertices.add(new Coordinate( + m1*(head.a % width) + b1, + m2*(head.a / width) + b2)); + + Coordinate [] coordinates = + vertices.toArray(new Coordinate[vertices.size()]); + + vertices.clear(); + + LinearRing ring = geometryFactory.createLinearRing( + coordinates); + + if (CGAlgorithms.isCCW(coordinates)) { + shell = ring; + } + else { + holes.add(ring); + } + } + + if (shell == null) { + log.error("polygon has no shell"); + return; + } + + Polygon polygon = geometryFactory.createPolygon( + shell, + holes.toArray(new LinearRing[holes.size()])); + + if (clip == null || clip.intersects(polygon)) { + Integer v = Integer.valueOf(value); + + ArrayList polygons = valueToPolygons.get(v); + + if (polygons == null) { + valueToPolygons.put(v, polygons = new ArrayList()); + } + + polygons.add(polygon); + } + } + + /** + * Returns a index -> multi polyon map. The internal index scheme + * is retained. + * {@link #getMultiPolygons(de.intevation.gnv.raster.JTSMultiPolygonProducer.ValueConverter)} + * @return The new map. + */ + public Map getMultiPolygons() { + return getMultiPolygons(null); + } + + /** + * Flattend a JTS geometry to a multi polygon if possible + * @param result The geometry to be flattend + * @return The resulting multi polygon. + */ + protected MultiPolygon flattenCollection(Geometry result) { + + if (result instanceof MultiPolygon) { + return (MultiPolygon)result; + } + + if (result instanceof Polygon) { + return geometryFactory.createMultiPolygon( + new Polygon[] { (Polygon)result }); + } + + log.warn("cannot handle " + result.getClass()); + + return null; + } + + /** + * Returns a index -> multi polyon map. The internal index scheme + * is remapped with the given value converter. + * @param valueConverter Converter to remap the index scheme. Maybe null + * if no remapping is required. + * @return The new map. + */ + public Map getMultiPolygons( + ValueConverter valueConverter + ) { + TreeMap multiPolygons = + new TreeMap(); + + for (Map.Entry> entry: + valueToPolygons.entrySet() + ) { + ArrayList polygons = entry.getValue(); + + Integer value = valueConverter != null + ? valueConverter.convert(entry.getKey()) + : entry.getKey(); + + MultiPolygon mp = geometryFactory.createMultiPolygon( + polygons.toArray(new Polygon[polygons.size()])); + + if (clip != null) { + try { + Geometry result = mp.intersection(clip); + + MultiPolygon mp2 = flattenCollection(result); + + if (mp2 != null) { mp = mp2; } + } + catch (TopologyException te) { + log.error(te.getLocalizedMessage(), te); + } + } + multiPolygons.put(value, mp); + } + + return multiPolygons; + } + + /** + * Empties internal temporary data structures to save some memory. + */ + public void clear() { + valueToPolygons.clear(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/KernelFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/KernelFilter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,99 @@ +package de.intevation.gnv.raster; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Element; + +/** + * An implemenation of raster filters based on given kernels. + * @author Sascha L. Teichmann + */ +public class KernelFilter +implements Filter +{ + private static Logger log = Logger.getLogger(KernelFilter.class); + + /** + * Implemens a factory which produces KernelFilters with Gauss kernels. + */ + public static class GaussFactory + implements Filter.Factory + { + /** + * Default sigma of Gauss kernel: {@value} + */ + public static final double DEFAULT_SIGMA = 1.0d; + /** + * Default radius of Gauss kernel: {@value} + */ + public static final int DEFAULT_RADIUS = 5; + + /** + * Configured sigma. + */ + protected double sigma; + /** + * Configured radius. + */ + protected int radius; + + /** + * Default constructor. + */ + public GaussFactory() { + sigma = DEFAULT_SIGMA; + radius = DEFAULT_RADIUS; + } + + public void init(Element element) { + String s = element.getAttribute("sigma"); + String r = element.getAttribute("radius"); + + if ((s = s.trim()).length() > 0) { + try { + sigma = Math.abs(Double.parseDouble(s)); + } + catch (NumberFormatException nfe) { + log.warn("gauss sigma '" + s + "' not a valid float value."); + } + } + + if ((r = r.trim()).length() > 0) { + try { + radius = Math.min(3, Math.abs(Integer.parseInt(r))); + } + catch (NumberFormatException nfe) { + log.warn("gauss radius '" + r + "' not a valid integer value."); + } + } + } + + public Filter create() { + return new KernelFilter(Raster.Kernel.createGauss(sigma, radius)); + } + } // class GaussFactory + + /** + * The kernel used by this filter. + */ + protected Raster.Kernel kernel; + + /** + * Default constructor. + */ + public KernelFilter() { + } + + /** + * Constructor to create a filter with a given kernel. + * @param kernel The kernel to be used. + */ + public KernelFilter(Raster.Kernel kernel) { + this.kernel = kernel; + } + + public Raster filter(Raster raster) { + return raster.create(kernel); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,428 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.raster.Raster.ValueToIndex; + +import java.awt.Color; + +import java.util.Arrays; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * Lookup mechanism to map double values from a list of + * ranges onto a set of colors and vice versa. + * @author Sascha L. Teichmann + */ +public class Palette +implements ValueToIndex +{ + private static Logger log = Logger.getLogger(Palette.class); + + /** + * An entry in the lookup table. + */ + public static final class Entry + implements Comparable + { + private Entry left; + private Entry right; + + private int index; + + private int externalIndex; + + private double from; + private double to; + + private String description; + + private Color color; + + /** + * Default constructor + */ + public Entry() { + } + + /** + * Copy constructor + * @param other The entry to copy. + */ + public Entry(Entry other) { + index = other.index; + externalIndex = other.externalIndex; + from = other.from; + to = other.to; + description = other.description; + color = other.color; + } + + /** + * Constructor to set the palette index, the exteral index, + * the value range, the color and the description. + * @param index The pallette index + * @param externalIndex The external index + * @param from Start of the interval + * @param to End of the interval + * @param color The color belonging to this interval. + * @param description The description of this range. + */ + public Entry( + int index, + int externalIndex, + double from, + double to, + Color color, + String description + ) { + this.index = index; + this.externalIndex = externalIndex; + this.from = from; + this.to = to; + this.color = color; + this.description = description; + } + + /** + * Compares two entries by the start point of the interval. + * @param other + * @return -1 if this start point is before other. +1 if this + * start point is after, else 0. + */ + public int compareTo(Object other) { + Entry e = (Entry)other; + if (from < e.from) return -1; + if (from > e.from) return +1; + return 0; + } + + /** + * The starting point of the interval. + * @return The starting point. + */ + public double getFrom() { + return from; + } + + /** + * The end point of the interval. + * @return The end point. + */ + public double getTo() { + return to; + } + + /** + * The color of the entry. + * @return The color. + */ + public Color getColor() { + return color; + } + + /** + * The external index of this entry. Useful to model + * external joins. + * @return The external index. + */ + public int getExternalIndex() { + return externalIndex; + } + + /** + * Searches for an entry which has a range that contains + * the given value. + * @param value The value to be searched. + * @return The entry containing the value or null if no such + * entry exists. + */ + public Entry locateEntry(double value) { + Entry current = this; + while (current != null) { + boolean b = value >= current.from; + if (b && value <= current.to) { + return current; + } + current = b + ? current.right + : current.left; + } + return null; + } + + /** + * Returns the palette index for a given value. + * @param value The value to search. + * @return The index of the palette entry or -1 if + * no such entry exists. + */ + public int locate(double value) { + Entry entry = locateEntry(value); + return entry != null + ? entry.index + : -1; + } + + /** + * Searches for an interval with a given index. + * @param index The index to be searched. + * @return The entry with the given index or null if no + * such entry exists. + */ + public Entry findByIndex(int index) { + Entry current = this; + while (current != null) { + if (current.index == index) { + break; + } + current = index < current.index + ? current.left + : current.right; + } + return current; + } + + /** + * The description of this entry. + * @return The description. + */ + public String getDescription() { + return description; + } + + /** + * Determines if the range of this entry has + * infinitive length. + * @return true if the range of this entry has infinitive + * length else false. + */ + public boolean isInfinity() { + return from == -Double.MAX_VALUE + || to == Double.MAX_VALUE; + } + } // class Entry + + /** + * Internal table of the entrys. + */ + protected Entry [] entries; + + /** + * Root of the entry tree used to map values to entries. + */ + protected Entry lookup; + + /** + * The list of colors used by this palette. + */ + protected Color [] rgbs; + + private Entry buildLookup(Entry [] entries, int lo, int hi) { + if (lo > hi) { + return null; + } + int mid = (lo + hi)/2; + Entry entry = entries[mid]; + entry.left = buildLookup(entries, lo, mid-1); + entry.right = buildLookup(entries, mid+1, hi); + return entry; + } + + /** + * Default constructor. + */ + public Palette() { + } + + /** + * Constructor to create the palette from an XML document. + * @param document The document with palette information. + */ + public Palette(Document document) { + + NodeList rangeNodes = document.getElementsByTagName("range"); + + entries = new Entry[rangeNodes.getLength()]; + rgbs = new Color[entries.length]; + + for (int i = 0; i < entries.length; ++i) { + Element rangeElement = (Element)rangeNodes.item(i); + double from = doubleValue(rangeElement.getAttribute("from")); + double to = doubleValue(rangeElement.getAttribute("to")); + int extIndex = intValue(rangeElement.getAttribute("index"), i); + Color color = color(rangeElement.getAttribute("rgb")); + String desc = rangeElement.getAttribute("description"); + if (from > to) { double t = from; from = to; to = t; } + entries[i] = new Entry(i, extIndex, from, to, color, desc); + rgbs[i] = color; + } + + buildLookup(); + } + + /** + * Constructor to split a given palette into a given number of + * equal sized sub entries. Ranges of infinitive length are not + * splitted. + * @param original The source palette. + * @param N The number of chunks to split single ranges into. + */ + public Palette(Palette original, int N) { + if (N < 2) { + throw new IllegalArgumentException("N < 2"); + } + + Entry [] origEntries = original.entries; + + int newSize = 0; + for (int i = 0; i < origEntries.length; ++i) { + // cannot split infinity intervals + newSize += origEntries[i].isInfinity() ? 1 : N; + } + + entries = new Entry[newSize]; + rgbs = new Color[newSize]; + + for (int i = 0, j = 0; i < origEntries.length; ++i) { + Entry origEntry = origEntries[i]; + if (origEntry.isInfinity()) { + // infinity intervals are just copied + Entry nEntry = new Entry(origEntry); + entries[j] = nEntry; + rgbs[j] = nEntry.color; + nEntry.index = j++; + } + else { + // split interval into N parts + double from = origEntry.from; + double to = origEntry.to; + double delta = (to - from)/N; + for (int k = 0; k < N; ++k) { + Entry nEntry = new Entry(origEntry); + nEntry.from = from; + nEntry.to = from + delta; + from += delta; + entries[j] = nEntry; + rgbs[j] = nEntry.color; + nEntry.index = j++; + } + } // limited interval + } // for all original entries + + buildLookup(); + } + + private static final int intValue(String s, int def) { + if (s == null || (s = s.trim()).length() == 0) { + return def; + } + try { + return Integer.parseInt(s); + } + catch (NumberFormatException nfe) { + log.error(nfe.getLocalizedMessage(), nfe); + } + return def; + } + + private static final double doubleValue(String s) { + if (s == null || (s = s.trim()).length() == 0) { + return 0d; + } + if ((s = s.toLowerCase()).startsWith("-inf")) { + return -Double.MAX_VALUE; // XXX: Not using Double.NEGATIVE_INFINITY! + } + + if (s.startsWith("inf")) { + return Double.MAX_VALUE; // XXX: Not using Double.NEGATIVE_INFINITY! + } + + return Double.parseDouble(s); + } + + private static final Color color(String s) { + if (s == null || (s = s.trim()).length() == 0) { + return null; + } + return Color.decode(s); + } + + + /** + * Internal method to build the lookup tree. + */ + protected void buildLookup() { + Arrays.sort(entries); + lookup = buildLookup(entries, 0, entries.length-1); + } + + /** + * Creates a new palette which has ranges that are subdivided + * into a given number of sub ranges each. + * @param N The number od sub divisions of each range. + * @return The new created palette. + */ + public Palette subdivide(int N) { + return new Palette(this, N); + } + + /** + * Return the number of entries in this palette. + * @return The number of entries. + */ + public int getSize() { + return rgbs.length; + } + + /** + * Return the color of an entry for a given index. + * @param index The index. + * @return The color. + */ + public Color getColor(int index) { + return rgbs[index]; + } + + /** + * Return the RGB value + * @param index of an entry for a given index. + * @return rgb value + */ + public int indexToRGB(int index) { + return rgbs[index].getRGB(); + } + + /** + * Searches for the index of an entry which contains the + * given value. + * @param value The value to be searched. + * @return The index of the entry or -1 if no entry is found. + */ + public int toIndex(double value) { + return lookup.locate(value); + } + + /** + * Searches for the an entry which contains the given value. + * @param value The value to be searched. + * @return The entry which contains the value or null if + * no such entry is found. + */ + public Entry getEntry(double value) { + return lookup.locateEntry(value); + } + + /** + * Searches the entry for a given index. + * @param index The index of the entry. + * @return The entry or null if no such entry is found. + */ + public Entry getEntryByIndex(int index) { + return lookup.findByIndex(index); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/PaletteManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PaletteManager.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,113 @@ +package de.intevation.gnv.raster; + +import java.lang.ref.SoftReference; + +import java.util.HashMap; + +/** + * Manages palettes by their name. Provides different levels of + * subdivisions. + * @author Sascha L. Teichmann + */ +public class PaletteManager +{ + /** + * The base palette. + */ + protected Palette base; + + /** + * The description of the palette. + */ + protected String description; + + /** + * The name of the palette. + */ + protected String name; + + /** + * Already created subdivisions of the palette. + */ + protected HashMap> levels; + + /** + * Default constructor. + */ + public PaletteManager() { + } + + /** + * Constructor to create a palette manager with a given name, + * description and base palette. + * @param name The name. + * @param description The description. + * @param base The base palette. + */ + public PaletteManager( + String name, + String description, + Palette base + ) { + this.name = name; + this.description = description; + this.base = base; + levels = new HashMap>(); + } + + /** + * Returns the description of the palette. + * @return The description. + */ + public String getDescription() { + return description; + } + + /** + * The name of the palette. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Returns the base palette. + * @return The base palette. + */ + public Palette getBase() { + return base; + } + + /** + * Returns the subdivided palette of a given level. + * @param n The level of subdivision. + * @return The subdivided palette. + */ + public Palette getLevel(int n) { + if (n < 2) { + return base; + } + + Integer N = Integer.valueOf(n); + + Palette palette; + + synchronized (levels) { + SoftReference ref = levels.get(N); + + if (ref != null && (palette = ref.get()) != null) { + return palette; + } + + palette = base.subdivide(n); + + ref = new SoftReference(palette); + + levels.put(N, ref); + } + + return palette; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,109 @@ +package de.intevation.gnv.raster; + +import de.intevation.gnv.jfreechart.CompactXYItems; +import de.intevation.gnv.jfreechart.PolygonDataset; +import de.intevation.gnv.jfreechart.PolygonSeries; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import gnu.trove.TDoubleArrayList; + +import java.util.HashMap; +import java.util.List; + +/** + * Vectorizer backend to produce polygon datasets suitable to being + * displayed with {@link de.intevation.gnv.jfreechart.PolygonPlot}. + * + * @author Sascha L. Teichmann + */ +public class PolygonDatasetProducer +extends AbstractProducer +{ + /** + * Maps value integers to series of polygons to group + * them by value. + */ + protected HashMap polygonSeries; + + /** + * Default constructor. + */ + protected PolygonDatasetProducer() { + } + + /** + * Constructor to create a PolygonDatasetProducer with + * a given world bound box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ + public PolygonDatasetProducer( + double minX, double minY, + double maxX, double maxY + + ) { + super(minX, minY, maxX, maxY); + polygonSeries = new HashMap(); + } + + public void handleRings( + List rings, + int value, + int width, + int height + ) { + if (value == -1) { + return; + } + + Integer v = Integer.valueOf(value); + + PolygonSeries ps = polygonSeries.get(v); + + if (ps == null) { + polygonSeries.put(v, ps = new PolygonSeries()); + ps.setAttribute("fill", v); + } + + TDoubleArrayList vertices = new TDoubleArrayList(); + + /* minX = 0*m1 + b1 <=> b1 = minX + * maxX = (width-1)*m1 + b1 + * m1 = (maxX - minX)/(width-1) + */ + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + for (Edge head: rings) { + Edge current = head; + do { + vertices.add(m1*(current.a % width) + b1); + vertices.add(m2*(current.a / width) + b2); + } + while ((current = current.next) != head); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + vertices.reset(); + } + } + + /** + * Creates a new PolygonDataset from the polygons build by this + * backend. + * @return the new PolygonDataset + */ + public PolygonDataset getPolygonDataset() { + return new PolygonDataset(polygonSeries.values()); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/Raster.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Raster.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,407 @@ +package de.intevation.gnv.raster; + +/** + * A 2D double valued representation of a raster array. + * @author Sascha L. Teichmann + */ +public class Raster +{ + /** + * A kernel can be applied to a raster to fold its values. + */ + public static class Kernel { + + /** + * The coefficients of the folding matrix. + */ + public static final class Coeff { + /** + * i delta index of this coefficient. + */ + public int di; + /** + * i delta index of this coefficient. + */ + public int dj; + /** + * The weight of this coefficient. + */ + public double c; + + /** + * Default constructor + */ + public Coeff() { + } + + /** + * Constructor to set the delta position and the weight of + * the coefficient. + * @param di The i delta index. + * @param dj The j delta index. + * @param c The weight of the index. + */ + public Coeff(int di, int dj, double c) { + this.di = di; + this.dj = dj; + this.c = c; + } + + /** + * Returns a string representation of this coefficient. + * @return The string representation. + */ + @Override + public String toString() { + return String.valueOf(c); + } + + } // class Coeff + + /** + * The coefficients of the folding matrix. + */ + protected Coeff [] coeffs; + /** + * The width of the kernel. + */ + protected int width; + + /** + * Default constrcutor. + */ + public Kernel() { + } + + /** + * Constructor for a kernel with a given coefficient matrix + * with a given width. + * @param coeffs The coefficients. + * @param width The width of the kernel. + */ + public Kernel(Coeff [] coeffs, int width) { + this.coeffs = coeffs; + this.width = width; + } + + /** + * Evaluates the 2D Gauss normal distribution a given x, y + * and a given sigma. + * @param x The x location. + * @param y The y location. + * @param sigma The sigma of the distribution. + * @return The value at point x, y. + */ + public static double gauss(double x, double y, double sigma) { + double s2 = sigma*sigma; + return 1.0d/(2.0d*Math.PI*s2)*Math.exp(-(x*x + y*y)/(2.0d*s2)); + } + + /** + * Creates a Gauss kernel with sigma = 1 and width 5. + * @return The new kernel. + */ + public static Kernel createGauss() { + return createGauss(1.0d, 5); + } + + /** + * Creates a Gauss kernel with a given sigma and width. + * @param sigma The sigma value + * @param width The width of the kernel. + * @return The new kernel. + */ + public static Kernel createGauss(double sigma, int width) { + Coeff [] coeffs = new Coeff[width*width]; + double sum = 0d; + for (int j = 0; j < width; ++j) { + int y = -width/2 + j; + for (int i = 0; i < width; ++i) { + int x = -width/2 + i; + double c = gauss(x, y, sigma); + coeffs[j*width + i] = new Coeff(x, y, c); + sum += c; + } + } + sum = 1.0/sum; + for (int i = 0; i < coeffs.length; ++i) { + coeffs[i].c *= sum; + } + return new Kernel(coeffs, width); + } + + /** + * Evaluates this Kernel at the raster at raster index i, j. + * @param access The accessor to the raster. + * @param i The i raster index. + * @param j The j raster index. + * @return The folded value at index i, j. + */ + public double fold(Access access, int i, int j) { + + double s = 0.0d; + + double unused = 0d; + + for (int k = 0; k < coeffs.length; ++k) { + Coeff coeff = coeffs[k]; + double v = access.get(i + coeff.di, j + coeff.dj); + if (Double.isNaN(v)) { + unused += coeff.c; + } + else { + s += v * coeff.c; + } + } + + return s*(1.0d - unused); + } + + /** + * Returns a string representation of this kernel. + * @return The string representation. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + int height = coeffs.length/width; + + for (int j = 0; j < height; ++j) { + if (j > 0) { + sb.append(System.getProperty("line.separator")); + } + for (int i = 0; i < width; ++i) { + if (i > 0) { + sb.append("\t"); + } + sb.append(coeffs[j*width + i]); + } + } + + return sb.toString(); + } + } // class Kernel + + /** + * Interface of allow special access patterns to the raster, + * especially at the border. + */ + public interface Access { + + /** + * Returns the raster value at a given index point. + * @param i The i index + * @param j The j index + * @return The value of the raster. + */ + double get(int i, int j); + + } // interface Access + + /** + * Interface to decouple the lookup which is needed + * to map double values to integers. + */ + public interface ValueToIndex { + + /** + * Returns the corresponding integer to a given value. + * @param value The value to be queried. + * @return The integer value or -1 if no such value was found. + */ + int toIndex(double value); + + } // interface ValueToIndex; + + /** + * Brings raster to an integer representation with equal sized bins + * of integer vaules. + */ + public static class IsoClasses + implements ValueToIndex + { + /** + * Linear scaling factor. + */ + protected double m; + /** + * Linear offset. + */ + protected double b; + /** + * Number of classes. + */ + protected int numClasses; + + /** + * Constructor to build a lookup to transform + * an raster into an equals sized bin integer array. + * @param raster The original raster + * @param numClasses The number of classes. + */ + public IsoClasses(Raster raster, int numClasses) { + + this.numClasses = numClasses; + + double min = Double.MAX_VALUE; + double max = -Double.MAX_VALUE; + + double [] src = raster.raster; + + for (int i = 0; i < src.length; ++i) { + double x = src[i]; + if (!Double.isNaN(x)) { + if (x < min) min = x; + if (x > max) max = x; + } + } + + /* f(min) = 0, f(max) = numClasses - 1 + + I: 0 = m*min + b + II: numClasses - 1 = m*max + b + + II - I: + numClasses - 1 = m*(max - min) + + m = (numClasses - 1)/(max - min) + b = m*min + */ + + if (max == min) { + m = 0; + b = 0; + } + else { + m = (numClasses - 1)/(max - min); + b = m*min; + } + } + + /** + * Implements the double to integer lookup. + * @param value The value to map. + * @return The mapped value. + */ + public int toIndex(double value) { + return Double.isNaN(value) + ? -1 + : Math.min(Math.max(0, (int)Math.round(m*value + b)), numClasses-1); + } + } // class IsoClasses + + /** + * Internal representation of the raster. + */ + protected double [] raster; + /** + * The width of the raster. + */ + protected int width; + + /** + * Default constructor. Creates an 0x0 raster. + */ + public Raster() { + this(new double[0], 0); + } + + /** + * Creates a raster with given values and width. + * @param raster + * @param width + */ + public Raster(double [] raster, int width) { + this.raster = raster; + this.width = width; + } + + /** + * The width of the raster. + * @return The width. + */ + public int getWidth() { + return width; + } + + /** + * The height of the raster. + * @return The height. + */ + public int getHeight() { + return raster.length / width; + } + + /** + * The values of the raster. + * @return The values. + */ + public double [] getValues() { + return raster; + } + + /** + * Creates an integer representation of this raster using a + * given value to index transformer. + * @param valueToIndex The transformer to map double to integer values. + * @return The new created integer representation. + */ + public int [] toIndexed(ValueToIndex valueToIndex) { + int [] dst = new int[raster.length]; + for (int i = 0; i < raster.length; ++i) { + dst[i] = valueToIndex.toIndex(raster[i]); + } + return dst; + } + + /** + * Creates a new raster by applying a kernel to this raster. + * Access to the raster is continuous at the border. + * The original raster is not modified. + * @param kernel The kernel to be applied. + * @return The new raster. + */ + public Raster create(Kernel kernel) { + double [] dst = new double[raster.length]; + Raster r = new Raster(dst, width); + r.apply(kernel, continueBorder()); + return r; + } + + /** + * Creates a new raster by applying a kernel to this raster. + * Access to the raster is given. + * @param kernel The kernel to be applied. + * @param access The access method to the raster. + */ + public void apply(Kernel kernel, Access access) { + int height = getHeight(); + for (int j = 0; j < height; ++j) { + int row = j*width; + for (int i = 0; i < width; ++i) { + raster[row + i] = kernel.fold(access, i, j); + } + } + } + + /** + * Returns a continuous access to the raster. Values + * at the border are repeated til infinity if indices + * are accessed outside the defined area. + * @return The accessor. + */ + public Access continueBorder() { + return new Access() { + int height = getHeight()-1; + public double get(int i, int j) { + if (i < 0) i = 0; + else if (i >= width) i = width-1; + if (j < 0) j = 0; + else if (j > height) j = height; + return raster[j*width + i]; + } + }; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/RasterToPPM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/RasterToPPM.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.raster; + +import java.awt.Color; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Little helper class to write a Raster into an output stream + * as a Netpbm PPM file. + * @author Sascha L. Teichmann + */ +public class RasterToPPM +{ + private RasterToPPM() { + } + + /** + * Writes a Raster to a given stream as PPM. + * @param raster The raster to be written. + * @param palette The palette used to figure out the rgb values. + * @param out The stream to write into. + * @throws IOException Thrown if some error occurred during writing + * data to the output stream. + */ + public static void writeToPPM( + Raster raster, + Palette palette, + OutputStream out + ) + throws IOException + { + int W = raster.getWidth(); + int H = raster.getHeight(); + out.write(("P6\n" + W + " " + H + "\n255\n").getBytes("US-ASCII")); + double [] values = raster.getValues(); + int pos = 0; + byte [] data = new byte[W*3]; + int black = Color.BLACK.getRGB(); + for (int i = 0; i < H; ++i) { + for (int j = 0; j < data.length; ++pos) { + Palette.Entry entry = palette.getEntry(values[pos]); + int rgb = entry == null + ? black + : entry.getColor().getRGB(); + data[j++] = (byte)((rgb >> 16) & 0xff); + data[j++] = (byte)((rgb >> 8) & 0xff); + data[j++] = (byte)( rgb & 0xff); + } + out.write(data); + } + out.flush(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,508 @@ +package de.intevation.gnv.raster; + +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntStack; + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import org.apache.log4j.Logger; + +/** + * Instances of this class are able to vectorize 2D integer arrays + * with a kind of flood filling regions detection mechanism to + * a set of line strings and polygons. + * + * @author Sascha L. Teichmann + */ +public class Vectorizer +{ + private static Logger log = Logger.getLogger(Vectorizer.class); + + /** + * Callback to process the found line strings and polygons. + */ + public interface RingsHandler { + + /** + * Called from {@link #process(de.intevation.gnv.raster.Vectorizer.RingsHandler) } + * to give the found features to the postprocessing backend. + * @param rings The found line strings and polygons. + * @param value The integer value of the raster surrounded by + * the features. + * @param width The width of the index space of the vectorized data. + * @param height The height of the index space of the vectorized data. + */ + void handleRings( + List rings, + int value, + int width, + int height); + + } // interface RingsHandler + + /** + * Doubly link list representing a line string or a polygon. + */ + public static final class Edge { + + /** + * The predecessor. + */ + public Edge prev; + /** + * The successor. + */ + public Edge next; + + /** + * Index of first vertex. To separate x and y values + * you have to divide the value by the width of the + * index space. + */ + public int a; + /** + * Index of second vertex. To separate x and y values + * you have to divide the value by the width of the + * index space. + */ + public int b; + + /** + * Default constructor. + */ + public Edge() { + } + + /** + * Constructor to create Edge with two vertices. + * @param a The first vertex. + * @param b The second vertex. + */ + public Edge(int a, int b) { + this.a = a; + this.b = b; + } + + /** + * Copy constructor + * @param other The edge to clone. + */ + public Edge(Edge other) { + a = other.a; + b = other.b; + } + + /** + * Chain a given edge segment to this segment. The + * side of the chaining is determined by a given + * parameter. + * @param other The segment to chain. + * @param found The side to chain. + */ + public void chain(Edge other, int found) { + + if (found == a) { + other.next = this; + prev = other; + return; + } + + if (found == b) { + next = other; + other.prev = this; + return; + } + + throw new IllegalStateException("cannot chain"); + } + + /** + * Tells if the list is complete which means that this + * edge list is a closed polygon. + * @return true if edge list is closed else false. + */ + public boolean isComplete() { + Edge current = this; + do { + if (current.prev == null || current.next == null) { + return false; + } + current = current.next; + } + while (current != this); + return true; + } + + /** + * Returns the length of this edge list in next direction. + * Segments in prev direction are ignored. + * @return The length of this edge list. + */ + public int length() { + int length = 0; + Edge current = this; + do { ++length; } + while ((current = current.next) != null && current != this); + return length; + } + + /** + * Returns the head node of this edge list. + * @return The head node. + */ + public Edge head() { + Edge current = this; + while (current.prev != null) { + current = current.prev; + } + return current; + } + + /** + * Hashes the two vertex indices to a common value. + * @return The hash value. + */ + @Override + public int hashCode() { + return (a << 16) | b; + } + + /** + * Two edges are considered equal if they have the same + * a and b vertices. + * @param other The other edge. + * @return true if the edges are equal else false. + */ + @Override + public boolean equals(Object other) { + Edge e = (Edge)other; + return a == e.a && b == e.b; + } + } // class Edge + + /** + * Simplifies a given edge list by removing collinear vertices. + * Attention: The original list is modified. + * @param edge The edge list to simplify. + * @param width The width of the vertex index space. + * @return The simplified list. + */ + protected static Edge simplify(Edge edge, int width) { + + Edge e1 = edge, start = edge; + + int length = edge.length(); + + if (length < 2) { + return e1; + } + + Edge e2 = edge.next; + + int count = 0; + + do { + int e1x = e1.a % width; + int e1y = e1.a / width; + int e2x = e1.b % width; + int e2y = e1.b / width; + int e3x = e2.b % width; + int e3y = e2.b / width; + + if ((e1x == e2x && e2x == e3x && e1x == e3x) + || (e1y == e2y && e2y == e3y && e1y == e3y)) { + e1.b = e2.b; + Edge removed = e1.next; + e1.next = e2.next; + if (e1.next != null) { + e1.next.prev = e1; + } + e2 = e1.next; + count = 0; + --length; + if (removed == start) { + start = e1; + } + } + else { + e1 = e1.next; + e2 = e2.next; + ++count; + } + } + while (length > 1 && e2 != null && count < length + 2); + + return start; + } + + /** + * The raster to be traced. + */ + protected int [] raster; + /** + * The width of the raster. + */ + protected int width; + /** + * Map of the currently open edges. + */ + protected TIntObjectHashMap openEdges; + /** + * List of rings already found. + */ + protected List rings; + /** + * Flag to signal if a simplification should be performed + * after a ring is completed. + */ + protected boolean simplify; + + /** + * Default constructor. Simplification is turned on. + */ + public Vectorizer() { + this(true); + } + + /** + * Constructor to create a vectorized with an explicit + * simplification policy. + * @param simplify Indicates if simplification should be + * used on ring completion. + */ + public Vectorizer(boolean simplify) { + openEdges = new TIntObjectHashMap(); + rings = new ArrayList(); + this.simplify = simplify; + } + + /** + * Constructor to create a vectorizer with a given raster and width. + * Simplification is turn on. + * @param raster The raster to be vectorized. + * @param width The width of the raster. + */ + public Vectorizer(int [] raster, int width) { + this(true, raster, width); + } + + /** + * Constructor to create a vectorizer with a given raster, width + * and an explicit simplification policy. + * @param simplify Indicates if simplification should be + * used on ring completion. + * @param raster The raster to be vectorized. + * @param width The width of the raster. + */ + public Vectorizer(boolean simplify, int [] raster, int width) { + this(simplify); + this.raster = raster; + this.width = width; + } + + /** + * Returns (x, y+1) for given vertex in index space. + * @param i vertex in index space. + * @param w width of raster. + * @return (x, y+1) in index space. + */ + public static final int tl(int i, int w) { + int x = i % w; + int y = i / w; + return x + (w + 1)*y; + } + + /** + * Returns tl(i, w) + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return tl(i, w) + 1. + */ + public static final int tr(int i, int w) { + return tl(i, w) + 1; + } + + /** + * Returns tl(i, w) + w + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return tl(i, w) + w + 1. + */ + public static final int bl(int i, int w) { + return tl(i, w) + w + 1; + } + + /** + * Returns bl(i, w) + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return bl(i, w) + 1. + */ + public static final int br(int i, int w) { + return bl(i, w) + 1; + } + + /** + * Resets open resources after a set of features were found. + */ + protected void resetRegion() { + openEdges.clear(); + rings.clear(); + } + + /** + * Adds an edge to the map of open edges, joins it + * with its direct neighbors of if complete add the + * list to the complete features. + * @param edge + */ + protected void emit(Edge edge) { + + Edge otherA = (Edge)openEdges.remove(edge.a); + if (otherA != null) { + otherA.chain(edge, edge.a); + } + + Edge otherB = (Edge)openEdges.remove(edge.b); + if (otherB != null) { + otherB.chain(edge, edge.b); + } + + if (edge.isComplete()) { + rings.add(simplify ? simplify(edge, width + 1) : edge); + } + else { + if (otherA == null) { + openEdges.put(edge.a, edge); + } + if (otherB == null) { + openEdges.put(edge.b, edge); + } + } + } + + /** + * Vectorize the raster. The found features are fed into + * the given ring handler. + * @param handler The RingHandler to postprocess the found features. + * @return The number of regions found. + */ + public int process(RingsHandler handler) { + + BitSet visited = new BitSet(raster.length); + + TIntStack stack = new TIntStack(); + + int regions = 0; + + int height = raster.length / width; + + for (int i = 0; i < raster.length; ++i) { + if (visited.get(i)) { + continue; + } + + ++regions; + + int currentValue = raster[i]; + visited.set(i); + + int current = i; + visited.set(current); + + for (;;) { + int tl = tl(current, width); + int tr = tr(current, width); + int bl = bl(current, width); + int br = br(current, width); + + int t = current - width; + + if (t < 0) { + emit(new Edge(tr, tl)); + } + else { + if (raster[t] != currentValue) { + emit(new Edge(tr, tl)); + } + else { + if (!visited.get(t)) { + visited.set(t); + stack.push(t); + } + } + } + + int b = current + width; + + if (b >= raster.length) { + emit(new Edge(bl, br)); + } + else { + if (raster[b] != currentValue) { + emit(new Edge(bl, br)); + } + else { + if (!visited.get(b)) { + visited.set(b); + stack.push(b); + } + } + } + + int x = current % width; + + if (x == 0) { + emit(new Edge(tl, bl)); + } + else { + int l = current - 1; + if (raster[l] != currentValue) { + emit(new Edge(tl, bl)); + } + else { + if (!visited.get(l)) { + visited.set(l); + stack.push(l); + } + } + } + + if (x == width - 1) { + emit(new Edge(br, tr)); + } + else { + int r = current + 1; + if (raster[r] != currentValue) { + emit(new Edge(br, tr)); + } + else { + if (!visited.get(r)) { + visited.set(r); + stack.push(r); + } + } + } + + if (stack.size() == 0) { + break; + } + + current = stack.pop(); + } + + handler.handleRings( + rings, + currentValue, + width + 1, + height + 1); + + resetRegion(); + } + + return regions; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/raster/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + +Classes and interfaces to handle 2D double valued +raster arrays. Additional palette support and vectorization these rasters into +simple feature vector representations are supplied. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/AutoResumeState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/AutoResumeState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,14 @@ +package de.intevation.gnv.state; + +/** + * + * Markerinterface for states which should be used for + * automatically resume and jump to the next State using + * the conditions of the transitions which are linked to it. + * + * @author Tim Englich + */ +public interface AutoResumeState extends State{ + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,175 @@ +package de.intevation.gnv.state; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.vividsolutions.jts.geom.Point; + +import de.intevation.artifactdatabase.Config; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; +import de.intevation.gnv.utils.ArtifactXMLUtilities; +import de.intevation.gnv.utils.InputValidator; +import de.intevation.gnv.utils.WKTUtils; +import de.intevation.gnv.utils.exception.ValidationException; + +/** + * This state handles coordinate input by the user. It searches database results + * for coordinates and turns them into a human readable form. + * + * @author Tim Englich + * + */ +public class CoordinateSelectionState extends StateBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(CoordinateSelectionState.class); + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 6318923553625195063L; + + /** + * XPATH Expressions for the setup. + */ + + private final static String MESH_WIDTH_XPATH = "mesh-width"; + private final static String XLINK_XPATH = "xlink:href"; + private final static String MESH_LIST_XPATH = "/mesh-widths/mesh"; + private final static String ID_XPATH = "id"; + private final static String WIDTH_VALUE_XPATH = "width"; + + /** + * Holds all given Widths between two MeshPoints for different Meshes. + */ + private HashMap meshWidths = null; + + /** + * Constructor + */ + public CoordinateSelectionState() { + super(); + } + + @Override + protected List purifyResult(Collection result, String uuid) { + log.debug("CoordinateSelectionState.purifyResult"); + List describeData = new ArrayList(); + + NamedCollection keyValueDescibeData = + extractKVP(result, "FEATUREID", "SHAPE"); + + describeData.add(keyValueDescibeData); + return describeData; + } + + + @Override + protected String prepareInputData4RegionDBQuery(String value) { + log.debug("CoordinateSelectionState.prepareInputData4RegionDBQuery"); + double distance=0.; + String returnValue = null; + try { + Point center = InputValidator.getPointValue(value); + String meshId = super.inputData.get("meshid").getValue(); + int segments = 97; + if (meshWidths != null){ + Double distanceValue = this.meshWidths.get(meshId); + if (distanceValue != null){ + log.debug("User "+distanceValue+" as Buffer around given Point"); + distance = distanceValue.doubleValue(); + }else{ + log.warn("No distance is configured for Mesh with id"+ meshId); + } + }else{ + log.warn("No MeshWidth configured. Check if this is correct."); + } + returnValue = center.buffer(distance,segments).toText(); + } catch (NumberFormatException e) { + log.error(e,e); + } catch (ValidationException e) { + log.error(e,e); + } + return returnValue; + + } + + + @Override + protected NamedCollection extractKVP( + Collection result, + String keyid, + String valueid) { + Iterator rit = result.iterator(); + NamedCollection keyValueDescibeData = new NamedArrayList( + this.dataName, result.size()); + keyValueDescibeData.setMultiSelect(this.dataMultiSelect); + String prevKey = null; + while (rit.hasNext()) { + Result resultValue = rit.next(); + String key = resultValue.getString(keyid); + if(prevKey == null || !prevKey.equals(key)){ // TODO: FIXME: We have to do that because the arcsde does not support a distinct Query on Layers + String geomString = CoordinateSelectionState.convert2DisplayCoordinate(resultValue.getString(valueid)); + String value = geomString; + if (resultValue.getResultDescriptor().getColumnIndex("VALUE") > 0){ + value = resultValue.getString("VALUE") + " - "+value; + } + + + keyValueDescibeData.add(new DefaultKeyValueDescribeData(key,value )); + } + prevKey = key; + } + return keyValueDescibeData; + } + + /** + * Turn coordinate into a human readable format. + * + * @param wkt Coordinate as wkt string. + * @return formatted coordinate. + */ + protected static String convert2DisplayCoordinate(String wkt){ + return WKTUtils.toText(wkt); + } + + + @Override + public void setup(Node configuration) { + super.setup(configuration); + Element widthElement = (Element)Config.getNodeXPath(configuration, MESH_WIDTH_XPATH); + + if (widthElement != null){ + String fileName = widthElement.getAttribute(XLINK_XPATH); + fileName = Config.replaceConfigDir(fileName); + Node configurationNode = new ArtifactXMLUtilities().readConfiguration(fileName); + NodeList meshNodes = Config.getNodeSetXPath(configurationNode,MESH_LIST_XPATH ); + if (meshNodes != null){ + meshWidths = new HashMap(meshNodes.getLength()); + for (int i = 0; i < meshNodes.getLength(); i++){ + Element meshNode = (Element)meshNodes.item(i); + String id = meshNode.getAttribute(ID_XPATH); + Double value = Double.parseDouble(meshNode.getAttribute(WIDTH_VALUE_XPATH)); + meshWidths.put(id, value); + } + } + }else{ + log.warn("No Mesh Width defined."); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultAutoResumeState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultAutoResumeState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,41 @@ +package de.intevation.gnv.state; + +import de.intevation.gnv.geobackend.base.Result; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + +/** + * Default implementation of AutoResumeState. + * + * @author Tim Englich + */ +public class DefaultAutoResumeState extends StateBase implements AutoResumeState +{ + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -4470531390092041577L; + + /** + * Constructor + */ + public DefaultAutoResumeState() { + super(); + } + + + @Override + protected List purifyResult(Collection result, String uuid) { + return new ArrayList(0); + } + + + @Override + protected String[] getDescriptionForInputData(InputData data, String uuid) { + return new String[0]; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultExportMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultExportMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.gnv.state; + +/** + * This is the default implementation of ExportMode. + * + * @author Ingo Weinzierl + */ +public class DefaultExportMode +implements ExportMode +{ + /** + * The name of the export (e.g. pdf, svg, image). + */ + protected String name; + + /** + * A description for this export. + */ + protected String description; + + /** + * The mimetype used to do execute this export. + */ + protected String mimeType; + + /** + * Constructor. + * + */ + public DefaultExportMode(String name, String description, String mimeType){ + this.name = name; + this.description = description; + this.mimeType = mimeType; + } + + + public String getName() { + return name; + } + + + public String getDescription() { + return description; + } + + + public String getMimeType() { + return mimeType; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,165 @@ +package de.intevation.gnv.state; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +/** + * The default implementation of InputData. This object stores + * multiple values separated by {@link #VALUE_SEPARATOR} for a specific key. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class DefaultInputData implements InputData { + + /** + * + */ + private static final long serialVersionUID = 4308041648698108066L; + + private static final Logger logger = Logger.getLogger(DefaultInputData.class); + + /** + * The character used to separate the different values. + */ + public final static String VALUE_SEPARATOR = " , "; + + /** + * The key/name of this object. + */ + protected String name; + + /** + * Values separated by {@link #VALUE_SEPARATOR}. + */ + protected String value; + + /** + * Descriptions for values used for user interface creation. Each value + * should have an own description in this map. + */ + protected Map description; + + /** + * An extra object. Might be everything. + */ + protected Object object; + + + /** + * Constructor + */ + public DefaultInputData(String name, String value) { + this.name = name; + this.value = value; + } + + + public DefaultInputData(String name, Object object) { + this.name = name; + this.object = object; + } + + + public DefaultInputData( + String name, + String value, + Object object) + { + this.name = name; + this.object = object; + this.value = value; + } + + + public String getName() { + return this.name; + } + + + public String getValue() { + return this.value; + } + + + public void setObject(Object object) { + this.object = object; + } + + + public Object getObject() { + return object; + } + + /** + * + * @param key Key needs to be a single value of {@link #value}. + * @return the description. + */ + public String getDescription(String key) { + if (description == null) + return null; + + return (String) description.get(key); + } + + /** + * Return all descriptions as array. + * + * @return descriptions as array. + */ + public String[] getDescription() { + String[] values = splitValue(); + int length = values.length; + + String[] description = new String[length]; + for (int i = 0; i < length; i++) { + description[i] = (String) this.description.get(values[i]); + } + + return description; + } + + + public void setDescription(String[] description) { + if (this.description == null) + this.description = new HashMap(); + + String[] values = splitValue(); + + int length = values.length; + int descLength = description.length; + + for (int i = 0; i < length; i++) { + if (i < descLength) { + this.description.put(values[i], description[i]); + } + else { + break; + } + } + } + + + @Override + public String toString() { + return this.name + "==> " + this.value; + } + + + public void concartValue(String value) { + this.value = this.value + VALUE_SEPARATOR + value; + } + + + public String[] splitValue() { + if (this.value != null){ + return this.value.split(VALUE_SEPARATOR); + } + return null; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultInputValue.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,75 @@ +package de.intevation.gnv.state; + +/** + * The default implementation of InputValue. InputValue objects are + * used to store meta information about InputData objects. + * + * @author Tim Englich + */ +public class DefaultInputValue implements InputValue { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -8518824299166180986L; + private String name = null; + private String type = null; + private boolean multiselect = false; + private int usedInQueries = 1; + private String defaultValue = "N/N"; + + + public DefaultInputValue(String name, String type, String defaultValue, + boolean multiselect) { + this(name, type, multiselect, 1); + this.defaultValue = defaultValue; + + } + + + public DefaultInputValue(String name, String type, boolean multiselect, + int usedInQueries) { + this.name = name; + this.type = type; + this.multiselect = multiselect; + this.usedInQueries = usedInQueries; + } + + + public String getName() { + return this.name; + } + + + public String getType() { + return this.type; + } + + /** + * Returns the information as string. + * + * @return information as string. + */ + @Override + public String toString() { + return "InputValue " + this.name + " ==> " + this.type + + "==> multiselect: " + this.multiselect; + } + + + public boolean isMultiselect() { + return this.multiselect; + } + + + public int usedInQueries() { + return this.usedInQueries; + } + + + public String getDefaultValue() { + return this.defaultValue; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultOutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultOutputMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,94 @@ +package de.intevation.gnv.state; + +import java.util.Collection; +import java.util.List; + +/** + * The default implementation of OutputMode. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class DefaultOutputMode implements OutputMode { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -6459085460904827056L; + private String name = null; + private String description = null; + private String mimeType = null; + private Collection inputParameters = null; + private List exportModes; + + /** + * Constructor + * + * @param name The name of the output mode. + * @param description The description of this output mode. + * @param mimeType The mime type used by this output mode. + * @param inputParameters The input parameters required by this output mode. + * @param exportModes The export modes for this output mode. + */ + public DefaultOutputMode( + String name, + String description, + String mimeType, + Collection inputParameters, + List exportModes) + { + super(); + this.name = name; + this.description = description; + this.mimeType = mimeType; + this.inputParameters = inputParameters; + this.exportModes = exportModes; + } + + /** + * @return the description. + */ + public String getDescription() { + return this.description; + } + + /** + * @return the mime type. + */ + public String getMimeType() { + return this.mimeType; + } + + /** + * @return the name. + */ + public String getName() { + return this.name; + } + + /** + * @return this output mode as string. + */ + @Override + public String toString() { + return "Name: " + this.name + " ; Description: " + this.description + + " ; Mime-Type: " + this.mimeType; + } + + /** + * @return the input parameters. + */ + public Collection getInputParameters() { + return this.inputParameters; + } + + /** + * + * @return the export modes. + */ + public List getExportModes() { + return exportModes; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/DefaultState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,23 @@ +package de.intevation.gnv.state; + +/** + * This is the default implementation of StateBase. + * + * @author Tim Englich + * + */ +public class DefaultState extends StateBase { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 8934030362091576766L; + + /** + * Constructor + */ + public DefaultState() { + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/ExportMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/ExportMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,34 @@ +package de.intevation.gnv.state; + +import java.io.Serializable; + +/** + * This interface defines basic methods which are necessary for exports. + * + * @author Ingo Weinzierl + */ +public interface ExportMode +extends Serializable +{ + /** + * Return the export name (e.g. pdf, svg, image). + * + * @return the export name. + */ + public String getName(); + + /** + * Return the description for this export. + * + * @return the export description. + */ + public String getDescription(); + + /** + * Returns the mime type used by this export. + * + * @return export's mimetype. + */ + public String getMimeType(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/ExtendedInputData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/ExtendedInputData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,70 @@ +package de.intevation.gnv.state; + +/** + * This class is used to save the relation between two attributes. Mainly used + * to save the relation between a measurement and the parameter it belongs to. + * + * @see MeasurementState + * @author Ingo Weinzierl + */ +public class ExtendedInputData extends DefaultInputData { + + /** + * The separater used to separate measurement ids and parameter ids. + */ + public static final String SEPARATOR = ";"; + + /** + * The parameter this object belongs to. + */ + protected String parameterid; + + /** + * Constructcor. + * + * @param name + * @param value + * @param object + * @param parameterid + */ + public ExtendedInputData( + String name, + String value, + Object object, + String parameterid) + { + super(name, value, object); + this.parameterid = parameterid; + } + + /** + * Return the parameter ids this object belongs to. + * + * @return the parameter id. + */ + public String getParameterID() { + return parameterid; + } + + /** + * Set the parameter ids. + * + * @param parameterid Parameter ids. + */ + public void setParameter(String parameterid) { + this.parameterid = parameterid; + } + + /** + * Return all parameter ids as array. + * + * @return Array of parameter ids. + */ + public String[] splitParameter() { + if (parameterid != null) + return parameterid.split(SEPARATOR); + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/InputData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/InputData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,80 @@ +package de.intevation.gnv.state; + +import java.io.Serializable; + +/** + * This interface defines the basic methods used to store multiple values with + * a specific key and name. + * + * @author Tim Englich + * + */ +public interface InputData extends Serializable { + + /** + * Method to Retrieve the name of this input data item. + * + * @return the name + */ + public String getName(); + + /** + * Method to retrieve the value of this input data item. A value might be a + * list of values separated by a specific character. + * + * @return the value + */ + public String getValue(); + + /** + * Method to store a further object at this input data item. + * + * @param o A further object. + */ + public void setObject(Object o); + + /** + * Method to retrieve the extra object. + * + * @return the extra object. + */ + public Object getObject(); + + /** + * Method to store descriptions for this input data item. + * + * @param description Array of descriptions. + */ + public void setDescription(String[] description); + + /** + * Method to retrieve a description specified by a given key. + * + * @param key Key. + * @return the description for this key. + */ + public String getDescription(String key); + + /** + * Method to retrieve all descriptions of this input data item. + * + * @return descriptions. + */ + public String[] getDescription(); + + /** + * Append a further string value to the value field devided by a separater + * character. + * + * @param value Value to append. + */ + public void concartValue(String value); + + /** + * Method to retrieve the character separated values split into an array. + * + * @return values as array. + */ + String[] splitValue(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/InputValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/InputValue.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,50 @@ +package de.intevation.gnv.state; + +import java.io.Serializable; + +/** + * This interface defines some basic methods to retrieve information about the + * type of an user input. + * + * @author Tim Englich + * + */ +public interface InputValue extends Serializable { + + /** + * Retrieve the name of the inserted data. + * + * @return the input data name. + */ + public String getName(); + + /** + * Retrieve the type of the input. + * + * @return the input data type. + */ + public String getType(); + + /** + * Retrieve the default value used when no input is done. + * + * @return the input data default value. + */ + public String getDefaultValue(); + + /** + * Retrieve information about mutliselect fields. + * + * @return true, if the input data is a multiselect, otherwise false. + */ + public boolean isMultiselect(); + + /** + * Retrieve information about the occurance of this input in an sql + * statement. + * + * @return the number of times, this data is used in a sql query. + */ + public int usedInQueries(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,450 @@ +package de.intevation.gnv.state; + +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.state.describedata.ExtendedKeyValueData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; + +import de.intevation.gnv.state.exception.StateException; + +import de.intevation.gnv.utils.InputValidator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * This state handles input of measurements relating to a parameter. The user + * interface description created by this class represents a matrix - each + * parameter in a single row, each measurement in a column. An invalid + * measurement column for a specific parameter is marked as disabled and should + * not be selected. + * + * @author Ingo Weinzierl + */ +public class MeasurementState +extends DefaultState +{ + private static Logger logger = Logger.getLogger(MeasurementState.class); + + public static final String SQL_KEY_PARAMETERID = "PARAMETERID"; + + public static final String SEPARATOR = ";"; + + + /** + * This class is used to generate the Matrix in MinMaxDateState. + * Parameter and Measurements are stored in separate lists and can be + * requested via different methods. + * + * @author Ingo Weinzierl + */ + private class ParameterMatrix { + private final Logger logger = + Logger.getLogger(ParameterMatrix.class); + + private List measurements; + private List mDescriptions; + private List parameters; + private boolean[][] values; + + /** + * Constructs a new matrix. + * + * @param data A collection containing the measurements. + * @param parameter An array of parameters. + */ + public ParameterMatrix(Collection data, String[] parameter) { + measurements = new ArrayList(data.size()); + mDescriptions = new ArrayList(data.size()); + parameters = new ArrayList(parameter.length); + + values = new boolean[data.size()][parameter.length]; + for (int i = 0; i < data.size(); i++) { + Arrays.fill(values[i], false); + } + + initParameters(parameter); + initMeasurements(data); + } + + /** + * Initialize the measurements used in this matrix. + * + * @param data The measurements. + */ + private void initMeasurements(Collection data) { + Iterator iter = data.iterator(); + while (iter.hasNext()) { + ExtendedKeyValueData value = (ExtendedKeyValueData) iter.next(); + String key = value.getKey(); + String val = value.getValue(); + String parameter = value.getParameter(); + + int i = measurements.indexOf(key); + int j = parameters.indexOf(parameter); + int tmp = mDescriptions.indexOf(val); + + if (i < 0) { + measurements.add(key); + i = measurements.indexOf(key); + } + + if (j < 0) { + logger.warn("Not a valid parameter: " + parameter); + } + + if (tmp < 0) { + mDescriptions.add(val); + tmp = mDescriptions.indexOf(val); + } + + if (i >= 0 && i < measurements.size() && j >= 0 + && j < parameters.size()) + { + values[i][j] = true; + } + } + } + + /** + * Initialize the parameters used in this matrix. + * + * @param parameter Parameters. + */ + private void initParameters(String[] parameter) { + for (String param: parameter) { + parameters.add(param); + } + } + + /** + * Returns the number of measurements. + * + * @return the number of measurements. + */ + public int measurementSize() { + if (measurements != null) + return measurements.size(); + + return 0; + } + + /** + * Returns the number of parameters. + * + * @return number of parameters. + */ + public int parameterSize() { + if (parameters != null) + return parameters.size(); + + return 0; + } + + /** + * Returns the measurement at idx. + * + * @param idx Index. + * @return the measurement. + */ + public String getMeasurement(int idx) { + if (idx >= 0 && idx < measurements.size()) + return (String) measurements.get(idx); + + logger.warn("Index is out of bounds: " + idx); + return ""; + } + + /** + * Returns the parameter at idx. + * + * @param idx Index + * @return the parameter. + */ + public String getParameter(int idx) { + if (idx >= 0 && idx < parameters.size()) { + return (String) parameters.get(idx); + } + + logger.warn("Index is out of bounds: " + idx); + return ""; + } + + /** + * Returns a description text for a specific measurement. + * + * @param idx Index of a measurement. + * @return measurement's description. + */ + public String getMDescription(int idx) { + if (mDescriptions != null) { + return (String) mDescriptions.get(idx); + } + + return null; + } + + /** + * This method returns true, if a measurement is valid for a specific + * parameter - otherwise false. + * + * @param i Index of a measurement column. + * @param j Index of a parameter row. + * @return true, if valid, else false. + */ + public boolean isValid(int i, int j) { + if (i < 0 || i > measurements.size() + || j < 0 || j > parameters.size()) + { + logger.warn("Index out of bounds: " + i + "|" + j); + return false; + } + + return values[i][j]; + } + } // End of ParameterMatrix + + + public MeasurementState() { + super(); + } + + @Override + protected NamedCollection extractKVP( + Collection result, + String keyid, + String valueid + ) { + NamedCollection kvdd = + new NamedArrayList(dataName, result.size()); + + kvdd.setMultiSelect(true); + + int keyPos = -1; + int valPos = -1; + int parPos = -1; + + for (Result res: result) { + if (keyPos < 0 || valPos < 0 || parPos < 0) { + ResultDescriptor rd = res.getResultDescriptor(); + + keyPos = rd.getColumnIndex(keyid); + valPos = rd.getColumnIndex(valueid); + parPos = rd.getColumnIndex(SQL_KEY_PARAMETERID); + } + + kvdd.add(new ExtendedKeyValueData( + res.getString(keyPos), + res.getString(valPos), + getID(), + res.getString(parPos))); + } + + return kvdd; + } + + + /** + * This method create the user interface description for measurement and + * parameters as matrix. A row for each parameter, a column for each + * measurement. + */ + @Override + protected void appendToDynamicNode( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node dynamicNode, + CallMeta callMeta, + Object o + ) { + NamedArrayList all = (NamedArrayList) o; + String name = all.getName(); + RessourceFactory factory = RessourceFactory.getInstance(); + + Element matrixNode = creator.create("group"); + Element matrixLabel = creator.create("label"); + matrixLabel.setTextContent(factory.getRessource( + callMeta.getLanguages(), all.getName(), all.getName())); + creator.addAttr(matrixNode, "mode", "matrix"); + matrixNode.appendChild(matrixLabel); + + InputData inputParam = inputData.get("parameterid"); + ParameterMatrix matrix = new ParameterMatrix(all, inputParam.splitValue()); + + int measurements = matrix.measurementSize(); + int parameters = matrix.parameterSize(); + + for (int i = 0; i < parameters; i++) { + Element select = creator.create("select"); + String param = matrix.getParameter(i); + creator.addAttr(select, "label", inputParam.getDescription(param)); + creator.addAttr(select, "ref", name); + + for (int j = 0; j < measurements; j++) { + Element item = creator.create("item"); + Element label = creator.create("label"); + Element value = creator.create("value"); + + creator.addAttr(item, "ref", name); + creator.addAttr( + item, + "parameter", + matrix.getMDescription(j)); + + if (!matrix.isValid(j, i)) { + creator.addAttr(item, "disabled", "true"); + } + else { + creator.addAttr(item, "disabled", "false"); + } + + String tmpValue = matrix.getMeasurement(j) + ";" + param; + label.setTextContent(matrix.getMDescription(j)); + value.setTextContent(tmpValue); + + item.appendChild(label); + item.appendChild(value); + select.appendChild(item); + } + + matrixNode.appendChild(select); + } + + dynamicNode.appendChild(matrixNode); + } + + + /** + * This feed takes some input data storing measurement ids and parameter ids + * and put them into ExtendedInputData objects to save the relation between + * a measurement and the parameter it belongs to. + */ + @Override + public Document feed( + CallContext context, + Collection input, + String uuid) + throws StateException + { + RessourceFactory resFactory = RessourceFactory.getInstance(); + Locale[] serverLocales = resFactory.getLocales(); + Locale locale = context.getMeta().getPreferredLocale( + serverLocales); + + if (input == null) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_NO_INPUT, + EXCEPTION_NO_INPUT); + logger.warn(msg); + return feedFailure(msg); + } + + for(InputData item: input) { + String name = item.getName(); + InputValue inputValue = inputValues.get(name); + + String[] tupel = extractValuesAndParams(item.getValue()); + String type = inputValue.getType(); + + if (inputValue == null) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + logger.warn(msg); + return feedFailure(msg); + } + + if (!InputValidator.isInputValid(tupel[0], type)) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + logger.warn(msg); + return feedFailure(msg); + } + + if (inputData == null) { + inputData = new HashMap(); + } + + ExtendedInputData extended = new ExtendedInputData( + name, + tupel[0], + item.getObject(), + tupel[1]); + + if (name.equals(dataName)) { + String[] desc = getDescriptionForInputData(extended, uuid); + extended.setDescription(desc); + } + + inputData.put(name, extended); + } + + return feedSuccess(); + } + + + /** + * Extract parameter ids and measurement ids from DefaultInputData objects + * and return an array. In the first position of this array, the measurement + * ids are placed, in the second position the parameter ids - all separated + * by a character. + * + * @param tmp String containing measurement ids and parameter ids. + * @return An array with separated measurements and parameters. + */ + protected String[] extractValuesAndParams(String tmp) { + String[] array = tmp.split(DefaultInputData.VALUE_SEPARATOR); + + String[] extracted = new String[2]; + for (String item: array) { + String[] tupel = item.split(ExtendedInputData.SEPARATOR); + + if (extracted[0] == null) { + extracted[0] = tupel[0]; + } + else { + extracted[0] += + DefaultInputData.VALUE_SEPARATOR + tupel[0]; + } + + if (extracted[1] == null) { + extracted[1] = tupel[1]; + } + else { + extracted[1] += DefaultInputData.VALUE_SEPARATOR + tupel[1]; + } + } + + logger.debug("VALUES RESULT: " + extracted[0]); + logger.debug("PARAMS RESULT: " + extracted[1]); + + return extracted; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxDateState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxDateState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,189 @@ +package de.intevation.gnv.state; + +import java.util.Collection; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.Locale; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; + +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.geobackend.util.DateUtils; +import de.intevation.gnv.state.describedata.DefaultMinMaxDescribeData; +import de.intevation.gnv.state.describedata.DescribeData; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.InputValidator; + +/** + * This state handles date input. The resulting describe document of this state + * contains two fields in the user interface description to define a time range. + * + * @author Ingo Weinzierl + */ +public class MinMaxDateState extends MinMaxState { + + + /** + * + */ + public static final String EXCEPTION_DATE_REQUIRED = + "input.is.not.valid.date.required"; + + /** + * + */ + public static final String EXCEPTION_START_AFTER_END = + "start.date.after.end.date"; + + /** + * + */ + public static final String EXCEPTION_DATE_OUT_OF_RANGE = + "date.out.of.range"; + + /** + * + */ + public static final String EXCEPTION_MISSING_DATE = + "missing.data.field"; + + private static Logger logger = Logger.getLogger(MinMaxDateState.class); + + + /** + * + */ + public MinMaxDateState() { + super(); + } + + + /** + * This feed method needs a collection of two InputData objects. These + * objects' values need to be a datetime string which is turned into a Date + * object. Afterwards, the given dates are validated. Min and max date need + * to be in range of the min and max date retrieved by + * {@link #getDescibeData(java.lang.String)}. + */ + @Override + public Document feed( + CallContext context, + Collection inputData, + String uuid) + throws StateException { + RessourceFactory resFactory = RessourceFactory.getInstance(); + Locale[] serverLocales = resFactory.getLocales(); + Locale locale = context.getMeta().getPreferredLocale( + serverLocales); + + if (inputData == null) { + String msg = "No input data given."; + logger.warn(msg); + return feedFailure(msg); + } + + Iterator iter = inputData.iterator(); + + MinMaxDescribeData data = + (MinMaxDescribeData) getDescibeData(uuid).get(0); + Object min = data.getMinValue(); + Object max = data.getMaxValue(); + + Object tmpMin = null; + Object tmpMax = null; + + while (iter.hasNext()) { + InputData tmp = (InputData) iter.next(); + InputValue meta = inputValues.get(tmp.getName()); + String type = meta.getType(); + String value = tmp.getValue(); + String name = tmp.getName(); + + if (meta == null) { + String msg = "Input data not expected here. Data will be ignored."; + logger.warn(msg); + return feedFailure(msg); + } + + if (!InputValidator.isInputValid(value, type)) { + String msg = resFactory.getRessource( + locale, EXCEPTION_DATE_REQUIRED, EXCEPTION_DATE_REQUIRED); + logger.error(msg); + return feedFailure(msg); + } + + Date lower = null; + if (min instanceof GregorianCalendar) { + lower = ((GregorianCalendar)min).getTime(); + } + + Date upper = null; + if (max instanceof GregorianCalendar) { + upper = ((GregorianCalendar)max).getTime(); + } + + Date d = null; + try { + d = DateUtils.getDateFromString(value,DateUtils.DATE_PATTERN); + } + catch (Exception e) { + logger.warn(e, e); + } + + if (d == null || lower == null || upper == null) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_MISSING_DATE, + EXCEPTION_MISSING_DATE); + logger.warn(msg); + } + else { + if (logger.isDebugEnabled()) { + logger.debug("Date to validate: " + d.toString()); + logger.debug("Lower date bound: " + lower.toString()); + logger.debug("Upper date bound: " + upper.toString()); + } + + if (!InputValidator.isDateValid(d, lower, upper)) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_DATE_OUT_OF_RANGE, + EXCEPTION_DATE_OUT_OF_RANGE); + logger.error(msg); + return feedFailure(msg); + } + } + + if (name.equals(MINVALUEFIELDNAME)) { + tmpMin = value; + } + + if (name.equals(MAXVALUEFIELDNAME)) { + tmpMax = value; + } + + if (tmpMin != null && tmpMax != null) { + if (!InputValidator.isInputValid((String) tmpMin, (String) tmpMax, type)) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_START_AFTER_END, + EXCEPTION_START_AFTER_END); + logger.error(msg); + return feedFailure(msg); + } + } + } + + DescribeData values = new DefaultMinMaxDescribeData( + dataName, tmpMin, tmpMax, getID()); + + this.inputData.put(dataName, new DefaultInputData(dataName, values)); + + return feedSuccess(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,217 @@ +package de.intevation.gnv.state; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.util.DateUtils; +import de.intevation.gnv.state.describedata.DefaultMinMaxDescribeData; +import de.intevation.gnv.state.describedata.DescribeData; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.InputValidator; + +/** + * This state handles input of a min and max value and validates the user input. + * The min value needs to be equal or smaller than the max value, otherwise the + * input results in an error. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class MinMaxState extends StateBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(MinMaxState.class); + + /** + * Constructor + */ + public MinMaxState() { + super(); + } + + /** + * The objects returned by the database are searched for two fields with + * 'MIN' and 'MAX' as names. These objects are stored and used to be + * displayed in the gui to give the user an orientation of the range he is + * able to insert. + */ + @Override + protected List purifyResult( + Collection result, String uuid) + { + List describeData = new ArrayList(); + + if (result != null && result.size() == 1) { + Result value = result.iterator().next(); + DescribeData values = new DefaultMinMaxDescribeData( + dataName, + value.getObject("MIN"), + value.getObject("MAX"), + getID()); + describeData.add(values); + } else { + log.warn("Result cannot be handled as MinMax Resultset"); + } + + return describeData; + } + + + @Override + public Document feed( + CallContext context, + Collection inputData, + String uuid) + throws StateException { + RessourceFactory resFactory = RessourceFactory.getInstance(); + + if (inputData == null) { + String msg = "No input data given."; + log.warn(msg); + return feedFailure(msg); + } + + InputValidator iv = new InputValidator(); + Iterator iter = inputData.iterator(); + + Object min = null; + Object max = null; + + while (iter.hasNext()) { + InputData tmp = (InputData) iter.next(); + InputValue meta = inputValues.get(tmp.getName()); + String type = meta.getType(); + String value = tmp.getValue(); + String name = tmp.getName(); + + if (meta == null) { + String msg = "Input data not expected here. Data will be ignored."; + log.warn(msg); + return feedFailure(msg); + } + + boolean valid = InputValidator.isInputValid(value, type); + if (!valid) { + String msg = "Input is not valid for this state."; + log.error(msg); + return feedFailure(msg); + } + + if (name.equals(MINVALUEFIELDNAME)) { + min = value; + } + + if (name.equals(MAXVALUEFIELDNAME)) { + max = value; + } + + if (min != null && max != null) { + if (!InputValidator.isInputValid((String) min, (String) max, type)) { + String msg = "Input is not valid for this state."; + log.error(msg); + return feedFailure(msg); + } + } + } + + + + DescribeData values = new DefaultMinMaxDescribeData( + dataName, min, max, getID()); + + this.inputData.put(dataName, new DefaultInputData(dataName, values)); + + return feedSuccess(); + } + + + @Override + protected void appendToStaticNode( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node staticNode, + CallMeta callMeta + ) { + InputData data = inputData.get(dataName); + + if (data == null) { + return; + } + + MinMaxDescribeData minMax = (MinMaxDescribeData) data.getObject(); + + Object min = minMax.getMinValue(); + Object max = minMax.getMaxValue(); + if (min instanceof GregorianCalendar) { + Date d = ((GregorianCalendar) min).getTime(); + min = DateUtils.getPatternedDateAmer(d); + } + + if (max instanceof GregorianCalendar) { + Date d = ((GregorianCalendar) max).getTime(); + max = DateUtils.getPatternedDateAmer(d); + } + + Element groupNode = creator.create("group"); + artCreator.addAttr(groupNode, "state", minMax.getState(), true); + + creator.addAttr(groupNode, "ref", minMax.getName()); + Element groupNodeLableNode = creator.create("label"); + groupNodeLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), + minMax.getName(), + minMax.getName())); + groupNode.appendChild(groupNodeLableNode); + + Element inputMinNode = creator.create("input"); + creator.addAttr(inputMinNode, "ref", MINVALUEFIELDNAME); + Element inputMinLableNode = creator.create("label"); + inputMinLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), MINVALUEFIELDNAME, + MINVALUEFIELDNAME)); + inputMinNode.appendChild(inputMinLableNode); + + Element inputMinValueNode = creator.create("value"); + inputMinValueNode.setTextContent(min.toString()); + inputMinNode.appendChild(inputMinValueNode); + + Element inputMaxNode = creator.create("input"); + creator.addAttr(inputMaxNode, "ref", MAXVALUEFIELDNAME); + Element inputMaxLableNode = creator.create("label"); + inputMaxLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), MAXVALUEFIELDNAME, + MAXVALUEFIELDNAME)); + inputMaxNode.appendChild(inputMaxLableNode); + + Element inputMaxValueNode = creator.create("value"); + inputMaxValueNode.setTextContent(max.toString()); + inputMaxNode.appendChild(inputMaxValueNode); + + groupNode.appendChild(inputMinNode); + groupNode.appendChild(inputMaxNode); + + staticNode.appendChild(groupNode); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.gnv.state; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.List; + +/** + * This is the interface description of an OutputMode. The + * methods defined here retrieve some basic information for an output. An output + * can be chart, histogram, statistic, csv, odv and so on. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public interface OutputMode extends Serializable { + + /** + * Retrieve the name of this output mode. + * + * @return the name of this output mode. + */ + public String getName(); + + /** + * Retrieve the description of an output. + * + * @return the description. + */ + public String getDescription(); + + /** + * Retrieve the mimetype used for the output. + * + * @return the mimetype. + */ + public String getMimeType(); + + /** + * Retrieve a list of optional InputValue objects the user is able to + * adjust. + * + * @return optional input parameters. + */ + public Collection getInputParameters(); + + /** + * Retrieve a list of export modes this output can be exported to. + * + * @return some export modes. + */ + public List getExportModes(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +package de.intevation.gnv.state; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.state.exception.StateException; + +import java.io.OutputStream; + +import java.util.Collection; + +import org.w3c.dom.Document; + +/** + * This is the interface description of an output state. Currently, there are + * two methods defined:
+ *
    + *
  1. out(): To start an output of the current state.
  2. + *
  3. getOutputModes(): To retrieve a list of possible output modes.
  4. + *
+ * + * @author Tim Englich + */ +public interface OutputState +extends State +{ + + /** + * Returns the Rendered Result of an State. + * + * @param format + * @param inputData + * @param outputStream + * @param uuid + * @param callContext + * @throws StateException + */ + public void out( + Document format, + Collection inputData, + OutputStream outputStream, + String uuid, + CallContext callContext + ) throws StateException; + + /** + * Delivers the provided OutputModes of an State + * + * @return the provided OutputModes of an State + */ + public Collection getOutputModes(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputStateBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/OutputStateBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,489 @@ +package de.intevation.gnv.state; + +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import javax.xml.xpath.XPathConstants; + +import net.sf.ehcache.Cache; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.gnv.artifacts.cache.CacheFactory; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.InputValidator; + +/** + * This is the default implementation of OutputState. Artifacts + * having reached this state or a subclass of this state are able to produce + * some output (e.g. chart, histograms, statistic, etc). + * + * @author Tim Englich + * @author Ingo Weinzierl + * + */ +public abstract class OutputStateBase +extends StateBase +implements OutputState +{ + public static final String XPATH_OUTPUT_MODE = + "/art:action/art:out/@name"; + + public static final String XPATH_EXPORT_MODE = + "/art:action/art:out/art:export/@name"; + + public static final String XPATH_MIME_TYPE = + "/art:action/art:out/art:mime-type/@value"; + + public static final String XPATH_EXPORTS = + "exportModes/export"; + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -1718732895737303823L; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(OutputStateBase.class); + + /** + * The different Outputmodes which are provided by an OutputState + */ + protected Collection outputModes = null; + + protected String queryODVID = null; + + /** + * Constructor + */ + public OutputStateBase() { + super(); + } + + public Collection getOutputModes() { + log.debug("OutputStateBase.getOutputModes"); + return this.outputModes; + } + + + @Override + public void setup(Node configuration) { + log.debug("OutputStateBase.setup"); + super.setup(configuration); + + this.queryODVID = Config.getStringXPath(configuration,"queryID-odv"); + + NodeList outputModeList = Config.getNodeSetXPath(configuration, + "outputsModes/outputsMode"); + if (outputModeList != null) { + log.debug(outputModeList.getLength() + " were found."); + this.outputModes = new ArrayList(outputModeList + .getLength()); + for (int i = 0; i < outputModeList.getLength(); i++) { + Element currentNode = (Element)outputModeList.item(i); + String name = currentNode.getAttribute("name"); + String description =currentNode.getAttribute("description"); + String mimeType = currentNode.getAttribute("mime-type"); + NodeList inputValuesList = Config.getNodeSetXPath(currentNode, + "parameters/inputvalue"); + Collection inputParameters = null; + if (inputValuesList != null) { + inputParameters = new ArrayList(inputValuesList + .getLength()); + for (int j = 0; j < inputValuesList.getLength(); j++) { + Element currentInputValuesNode = (Element)inputValuesList.item(j); + String inputValueName = currentInputValuesNode.getAttribute("name"); + String inputValueType = currentInputValuesNode.getAttribute("type"); + String defaultValue =currentInputValuesNode.getAttribute("value"); + boolean isMultiselect = false; + InputValue inputValue = new DefaultInputValue( + inputValueName, inputValueType, defaultValue, + isMultiselect); + inputParameters.add(inputValue); + } + } + + // parse export modes + List exportList = null; + NodeList exports = (NodeList) XMLUtils.xpath( + currentNode, XPATH_EXPORTS, XPathConstants.NODESET); + + if (exports != null) { + int exportSize = exports.getLength(); + + exportList = new ArrayList(exportSize); + for (int k = 0; k < exportSize; k++) { + Element exp = (Element) exports.item(k); + String expName = exp.getAttribute("name"); + String expDesc = exp.getAttribute("description"); + String expMime = exp.getAttribute("mime-type"); + + exportList.add( + new DefaultExportMode(expName, expDesc, expMime)); + } + } + + OutputMode outputMode = new DefaultOutputMode(name, + description, mimeType, inputParameters, exportList); + log.debug(outputMode.toString()); + this.outputModes.add(outputMode); + + } + } + } + + + @Override + public void advance(String uuid, CallContext context) + throws StateException + { + } + + + @Override + public void initialize(String uuid, CallContext context) + throws StateException + { + } + + /** + * This method needs to be defined by concrete subclasses. Nothing is done + * here. + */ + public void out( + Document format, + Collection inputData, + OutputStream outputStream, + String uuid, + CallMeta callMeta + ) + throws StateException + { + } + + /** + * This method needs to be defined by concrete subclasses. Nothing is done + * here. + */ + public void out(String outputMode, Collection inputData, + OutputStream outputStream) throws StateException { + } + + /** + * Returns the data used to create charts. If a cache is configured, try to + * fetch the data from cache. The database is queried if the data is not in + * cache yet, or if no cache is configured. If the cache is configured, but + * the data is not in cache yet, put it into cache for a faster access + * in a later time. + * + * @param uuid The uuid of an artifact. + * @param callContext The CallContext. + * @return the chart data. + */ + protected Object getChartResult(String uuid, CallContext callContext) { + log.debug("OutputStateBase.getChartResult"); + CacheFactory factory = CacheFactory.getInstance(); + + if (factory.isInitialized()) { + // we use a cache + log.info("Using cache."); + Cache cache = factory.getCache(); + String key = "chart_" + getHash(); + + net.sf.ehcache.Element value = cache.get(key); + if (value != null) { + log.debug("Found element in cache."); + return value.getObjectValue(); + } + else { + log.debug("Element not in cache, we need to ask the database"); + Object result = getData(queryID); + cache.put(new net.sf.ehcache.Element(key, result)); + + return result; + } + } + else { + // we don't use a cache, so we have to query the database every + // single time + log.info("Not using a cache."); + return getData(queryID); + } + } + + /** + * This method should no longer be used, because it is not good to put a + * chart into cache. Parameter changes done by the user wouldn't be detected + * proper. + * @deprecated + */ + protected Object getChartFromCache(String uuid, CallContext callContext) { + log.debug("Fetch chart [" + uuid + "] from cache"); + CacheFactory cacheFactory = CacheFactory.getInstance(); + if (cacheFactory.isInitialized()) { + String key = "chart_" + getHash(); + net.sf.ehcache.Element object = cacheFactory.getCache().get(key); + + if (object != null) { + return object.getObjectValue(); + } + } + return null; + } + + /** + * Retrieves the data used to create an ODV export. + * + * @param uuid + * @return odv data. + */ + protected Collection getODVResult(String uuid) { + log.debug("OutputStateBase.getODVResult"); + // TODO add Caching? I think it's not nessessary + Collection returnValue = null; + if (this.queryODVID != null){ + returnValue = this.getData(this.queryODVID); + }else{ + log.warn("No Query for ODV Data is defined."); + } + return returnValue; + } + + /** + * Retrieve data from database with help of queryID. + * + * @param queryID A query id defined in sql statements properties file. + * @return some data. + */ + protected Collection getData(String queryID) { + log.debug("OutputStateBase.getData"); + Collection returnValue = null; + try { + String[] filterValues = this.generateFilterValuesFromInputData(); + try { + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + returnValue = queryExecutor.executeQuery(queryID,filterValues); + } catch (RuntimeException e) { + log.error(e, e); + } + } catch (QueryException e) { + log.error(e, e); + } + return returnValue; + } + + /** + * This method removes the data used for creating charts from cache. + * + */ + protected void removeChartResult(String uuid) { + log.debug("OutputStateBase.getChartResult"); + if (CacheFactory.getInstance().isInitialized()) { + String key = "chart_" + getHash(); + log.debug("Hash for Queryelements: " + key); + net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); + if (value != null) { + CacheFactory.getInstance().getCache().remove(key); + } + } + } + + /** + * This method should no longer be used. It removes a chart from cache. + * + * @deprecated + */ + protected void removeChart(String uuid) { + log.debug("OutputStateBase.removeChart from cache"); + + CacheFactory cacheFactory = CacheFactory.getInstance(); + if (cacheFactory.isInitialized()) { + String key = "chart_" + getHash(); + net.sf.ehcache.Element object = cacheFactory.getCache().get(key); + if (object != null) + cacheFactory.getCache().remove(key); + } + } + + /** + * This is an internal method used while database query. + */ + protected void purifyChart(Object chart, String uuid) { + log.debug("Prufify chart [" + uuid + "]"); + CacheFactory cacheFactory = CacheFactory.getInstance(); + if (cacheFactory.isInitialized()) { + String key = "chart_" + getHash(); + cacheFactory.getCache().put(new net.sf.ehcache.Element(key, chart)); + } + } + + + /** + * Use this method to feed a state with new data. + */ + @Override + public Document feed( + CallContext context, + Collection inputData, + String uuid) + throws StateException + { + putInputData(inputData, uuid); + + return feedSuccess(); + } + + /** + * This method is used to put new data into a next state. The difference + * between this method and feed is, that this method should be used to + * transfer some old input data required by this state. New data need to be + * inserted via feed! + */ + @Override + public void putInputData(Collection inputData, + String uuid) + throws StateException { + log.debug("OutputStateBase.putInputData"); + this.removeChartResult(uuid); + this.removeChart(uuid); + + if (inputData != null) { + Iterator it = inputData.iterator(); + InputValidator iv = new InputValidator(); + while (it.hasNext()) { + InputData tmpItem = it.next(); + Object tmpObj = tmpItem.getObject(); + InputValue inputValue = this.inputValues.get(tmpItem.getName()); + if (inputValue != null) { + if (this.inputData == null) { + this.inputData = new HashMap( + inputData.size()); + } + + boolean valid = InputValidator.isInputValid(tmpItem.getValue(), + inputValue.getType()); + if (valid) { + if (tmpItem.getName().equals(MINVALUEFIELDNAME)){ + String minValue = tmpItem.getValue(); + String maxValue = getInputValue4ID(inputData, MAXVALUEFIELDNAME); + valid = InputValidator.isInputValid(maxValue,inputValue.getType()); + if (!valid){ + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + valid = InputValidator.isInputValid(minValue, + maxValue, + inputValue.getType()); + if (!valid){ + String errMsg = "MaxValue-Input is less than MinValue-Input "; + log.warn(errMsg); + throw new StateException(errMsg); + } + }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){ + String minValue = getInputValue4ID(inputData, MINVALUEFIELDNAME); + String maxValue = tmpItem.getValue(); + valid = InputValidator.isInputValid(minValue,inputValue.getType()); + if (!valid){ + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + valid = InputValidator.isInputValid(minValue, + maxValue, + inputValue.getType()); + if (!valid){ + String errMsg = "MaxValue-Input is less than MinValue-Input "; + log.warn(errMsg); + throw new StateException(errMsg); + } + } + this.inputData.put(tmpItem.getName(), tmpItem); + } else { + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + } + else if (tmpObj != null && tmpObj instanceof MinMaxDescribeData) { + MinMaxDescribeData data = (MinMaxDescribeData) tmpObj; + if (this.inputData == null) { + this.inputData = new HashMap(inputData.size()); + } + this.inputData.put(tmpItem.getName(), tmpItem); + this.inputData.put("minvalue", new DefaultInputData("minvalue", (String) data.getMinValue())); + this.inputData.put("maxvalue", new DefaultInputData("maxvalue", (String) data.getMaxValue())); + } + else { + + String errMsg = "No Inputvalue given for Inputdata " + + tmpItem.getName(); + log.warn(errMsg + "Value will be ignored"); + + } + } + } else { + log.warn("No Inputdata given"); + } + setHash(uuid); + } + + + public void out( + String outputMode, + Collection inputData, + OutputStream outputStream, + String uuid, + CallMeta callMeta) + throws StateException { } + + + /** + * Retrieves a message from resource bundle specified by locale. + * + * @param locale Locale to use. + * @param key The key of the message. + * @param value The default value. + * @return The value. + */ + protected String getMessage(Locale locale, String key, String value) { + return RessourceFactory.getInstance().getRessource( + locale, + key, + value + ); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/PreSettingsTransferCoordinateSelectionState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/PreSettingsTransferCoordinateSelectionState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,81 @@ +package de.intevation.gnv.state; + +import de.intevation.artifactdatabase.Config; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.state.exception.StateException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * This method looks for former inserted coordinates before initialization. + * + * @author Tim Englich + */ +public class PreSettingsTransferCoordinateSelectionState extends CoordinateSelectionState { + + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -3972304838976884048L; + + private String transferPreSettingsName = null; + + private String transferInputDataname = null; + /** + * Constructor + */ + public PreSettingsTransferCoordinateSelectionState() { + super(); + } + + + /** + * Lookup mechanism for former inserted data before intialization begins. + * + * @param uuid + * @param context + * @throws StateException + */ + @Override + public void initialize(String uuid, CallContext context) + throws StateException { + Map preSettings = this.getPreSettings(); + if (preSettings != null){ + InputData ip = preSettings.get(transferPreSettingsName); + if (ip != null){ + Collection localInputdata = new ArrayList(1); + localInputdata.add(new DefaultInputData(transferInputDataname, + ip.getValue())); + this.putInputData(localInputdata, uuid); + } + } + + super.initialize(uuid, context); + } + + + /** + * + * @param configuration + */ + @Override + public void setup(Node configuration) { + + Element preSettingsNode = (Element)Config.getNodeXPath(configuration, + "presettings-transfer"); + if (preSettingsNode != null){ + this.transferPreSettingsName = preSettingsNode.getAttribute("presetting"); + this.transferInputDataname = preSettingsNode.getAttribute("inputvalue"); + } + super.setup(configuration); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/PreSettingsTransferState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/PreSettingsTransferState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,83 @@ +package de.intevation.gnv.state; + +import de.intevation.artifactdatabase.Config; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.state.exception.StateException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * This special state does a lookup for already inserted data while + * initializing. If there are some data for this state, take them for further + * work. + * + * @author Tim Englich + */ +public class PreSettingsTransferState extends DefaultState { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 573381812690806922L; + + private String transferPreSettingsName = null; + + private String transferInputDataname = null; + /** + * Constructor + */ + public PreSettingsTransferState() { + super(); + } + + + /** + * This method does a lookup for already inserted data before initializing + * it. + * + * @param uuid + * @param context + * @throws StateException + */ + @Override + public void initialize(String uuid, CallContext context) + throws StateException { + Map preSettings = this.getPreSettings(); + if (preSettings != null){ + InputData ip = preSettings.get(transferPreSettingsName); + if (ip != null){ + Collection localInputdata = new ArrayList(1); + localInputdata.add(new DefaultInputData(transferInputDataname, + ip.getValue())); + this.putInputData(localInputdata, uuid); + } + } + + super.initialize(uuid, context); + } + + + /** + * + * @param configuration + */ + @Override + public void setup(Node configuration) { + + Element preSettingsNode = (Element)Config.getNodeXPath(configuration, + "presettings-transfer"); + if (preSettingsNode != null){ + this.transferPreSettingsName = preSettingsNode.getAttribute("presetting"); + this.transferInputDataname = preSettingsNode.getAttribute("inputvalue"); + } + super.setup(configuration); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/SingleInputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/SingleInputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,121 @@ +package de.intevation.gnv.state; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.state.describedata.DefaultSingleValueDescribeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.InputValidator; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * This state handles single user input. The user is allowed to select just one + * value. + * + * @author Tim Englich + * + */ +public class SingleInputState extends StateBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(SingleInputState.class); + + private static final long serialVersionUID = -6169497306324917318L; + + /** + * Constructor + */ + public SingleInputState() { + } + + + @Override + protected List purifyResult(Collection result, String uuid) { + log.debug("SingleInputState.purifyResult"); + List describeData = new ArrayList(); + + String value = null; + if (result != null && result.size() == 1) { + Result tmpItem = result.iterator().next(); + value = tmpItem.getObject("MAX").toString(); + } else { + value = ""; + } + + describeData.add(new DefaultSingleValueDescribeData( + this.dataName, value, getID())); + + return describeData; + } + + /** + * This feed method needs a collection of two InputData objects. These + * objects' values need to be a datetime string which is turned into a Date + * object. Afterwards, the given dates are validated. Min and max date need + * to be in range of the min and max date retrieved by + * {@link #getDescibeData(java.lang.String)}. + */ + @Override + public Document feed( + CallContext context, + Collection inputData, + String uuid) + throws StateException { + RessourceFactory resFactory = RessourceFactory.getInstance(); + Locale[] serverLocales = resFactory.getLocales(); + Locale locale = context.getMeta().getPreferredLocale( + serverLocales); + + if (inputData == null) { + String msg = "No input data given."; + log.warn(msg); + return feedFailure(msg); + } + + Iterator it = inputData.iterator(); + InputData tmpItem = it.next(); + InputValue inputValue = inputValues.get(tmpItem.getName()); + + if (inputValue == null) { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + log.warn(msg); + return feedFailure(msg); + } + + boolean valid = InputValidator.isInputValid( + tmpItem.getValue(), inputValue.getType()); + + if (valid) { + String[] desc = getDescriptionForInputData(tmpItem, uuid); + tmpItem.setDescription(desc); + + this.inputData.put(tmpItem.getName(), tmpItem); + return feedSuccess(); + } + + else { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + log.warn(msg); + return feedFailure(msg); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,182 @@ +package de.intevation.gnv.state; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.state.exception.StateException; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.Map; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +/** + * This interface describes the basic method a concrete state class needs to + * implement. + * + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public interface State extends Serializable { + + /** + * Setup the state. + * + * @param configuration State configuration. + */ + public void setup(Node configuration); + + /** + * Return the id of the state. + * + * @return the id. + */ + public String getID(); + + /** + * Return the description of the state. + * + * @return the description of the state. + */ + public String getDescription(); + + /** + * This method is called when an artifacts retrieves a describe request. It + * creates the user interface description of the current state. + * + * @param document Describe doucment. + * @param rootNode Parent node for all new xml elements. + * @param context The CallContext. + * @param uuid The uuid of an artifact. + */ + public void describe( + Document document, + Node rootNode, + CallContext context, + String uuid + ); + + /** + * This method is used to insert new data into this state. Concrete + * subclasses should valide the input before saving it. + * + * @param context The CallContext. + * @param inputData New InputData items. + * @param uuid The uuid of an artifact. + * @return a document with an error or sucess message. + * @throws StateException + */ + public Document feed( + CallContext context, Collection inputData, String uuid) + throws StateException; + + /** + * Set the previous state. + * + * @param state The previous state. + */ + public void setParent(State state); + + /** + * Returns the previous state. + * + * @return the previous state. + */ + public State getParent(); + + /** + * Retrieve a collection of required input values. + * + * @return required input values. + */ + public Collection getRequiredInputValues(); + + /** + * Retrieves a map with InputData items. + * + * @return a map with InputData items. + */ + public Map inputData(); + + /** + * Use this method to feed a state with some data. + * + * @param inputData InputData collection. + * @param uuid UUID of an artifact. + * @throws StateException + */ + public void putInputData(Collection inputData, String uuid) + throws StateException; + + /** + * Retrieves a collection with the InputData stored in this state. + * + * @return An InputData collection. + * @throws StateException + */ + public Collection getInputData() throws StateException; + + /** + * This method is called to advance to a next or previous state. + * + * @param uuid The uuid of an artifact. + * @param context The CallContext object. + * @throws StateException + */ + public void advance(String uuid, CallContext context) + throws StateException; + + /** + * This method is called when the state is created. + * + * @param uuid The uuid of an artifact. + * @param context The CallContext object. + * @throws StateException + */ + public void initialize(String uuid, CallContext context) + throws StateException; + + /** + * This method can be used to reset the state. + * + * @param uuid The uuid of an artifact. + */ + public void reset(String uuid); + + /** + * This method is called when the lifetime of an artifact ends or if the + * user decides to step back to a previous state. + * + * @param globalContext The CallContext. + */ + public void endOfLife(Object globalContext); + + /** + * This method is used to put some InputData objects into an artifact before + * the parameterization begins. + * + * @param preSettings + */ + public void setPreSettings(Map preSettings); + + /** + * This method retrieves a map with InputData objects which have been + * inserted into this state before the parameterization has started. The key + * used to store the objects is the name of the state. + * + * @return map with InputData objects. + */ + public Map getPreSettings(); + + /** + * Method to remove the data stored at a state which should not be + * serialized while an artifact is exported. + * + * @param context The CallContext + */ + public void cleanup(Object context); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1052 @@ +package de.intevation.gnv.state; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.xml.xpath.XPathConstants; + +import net.sf.ehcache.Cache; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.gnv.artifacts.cache.CacheFactory; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.geobackend.util.DateUtils; +import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; +import de.intevation.gnv.state.describedata.SingleValueDescribeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.ArtifactXMLUtilities; +import de.intevation.gnv.utils.InputValidator; + +/** + * This is the major implementation of State. Nearly every other + * state is derived by this class. + * + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public abstract class StateBase implements State { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 2411169179001645426L; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(StateBase.class); + + protected final static String MINVALUEFIELDNAME = "minvalue"; + + protected final static String MAXVALUEFIELDNAME = "maxvalue"; + + private final static String NODATASELECTIONKEY = "n/n"; + + public final static String DESCRIBEDATAKEY = "_DESCRIBEDATA"; + + public final static String XPATH_STATIC_UI = "art:static"; + + public final static String XPATH_DYNAMIC_UI = "art:dynamic"; + + public static final String EXCEPTION_NO_INPUT = "no.input.data"; + + public static final String EXCEPTION_INVALID_INPUT = + "input.is.not.valid"; + + public final static String HASH_ID_SEPARATOR = "#"; + + /** input value names which should not be rendered from State itself */ + public final static String[] BLACKLIST = {"sourceid", "fisname"}; + + private String id = null; + + protected String hash; + + private String description = null; + + protected String dataName = null; + + protected String preSettingsName = null; + + protected boolean dataMultiSelect = false; + + protected boolean dataNoSelect = false; + + protected String queryID = null; + + protected Collection inputValueNames = null; + + protected Map inputValues = null; + + protected State parent = null; + + protected Map inputData = null; + + protected Map preSettings = null; + + + /** + * The source date format as string. + */ + public static String srcDateFormat = "yyyy.MM.dd hh:mm:ss"; + + + /** + * The source date format used to read string represented strings. + */ + public static DateFormat srcFormat; + + + static { + srcFormat = new SimpleDateFormat(srcDateFormat); + } + + + /** + * Constructor + */ + public StateBase() { + super(); + } + + + public String getID() { + return this.id; + } + + + public String getDescription() { + return this.description; + } + + + public Collection getRequiredInputValues() { + return this.inputValues.values(); + } + + + public void reset(String uuid) { + inputData.remove(dataName); + } + + + public void setup(Node configuration) { + this.id = ((Element)configuration).getAttribute("id"); + this.description = ((Element)configuration).getAttribute("description"); + + log.info("State-ID = " + this.id); + + NodeList inputValuesNodes = Config.getNodeSetXPath(configuration, + "inputvalues/inputvalue"); + this.inputValues = new HashMap(inputValuesNodes + .getLength()); + this.inputValueNames = new ArrayList(inputValuesNodes + .getLength()); + for (int i = 0; i < inputValuesNodes.getLength(); i++) { + Element inputValueNode = (Element)inputValuesNodes.item(i); + String usedinQueryValue = inputValueNode.getAttribute("usedinquery"); + int usedinQuery = 1; + if (usedinQueryValue != null) { + try { + usedinQuery = Integer.parseInt(usedinQueryValue); + } catch (NumberFormatException e) { + log + .warn("Used in Query Value cannot be transformed into a Number"); + } + } + InputValue inputValue = new DefaultInputValue(inputValueNode.getAttribute("name"), + inputValueNode.getAttribute("type"), + Boolean.parseBoolean(inputValueNode. + getAttribute("multiselect")), usedinQuery); + this.inputValues.put(inputValue.getName(), inputValue); + this.inputValueNames.add(inputValue.getName()); + } + + this.queryID = Config.getStringXPath(configuration, "queryID"); + log.info("QueryID ==> " + this.queryID); + + this.dataName = Config.getStringXPath(configuration, "dataname"); + + String dataMultiSelectValue = Config.getStringXPath(configuration, + "data-multiselect"); + if (dataMultiSelectValue != null) { + this.dataMultiSelect = Boolean.parseBoolean(dataMultiSelectValue); + } + + String dataNoSelectValue =Config.getStringXPath(configuration, + "data-noselect"); + if (dataNoSelectValue != null) { + this. dataNoSelect = Boolean.parseBoolean(dataNoSelectValue); + } + + this.preSettingsName = Config.getStringXPath(configuration, "presettings-name"); + + } + + + public State getParent() { + return this.parent; + } + + + public void setParent(State state) { + this.parent = state; + } + + + public Document feed( + CallContext context, + Collection inputData, + String uuid) + throws StateException + { + RessourceFactory resFactory = RessourceFactory.getInstance(); + Locale[] serverLocales = resFactory.getLocales(); + Locale locale = context.getMeta().getPreferredLocale( + serverLocales); + + if (inputData != null) { + Iterator it = inputData.iterator(); + InputValidator iv = new InputValidator(); + while (it.hasNext()) { + InputData tmpItem = it.next(); + InputValue inputValue = this.inputValues.get(tmpItem.getName()); + if (inputValue != null) { + if (this.inputData == null) { + this.inputData = new HashMap( + inputData.size()); + } + + boolean valid = InputValidator.isInputValid(tmpItem.getValue(), + inputValue.getType()); + if (valid) { + + if (tmpItem.getName().equals(this.dataName)){ + String[] desc = getDescriptionForInputData(tmpItem, uuid); + tmpItem.setDescription(desc); + } + this.inputData.put(tmpItem.getName(), tmpItem); + } else { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + log.warn(msg); + return feedFailure(msg); + } + + } else { + String msg = resFactory.getRessource( + locale, + EXCEPTION_INVALID_INPUT, + EXCEPTION_INVALID_INPUT); + log.warn(msg); + return feedFailure(msg); + + } + } + + return feedSuccess(); + } else { + String msg = resFactory.getRessource( + locale, + EXCEPTION_NO_INPUT, + EXCEPTION_NO_INPUT); + log.warn(msg); + return feedFailure(msg); + } + } + + + protected Document feedSuccess() { + return ArtifactXMLUtilities.createSuccessReport( + "Initialize success", XMLUtils.newDocument()); + } + + + protected Document feedFailure(String msg) { + return ArtifactXMLUtilities.createInputExceptionReport( + msg, XMLUtils.newDocument()); + } + + + protected String[] getDescriptionForInputData(InputData data, String uuid) { + // there is only one element in the list, so take the first + Object obj = getDescibeData(uuid).get(0); + List descs = new ArrayList(); + + if (obj instanceof NamedArrayList) { + NamedArrayList list = (NamedArrayList) obj; + List selected = Arrays.asList(data.splitValue()); + int size = list.size(); + + for (int i = 0; i < size; i++) { + KeyValueDescibeData kv = (KeyValueDescibeData) list.get(i); + + // values are concatinated in InputData, so one InputData object can + // contain many input + String key = kv.getKey(); + int idx = selected.indexOf(key); + if (idx >= 0) { + descs.add(kv.getValue()); + + // XXX Workarround: I just wanted to remove the element at + // 'idx' from selected, but for any reason this is not + // possible (throws an exception) (iw) + List tmp = new ArrayList(); + for (int j = 0; j < selected.size(); j++) { + if (j != idx) + tmp.add(selected.get(j)); + } + + selected = tmp; + } + } + } + + return (String[]) descs.toArray(new String[descs.size()]); + } + + + public void putInputData(Collection inputData, String uuid) + throws StateException { + if (inputData != null) { + Iterator it = inputData.iterator(); + InputValidator iv = new InputValidator(); + while (it.hasNext()) { + InputData tmpItem = it.next(); + InputValue inputValue = this.inputValues.get(tmpItem.getName()); + if (inputValue != null) { + if (this.inputData == null) { + this.inputData = new HashMap( + inputData.size()); + } + + boolean valid = InputValidator.isInputValid(tmpItem.getValue(), + inputValue.getType()); + if (valid) { + if (tmpItem.getName().equals(MINVALUEFIELDNAME)){ + String minValue = tmpItem.getValue(); + String maxValue = this.getInputValue4ID(inputData, MAXVALUEFIELDNAME); + valid = InputValidator.isInputValid(maxValue,inputValue.getType()); + if (!valid){ + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + valid = InputValidator.isInputValid(minValue, + maxValue, + inputValue.getType()); + if (!valid){ + String errMsg = "MaxValue-Input is less than MinValue-Input "; + log.warn(errMsg); + throw new StateException(errMsg); + } + }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){ + String minValue = this.getInputValue4ID(inputData, MINVALUEFIELDNAME); + String maxValue = tmpItem.getValue(); + valid = InputValidator.isInputValid(minValue,inputValue.getType()); + if (!valid){ + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + valid = InputValidator.isInputValid(minValue, + maxValue, + inputValue.getType()); + if (!valid){ + String errMsg = "MaxValue-Input is less than MinValue-Input "; + log.warn(errMsg); + throw new StateException(errMsg); + } + } + this.inputData.put(tmpItem.getName(), tmpItem); + } else { + String errMsg = "Wrong input for " + tmpItem.getValue() + + " is not an " + inputValue.getType() + + " Value."; + log.warn(errMsg); + throw new StateException(errMsg); + } + + } else { + String errMsg = "No Inputvalue given for Inputdata " + + tmpItem.getName(); + log.warn(errMsg + "Value will be ignored"); + + } + } + } else { + log.warn("No Inputdata given"); + } + + setHash(uuid); + } + + + public void setPreSettings(Map preSettings) { + this.preSettings = preSettings; + } + + + public Map getPreSettings() { + return this.preSettings; + } + + + protected String getInputValue4ID(Collection inputData, String inputName){ + Iterator it = inputData.iterator(); + while (it.hasNext()) { + InputData tmpItem = it.next(); + if (tmpItem.getName().equals(inputName)){ + return tmpItem.getValue(); + } + } + return null; + } + + + public void advance(String uuid, CallContext context) + throws StateException + { + } + + + public void initialize(String uuid, CallContext context) + throws StateException + { + } + + + protected String[] generateFilterValuesFromInputData() { + List list = new ArrayList(); + Iterator it = this.inputValueNames.iterator(); + while (it.hasNext()) { + String value = it.next(); + InputData data = this.inputData.get(value); + if (data != null + && this.inputValues.containsKey(data.getName())) { + int size = this.inputValues.get(data.getName()) + .usedInQueries(); + String type = this.inputValues.get(data.getName()) + .getType(); + String requestValue = data.getValue(); + if (type.equalsIgnoreCase("string")) { + requestValue = this + .prepareInputData4DBQuery(requestValue); + } else if (type.equalsIgnoreCase("date")) { + requestValue = this + .prepareInputData4DateDBQuery(requestValue); + } else if (type.equalsIgnoreCase("coordinate") || (type.equalsIgnoreCase("geometry") && requestValue.toLowerCase().startsWith("point"))){ + requestValue = this + .prepareInputData4RegionDBQuery(requestValue); + } + for (int j = 0; j < size; j++) { + list.add(requestValue); + } + } + } + String[] filterValues = list.toArray(new String[list.size()]); + return filterValues; + } + + + protected String prepareInputData4RegionDBQuery(String value){ + return value; + } + + private String prepareInputData4DateDBQuery(String value) { + if (value != null) { + String[] values = value.split(","); + String newValue = ""; + for (int i = 0; i < values.length; i++) { + if (newValue.length() > 0) { + newValue = newValue + " , "; + } + // TODO JUST HACK FIND A BETTER RESOLUTION + newValue = newValue + "to_date('" + values[i].trim() + + "', 'YYYY.MM.DD HH24:MI:SS')"; + } + return newValue; + } + + return value; + } + + private String prepareInputData4DBQuery(String value) { + if (value != null) { + String[] values = value.split(","); + String newValue = ""; + for (int i = 0; i < values.length; i++) { + if (newValue.length() > 0) { + newValue = newValue + " , "; + } + newValue = newValue + "'" + values[i].trim() + "'"; + } + return newValue; + } + + return value; + + } + + + protected List purifyResult(Collection result, String uuid) { + List describeData = new ArrayList(); + + NamedCollection keyValueDescibeData = + extractKVP(result, "KEY", "VALUE"); + + describeData.add(keyValueDescibeData); + + return describeData; + } + + + protected NamedCollection extractKVP(Collection result, + String keyid, + String valueid) { + Iterator rit = result.iterator(); + int dataSize = (this.dataNoSelect ? result.size()+1 : result.size()); + + NamedCollection keyValueDescibeData = new NamedArrayList( + this.dataName, dataSize); + keyValueDescibeData.setMultiSelect(this.dataMultiSelect); + + if (this.dataNoSelect){ + keyValueDescibeData.add(new DefaultKeyValueDescribeData( + NODATASELECTIONKEY, + "No Selection", + getID() + )); + } + + boolean initialized = false; + int keyPos = 0; + int valuePos = 1; + String previousKey = null; + InputData preSettingsData = + (this.preSettings != null && this.preSettingsName != null) + ? this.preSettings.get(this.preSettingsName) + : null; + boolean filterWithPresettings = preSettingsData != null; + + List preSettingValues = null; + if(filterWithPresettings){ + preSettingValues = Arrays.asList(preSettingsData.splitValue()); + } + while (rit.hasNext()) { + Result resultValue = rit.next(); + if (!initialized){ + keyPos = resultValue.getResultDescriptor().getColumnIndex(keyid); + valuePos = resultValue.getResultDescriptor().getColumnIndex(valueid); + if (valuePos < 0){ + valuePos = 1; + } + initialized = true; + } + String tmpKey = resultValue.getString(keyPos); + + // TODO: FIXME: We have to do that because the arcsde does not + // support a distinct Query on Layers. + if (previousKey == null || !tmpKey.equals(previousKey)){ + previousKey = tmpKey; + if (!filterWithPresettings || preSettingValues.contains(tmpKey)){ + keyValueDescibeData.add( + new DefaultKeyValueDescribeData( + tmpKey, + resultValue.getString(valuePos), + getID()) + ); + } + } + } + return keyValueDescibeData; + } + + + public static boolean inBlackList(String key) { + int length = BLACKLIST.length; + for (int i = 0; i < length; i++) { + if (BLACKLIST[i].equals(key)) { + return true; + } + } + + return false; + } + + + public void describe( + Document document, + Node rootNode, + CallContext context, + String uuid) + { + XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator( + document, + XMLUtils.XFORM_URL, + XMLUtils.XFORM_PREFIX + ); + + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX + ); + + // append dynamic node + Node dynamic = (Node) XMLUtils.xpath( + rootNode, + XPATH_DYNAMIC_UI, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE + ); + + describeDynamic( + creator, xCreator, document, dynamic, context, uuid); + + // append static nodes + Node staticNode = (Node) XMLUtils.xpath( + rootNode, + XPATH_STATIC_UI, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE + ); + + State parent = getParent(); + if (parent != null && parent instanceof StateBase) { + ((StateBase) parent).describeStatic( + creator,xCreator, document, staticNode, context,uuid); + } + } + + + protected void describeDynamic( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node dynamic, + CallContext context, + String uuid) + { + CallMeta callMeta = context.getMeta(); + + if (dataName == null) + return; + + List descibeData = getDescibeData(uuid); + if (descibeData != null) { + Iterator it = descibeData.iterator(); + + while (it.hasNext()) { + Object o = it.next(); + if ((!it.hasNext() && dataName != null)) { + appendToDynamicNode( + artCreator, creator, document, dynamic, callMeta, o); + } + } + } + } + + + protected void describeStatic( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node staticNode, + CallContext context, + String uuid) + { + State parent = getParent(); + if (parent != null && parent instanceof StateBase) { + ((StateBase) parent).describeStatic( + artCreator, creator, document, staticNode, context, uuid); + } + + CallMeta callMeta = context.getMeta(); + appendToStaticNode(artCreator, creator, document, staticNode, callMeta); + } + + + protected void appendToStaticNode( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node staticNode, + CallMeta callMeta + ) { + InputData data = inputData.get(dataName); + + if (data == null) { + return; + } + + Element selectNode = creator.create("select1"); + creator.addAttr(selectNode, "ref", dataName); + + Element lableNode = creator.create("label"); + lableNode.setTextContent(RessourceFactory.getInstance() + .getRessource(callMeta.getLanguages(), dataName, dataName)); + Element choiceNode = creator.create("choices"); + + artCreator.addAttr( + selectNode, "state", getID(), true + ); + + String[] descriptions = data.getDescription(); + int size = descriptions.length; + + for (int i = 0; i < size; i++) { + Element itemNode = creator.create("item"); + String value = data.getValue(); + String desc = descriptions[i]; + desc = desc == null ? value : desc; + + creator.addAttr(itemNode, "selected", "true"); + + Element choiceLableNode = creator.create("label"); + choiceLableNode.setTextContent(desc); + itemNode.appendChild(choiceLableNode); + + Element choiceValueNode = creator.create("value"); + choiceValueNode.setTextContent(value); + itemNode.appendChild(choiceValueNode); + choiceNode.appendChild(itemNode); + } + + selectNode.appendChild(lableNode); + selectNode.appendChild(choiceNode); + + staticNode.appendChild(selectNode); + } + + + protected void appendToDynamicNode( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node dynamicNode, + CallMeta callMeta, + Object o + ) { + if (o instanceof Collection) { + String name = null; + boolean multiselect = false; + if (o instanceof NamedCollection) { + NamedCollection nc = ((NamedCollection) o); + name = nc.getName(); + multiselect = nc.isMultiSelect(); + } else { + Object[] names = this.inputValueNames.toArray(); + name = names[names.length - 1].toString(); + } + + Element selectNode = creator.create(multiselect?"select":"select1"); + creator.addAttr(selectNode, "ref", name); + + Element lableNode = creator.create("label"); + lableNode.setTextContent(RessourceFactory.getInstance() + .getRessource(callMeta.getLanguages(), name, name)); + Element choiceNode = creator.create("choices"); + + Collection values = (Collection) o; + Iterator resultIt = values.iterator(); + while (resultIt.hasNext()) { + KeyValueDescibeData result = resultIt.next(); + Element itemNode = creator.create("item"); + + if (result.isSelected()) { + itemNode.setAttribute("selected", "true"); + } + + Element choiceLableNode = creator.create("label"); + choiceLableNode.setTextContent(result.getValue()); + itemNode.appendChild(choiceLableNode); + + Element choicValueNode = creator.create("value"); + choicValueNode.setTextContent("" + result.getKey()); + itemNode.appendChild(choicValueNode); + choiceNode.appendChild(itemNode); + } + selectNode.appendChild(lableNode); + selectNode.appendChild(choiceNode); + + dynamicNode.appendChild(selectNode); + } + else if (o instanceof MinMaxDescribeData) { + appendMinMaxDescribeData( + artCreator, + creator, + document, + dynamicNode, + callMeta, + o); + } + else if (o instanceof SingleValueDescribeData) { + appendSingleValueDescribeData( + artCreator, + creator, + document, + dynamicNode, + callMeta, + o); + } + } + + + protected void appendMinMaxDescribeData( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node node, + CallMeta callMeta, + Object o + ) { + MinMaxDescribeData minMaxDescibeData = (MinMaxDescribeData) o; + Object min = minMaxDescibeData.getMinValue(); + Object max = minMaxDescibeData.getMaxValue(); + if (min instanceof GregorianCalendar) { + Date d = ((GregorianCalendar) min).getTime(); + min = DateUtils.getPatternedDateAmer(d); + } + + if (max instanceof GregorianCalendar) { + Date d = ((GregorianCalendar) max).getTime(); + max = DateUtils.getPatternedDateAmer(d); + } + + Element groupNode = creator.create("group"); + artCreator.addAttr(groupNode, "state", minMaxDescibeData.getState(), true); + + creator.addAttr(groupNode, "ref", minMaxDescibeData.getName()); + Element groupNodeLableNode = creator.create("label"); + groupNodeLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), + minMaxDescibeData.getName(), + minMaxDescibeData.getName())); + groupNode.appendChild(groupNodeLableNode); + + Element inputMinNode = creator.create("input"); + creator.addAttr(inputMinNode, "ref", MINVALUEFIELDNAME); + Element inputMinLableNode = creator.create("label"); + inputMinLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), MINVALUEFIELDNAME, + MINVALUEFIELDNAME)); + inputMinNode.appendChild(inputMinLableNode); + + Element inputMinValueNode = creator.create("value"); + inputMinValueNode.setTextContent(min.toString()); + inputMinNode.appendChild(inputMinValueNode); + + Element inputMaxNode = creator.create("input"); + creator.addAttr(inputMaxNode, "ref", MAXVALUEFIELDNAME); + Element inputMaxLableNode = creator.create("label"); + inputMaxLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), MAXVALUEFIELDNAME, + MAXVALUEFIELDNAME)); + inputMaxNode.appendChild(inputMaxLableNode); + + Element inputMaxValueNode = creator.create("value"); + inputMaxValueNode.setTextContent(max.toString()); + inputMaxNode.appendChild(inputMaxValueNode); + + groupNode.appendChild(inputMinNode); + groupNode.appendChild(inputMaxNode); + + node.appendChild(groupNode); + } + + + protected void appendSingleValueDescribeData( + XMLUtils.ElementCreator artCreator, + XMLUtils.ElementCreator creator, + Document document, + Node node, + CallMeta callMeta, + Object o + ) { + SingleValueDescribeData svdb = (SingleValueDescribeData) o; + + Element groupNode = creator.create("group"); + artCreator.addAttr(groupNode, "state", svdb.getState(), true); + creator.addAttr(groupNode, "ref", svdb.getName()); + + Element groupNodeLableNode = creator.create("label"); + groupNodeLableNode.setTextContent(RessourceFactory + .getInstance().getRessource( + callMeta.getLanguages(), + svdb.getName(), + svdb.getName())); + groupNode.appendChild(groupNodeLableNode); + + Element inputNode = creator.create("input"); + creator.addAttr(inputNode, "ref", svdb.getName()); + + Element inputLableNode = creator.create("label"); + inputLableNode.setTextContent(""); + inputNode.appendChild(inputLableNode); + + Element inputValueNode = creator.create("value"); + inputValueNode.setTextContent(svdb.getValue()); + inputNode.appendChild(inputValueNode); + + groupNode.appendChild(inputNode); + + node.appendChild(groupNode); + } + + + protected void setHash(String uuid) { + this.hash = uuid + + HASH_ID_SEPARATOR + + id + + HASH_ID_SEPARATOR + + inputData.hashCode(); + } + + + protected String getHash() { + return this.hash; + } + + + public List getDescibeData(String uuid) { + CacheFactory factory = CacheFactory.getInstance(); + if (factory.isInitialized()) { + // we use a cache + log.debug("Using cache."); + Cache cache = factory.getCache(); + String key = getHash(); + + net.sf.ehcache.Element value = cache.get(key); + if (value != null) { + // element already in cache, so return it. + log.debug("Found element in cache."); + return (List) (value.getObjectValue()); + } + else { + // element is not in cache yet, so we need to fetch data from + // database and put it into cache right now + log.debug("Element not in cache, we need to ask the database"); + try { + String[] filterValues = generateFilterValuesFromInputData(); + List data = queryDatabase(filterValues, uuid); + + cache.put(new net.sf.ehcache.Element(key, data)); + return data; + } + catch (QueryException qe) { + log.error(qe, qe); + } + } + } + else { + // we don't use a cache, so we have to query the database every + // single time + log.debug("Not using cache."); + String[] filterValues = generateFilterValuesFromInputData(); + Collection result = null; + try { + return queryDatabase(filterValues, uuid); + } + catch (RuntimeException e) { + log.error(e, e); + } + catch (QueryException e) { + log.error(e, e); + } + } + + return null; + } + + + protected List queryDatabase(String[] filterValues, String uuid) + throws QueryException { + Collection result = null; + + if (queryID != null) { + QueryExecutor queryExecutor = + QueryExecutorFactory.getInstance().getQueryExecutor(); + + result = queryExecutor.executeQuery(queryID, filterValues); + } + return purifyResult(result, uuid); + } + + + + public Map inputData() { + return inputData; + } + + + public Collection getInputData() throws StateException { + return this.inputData != null ? this.inputData.values() : null; + } + + + public InputData getInputDataByName(String name) { + State state = this; + + while (state != null) { + InputData data = state.inputData().get(name); + if (data != null) { + return data; + } + + state = state.getParent(); + } + + return null; + } + + + public void endOfLife(Object globalContext) { + } + + + public void cleanup(Object context) { + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/StateFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.gnv.state; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + +/** + * This factory should be used to create new state objects with help of a + * configuration segment. + * + * @author Tim Englich + * + */ +public class StateFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactBase.class); + + private static StateFactory instance = null; + + /** + * Constructor + */ + public StateFactory() { + super(); + } + + /** + * Return the instance of this class. + */ + public static StateFactory getInstance() { + if (instance == null) { + instance = new StateFactory(); + } + return instance; + } + + /** + * This method creates a new state with help of the information in + * configuration and calls its setup method after creation. + * + * @return the new state. + */ + public State createState(Node configuration) { + log.debug("StateFactory.createState"); + State state = null; + try { + String classname = ((org.w3c.dom.Element)configuration).getAttribute("state"); + state = (State) (Class.forName(classname).newInstance()); + state.setup(configuration); + } catch (InstantiationException e) { + log.error(e, e); + } catch (IllegalAccessException e) { + log.error(e, e); + } catch (ClassNotFoundException e) { + log.error(e, e); + } + return state; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/cache/QueryObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/cache/QueryObject.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +/** + * + */ +package de.intevation.gnv.state.cache; +/** + * @author Tim Englich + * + */ +public class QueryObject { + + /** + * The Id of the State the Query belongs to + */ + private String stateId = null; + + /** + * The Query which belongs to the State + */ + private String query = null; + + /** + * Constructor + * @param stateId the Id of the State the Query belongs to + * @param query the Query which belongs to the State + */ + public QueryObject(String stateId, String query) { + this.stateId = stateId; + this.query = query.toUpperCase(); + } + + /** + * Returns the StateId + * @return the Stateid + */ + public String getStateId() { + return stateId; + } + + /** + * Returns the Querystring + * @return the QueryString + */ + public String getQuery() { + return query; + } + + /** + * Returns true if the given Name of the Table is Contained in the Query + * @param tableName the Name of the Table + * @return true if the Name of the Table is contained in the Query + */ + public boolean queryContainsTableName(String tableName){ + return this.query.contains(tableName); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/cache/ThematicDataCacheCleaner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/cache/ThematicDataCacheCleaner.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,237 @@ +/** + * + */ +package de.intevation.gnv.state.cache; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import net.sf.ehcache.Cache; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import de.intevation.artifactdatabase.Config; +import de.intevation.gnv.artifacts.cache.CacheFactory; +import de.intevation.gnv.geobackend.base.query.cache.CacheCleaner; +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.state.StateBase; +import de.intevation.gnv.utils.ArtifactXMLUtilities; + + +/** + * Extended Class of the CacheCleaner. + * This Cleaner has the job to cleanup the ThematicData-Cache if it + * is necessary. + * @author Tim Englich + * + */ +public class ThematicDataCacheCleaner extends CacheCleaner { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ThematicDataCacheCleaner.class); + + private final static String XPATH_ARTIFACTS = + "/artifact-database/artifacts/artifact"; + private final static String XPATH_STATES = "states/state"; + private final static String XPATH_STATEID = "id"; + private final static String XPATH_QUERYID = "queryID"; + + /** + * The Queries that should be Cleaned with its links to the + * StateIds. + */ + private Collection queryObjects = null; + + /** + * Constructor + */ + public ThematicDataCacheCleaner() { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + */ + public ThematicDataCacheCleaner(Runnable arg0) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + */ + public ThematicDataCacheCleaner(String arg0) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public ThematicDataCacheCleaner(ThreadGroup arg0, Runnable arg1) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public ThematicDataCacheCleaner(ThreadGroup arg0, String arg1) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public ThematicDataCacheCleaner(Runnable arg0, String arg1) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + * @param arg2 + */ + public ThematicDataCacheCleaner(ThreadGroup arg0, Runnable arg1, String arg2) { + this.setUp(); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + * @param arg2 + * @param arg3 + */ + public ThematicDataCacheCleaner(ThreadGroup arg0, Runnable arg1, + String arg2, long arg3) { + this.setUp(); + } + + /** + * Initializes the QueryObjects. + * The Queryobjects will be read from the Configuration. + * Only Queries which are defined in queryID-Elements + * are used. + * The other Queries are currently not put into the Cache. + */ + @Override + protected void setUp(){ + super.setUp(); + this.queryObjects = new ArrayList(); + Document configuration = Config.getConfig(); + NodeList artifactList = Config.getNodeSetXPath(configuration, + XPATH_ARTIFACTS); + log.debug("ThematicDataCacheCleaner.setUp()"); + if (artifactList != null && artifactList.getLength() > 0){ + for (int i = 0; i < artifactList.getLength(); i++){ + Element currentArtifactNode = (Element)artifactList.item(i); + + String link = currentArtifactNode.getAttribute("xlink:href"); + if (link != null && link.length() > 0){ + String absolutFileName = Config.replaceConfigDir(link); + currentArtifactNode = (Element)new ArtifactXMLUtilities() + .readConfiguration(absolutFileName); + } + NodeList stateList = Config.getNodeSetXPath(currentArtifactNode, + XPATH_STATES); + if (stateList != null && stateList.getLength() > 0){ + for (int j = 0; j < stateList.getLength() ; j++){ + Element currentStateNode = (Element)stateList.item(j); + String stateId = currentStateNode + .getAttribute(XPATH_STATEID); + String queryID = Config.getStringXPath(currentStateNode, + XPATH_QUERYID); + try { + if (queryID != null){ + String query = QueryContainerFactory + .getInstance() + .getQueryContainer() + .getQuery(queryID); + QueryObject qo = new QueryObject(stateId, query); + queryObjects.add(qo); + } + } catch (QueryContainerException e) { + log.error(e,e); + } + } + } + } + } + } + + @Override + protected void cleanup() { + log.debug("ThematicDataCacheCleaner.cleanup"); + try { + if (queryObjects != null && queryObjects.size() > 0){ + String[] tableNames = this.getUpdatedTableNames(); + if (tableNames != null && tableNames.length > 0){ + Iterator it = queryObjects.iterator(); + while (it.hasNext()){ + QueryObject qo = it.next(); + for (int i = 0; i < tableNames.length; i++){ + if (qo.queryContainsTableName(tableNames[i])){ + String stateId = qo.getStateId(); + this.cleanUpCache(stateId); + break; + } + } + } + }else{ + log.debug("No Tables found to cleanup."); + } + }else{ + log.warn("No Queries to clean"); + } + } catch (QueryException e) { + log.error(e,e); + } + } + + /** + * Removes the Entries which Keys matches to the stateId + * from the Cache. + * @param stateId The Id of the State which Entries has to be removed. + */ + private void cleanUpCache(String stateId){ + log.debug("ThematicDataCacheCleaner.cleanUpCache "+stateId); + CacheFactory factory = CacheFactory.getInstance(); + Cache cache = factory.getCache(); + List keys = cache.getKeys(); + String keySample = StateBase.HASH_ID_SEPARATOR + + stateId + + StateBase.HASH_ID_SEPARATOR; + if (keys != null && keys.size() > 0){ + Iterator it = keys.iterator(); + while (it.hasNext()){ + String key = it.next(); + if (key != null && key.contains(keySample)){ + boolean removed = cache.remove(key); + if (!removed){ + log.warn("Object with Key " + + key + "could not be removed from Cache"); + }else{ + log.debug("Object with Key " + + key + "has been removed from Cache"); + } + } + } + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultKeyValueDescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultKeyValueDescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,67 @@ +package de.intevation.gnv.state.describedata; + +/** + * This is the default implementation of KeyValueDescibeData. This + * class just implements the necessary methods and two constructors. + * + * @author Tim Englich + */ +public class DefaultKeyValueDescribeData implements KeyValueDescibeData { + + private static final long serialVersionUID = -924469415242703108L; + + private String key; + + private String value = null; + + private String state; + + private boolean selected = false; + + /** + * Creates a new instance of this class with a key-value pair, but no state + * and no selection. + * + * @param key The key. + * @param value A value. + */ + public DefaultKeyValueDescribeData(String key, String value) { + this(key, value, null); + } + + /** + * Creates a new instance of this class with a key-value pair and the state + * this object belongs to. + * + * @param key The key. + * @param value A value. + * @param state A state. + */ + public DefaultKeyValueDescribeData(String key, String value, String state) { + super(); + this.key = key; + this.value = value; + this.state = state; + } + + public String getKey() { + return this.key; + } + + public String getValue() { + return this.value; + } + + public boolean isSelected() { + return this.selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + public String getState() { + return this.state; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultMinMaxDescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultMinMaxDescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,86 @@ +package de.intevation.gnv.state.describedata; + +/** + * @author Tim Englich + */ +public class DefaultMinMaxDescribeData implements MinMaxDescribeData { + + private static final long serialVersionUID = -2917176219029052295L; + + private Object minValue = null; + + private Object maxValue = null; + + private String name = null; + + private String state = null; + + private final static String minName = "minvalue"; + + private final static String maxName = "maxvalue"; + + /** + * The default constructor. + * + * @param name A general name for this object. + * @param minValue The min value. + * @param maxValue The max value. + * @param state The state. + */ + public DefaultMinMaxDescribeData( + String name, + Object minValue, + Object maxValue, + String state + ) { + super(); + this.name = name; + this.minValue = minValue; + this.maxValue = maxValue; + this.state = state; + } + + public Object getMaxValue() { + return this.maxValue; + } + + public Object getMinValue() { + return this.minValue; + } + + /** + * Returns the string representation of this object. + * + * @return this object as string. + */ + @Override + public String toString() { + return "MIN: " + this.minValue.toString() + " ; MAX: " + + this.maxValue.toString(); + } + + public String getMinName() { + return minName; + } + + public String getMaxName() { + return maxName; + } + + public void setMaxValue(Object maxValue) { + this.maxValue = maxValue; + } + + public void setMinValue(Object minValue) { + this.minValue = minValue; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultSingleValueDescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DefaultSingleValueDescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,63 @@ +package de.intevation.gnv.state.describedata; + +/** + * This is the default implementation of SingleValueDescribeData. + * This object is used to store a single value for a specific name. + * + * @author Tim Englich + */ +public class DefaultSingleValueDescribeData implements SingleValueDescribeData { + + private static final long serialVersionUID = 3580176842483316917L; + + private String name = null; + + private String value = null; + + private String state = null; + + /** + * Constructor to create new objects without a specific state. + * + * @param name The name of this object. + * @param value The value of this object. + */ + public DefaultSingleValueDescribeData(String name, String value) { + this(name, value, null); + } + + /** + * Constructor to create new objects with a specific state. + * + * @param name The name of this object. + * @param value The value of this object. + * @param state The state this object belongs to. + */ + public DefaultSingleValueDescribeData( + String name, + String value, + String state + ) { + super(); + this.name = name; + this.value = value; + this.state = state; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getState() { + return this.state; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/DescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,14 @@ +package de.intevation.gnv.state.describedata; + +import java.io.Serializable; + +/** + * Markerinterface + * + * @author Tim Englich + * + */ +public interface DescribeData extends Serializable { + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/ExtendedKeyValueData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/ExtendedKeyValueData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.gnv.state.describedata; + +import org.apache.log4j.Logger; + +/** + * This implementation improves the DefaultKeyValueDescribeData and + * establishes another field to store a further parameter. + * + * @author Ingo Weinzierl + */ +public class ExtendedKeyValueData +extends DefaultKeyValueDescribeData +{ + private static Logger logger = Logger.getLogger(ExtendedKeyValueData.class); + + /** + * A further parameter to be stored at this object. + */ + protected String parameter; + + /** + * Default constructor to initialize new objects. + * + * @param key The key. + * @param value The value. + * @param state The state - null permitted. + * @param parameter A further value. + */ + public ExtendedKeyValueData( + String key, String value, String state, String parameter) + { + super(key, value, state); + this.parameter = parameter; + } + + /** + * Returns the parameter. + * + * @return the parameter. + */ + public String getParameter() { + return parameter; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/KeyValueDescibeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/KeyValueDescibeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,50 @@ +package de.intevation.gnv.state.describedata; + +import java.io.Serializable; + +/** + * This interface defines some methods to retrieve a key-value pair, a state + * this data belongs to and a boolean property, if this data have been selected. + * + * @author Tim Englich + */ +public interface KeyValueDescibeData extends Serializable { + + /** + * Returns the key of this data object. + * + * @return the key. + */ + public String getKey(); + + /** + * Returns the value of this data object. + * + * @return the value. + */ + public String getValue(); + + /** + * Returns the state of this data object. + * + * @return the state. + */ + public String getState(); + + /** + * Returns a boolean which defines, if this data pair has been selected or + * not. + * + * @return true, if this pair has been selected - otherwise false. + */ + public boolean isSelected(); + + /** + * Method to change the selection of this data object. + * + * @param selected Set this value to true, if you want to select this data + * object - set it to false, if you want to unselect it. + */ + public void setSelected(boolean selected); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/MinMaxDescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/MinMaxDescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,67 @@ +package de.intevation.gnv.state.describedata; + +/** + * This interface describes some methods to set and retrieve a min-max value + * pair with a specific name. + * + * @author Tim Englich + */ +public interface MinMaxDescribeData extends DescribeData { + + /** + * Returns the min value stored in this object. + * + * @return the min value. + */ + public Object getMinValue(); + + /** + * Returns the max value stored in this object. + * + * @return the max value. + */ + public Object getMaxValue(); + + /** + * Sets the min value in this object. + * + * @param minValue A new min value. + */ + public void setMinValue(Object minValue); + + /** + * Sets the max value in this object. + * + * @param maxValue A new max value. + */ + public void setMaxValue(Object maxValue); + + /** + * Returns the general name of this object. + * + * @return the name. + */ + public String getName(); + + /** + * Returns the name of the min value. + * + * @return the name of the min value. + */ + public String getMinName(); + + /** + * Returns the name of this max value. + * + * @return the name of the max value. + */ + public String getMaxName(); + + /** + * Returns the state this object belongs to. + * + * @return the state. + */ + public String getState(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/NamedArrayList.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/NamedArrayList.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,66 @@ +package de.intevation.gnv.state.describedata; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * This is the default implementation of NamedCollection. + * + * @param The type which the objects stored in this object are from. + * @author Tim Englich + */ +public class NamedArrayList extends ArrayList implements + NamedCollection { + /** + * + */ + private static final long serialVersionUID = 8172229594749676354L; + + private String name = null; + + private boolean multiSelect = false; + + /** + * Constructor + * + * @param name The name of this collection. + */ + public NamedArrayList(String name) { + this.name = name; + } + + /** + * Constructor + * + * @param name The name of this collection. + * @param initialCapacity The initial capacity of this collection. + */ + public NamedArrayList(String name, int initialCapacity) { + super(initialCapacity); + this.name = name; + } + + /** + * Constructor + * + * @param name The name of this collection. + * @param c the collection whose elements are to be placed into this list. + */ + public NamedArrayList(String name, Collection c) { + super(c); + this.name = name; + } + + public String getName() { + return this.name; + } + + public boolean isMultiSelect() { + return multiSelect; + } + + public void setMultiSelect(boolean multiSelect) { + this.multiSelect = multiSelect; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/NamedCollection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/NamedCollection.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.gnv.state.describedata; + +import java.util.Collection; + +/** + * This interface describes some methods to retrieve the name of this + * Collection and to determine if this Collection is a + * single or multiselect object. + * + * @param The objects in this class need to be of this type. + * @author Tim Englich + * + */ +public interface NamedCollection extends Collection { + + /** + * Returns the name of this Collection. + * + * @return the name. + */ + public String getName(); + + /** + * Determines if this Collection is a multi select object. + * + * @return true, if it is multi select, otherwise false. + */ + public boolean isMultiSelect(); + + /** + * Change between single and multiselect. + * + * @param multiSelect true, if this object should be a multiselect, + * otherwise false. + */ + public void setMultiSelect(boolean multiSelect); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/SingleValueDescribeData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/SingleValueDescribeData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,38 @@ +package de.intevation.gnv.state.describedata; + +/** + * This interface defines some methods to store and retrieve key-value pairs. + * + * @author Tim Englich + */ +public interface SingleValueDescribeData extends DescribeData { + + /** + * Returns the name of this object. + * + * @return the name. + */ + public String getName(); + + /** + * Returns the value stored in this object. + * + * @return the value. + */ + public String getValue(); + + /** + * Sets the value of this object to value. + * + * @param value A new value. + */ + public void setValue(String value); + + /** + * Returns the state this objects belongs to. + * + * @return the state. + */ + public String getState(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/describedata/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Classes and interfaces to handle user input. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/exception/StateException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/exception/StateException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,50 @@ +package de.intevation.gnv.state.exception; + +/** + * @author Tim Englich + * + */ +public class StateException extends Exception { + + /** + * The UID of the Class + */ + private static final long serialVersionUID = -1635921702746050244L; + + /** + * Constructor + */ + public StateException() { + super(); + } + + /** + * Constructor + * + * @param message + */ + public StateException(String message) { + super(message); + } + + /** + * Constructor + * + * @param cause + */ + public StateException(Throwable cause) { + super(cause); + } + + /** + * Constructor + * + * @param message + * @param cause + */ + public StateException(String message, Throwable cause) { + super(message, cause); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Exception classes to be thrown if error occur in state objects. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/LayerMetaData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/LayerMetaData.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,106 @@ +/** + * + */ +package de.intevation.gnv.state.layer; +/** + * Beanclass for storing Metainformation to create Shapefiles or Layer + * in an WMS-Output. + * @author Tim Englich + * + */ +public class LayerMetaData { + + private String table = null; + private String geometryType = null; + private String where = null; + private String columns = null; + private String templateID = null; + private String[] queryValues = null; + private String geometryWKT = null; + + /** + * Constructor + * @param table the Name of the Databasetable the Data should be fetched from. + * @param geometryType the Geometrytype of the Layer + * @param where the Query-Statement which should be used to fetch the Data. + * @param columns the Columnnames which should be fetched to generate the + * Shapefile + * @param templateID the Id of the Template which should be used to create + * the Mapfileentry. + * @param queryValues the Values that should be used to Query the data + * @param geometryWKT The Geometry represented by as an WKT to Query the Data. + */ + public LayerMetaData(String table, String geometryType, String where, + String columns, String templateID, + String[] queryValues,String geometryWKT) { + super(); + this.table = table; + this.geometryType = geometryType; + this.where = where; + this.columns = columns; + this.templateID = templateID; + this.queryValues = queryValues; + this.geometryWKT = geometryWKT; + } + + /** + * Returns the Geometry WKT + * @return the Geometry WKT + */ + public String getGeometryWKT() { + return geometryWKT; + } + + /** + * Returns the Name of the Databasetable the Data should be fetched from. + * @return the Name of the Databasetable the Data should be fetched from. + */ + public String getTable() { + return table; + } + + /** + * Returns the Geometrytype of the Layer. + * @return the Geometrytype of the Layer. + */ + public String getGeometryType() { + return geometryType; + } + + /** + * Returns the Query-Statement which should be used to fetch the Data. + * @return the Query-Statement which should be used to fetch the Data. + */ + public String getWhere() { + return where; + } + + /** + * Returns the Columnnames which should be fetched to generate the + * Shapefile + * @return the Columnnames which should be fetched to generate the + * Shapefile + */ + public String getColumns() { + return columns; + } + + /** + * Returns the Id of the Template which should be used to create + * the Mapfileentry. + * @return the Id of the Template which should be used to create + * the Mapfileentry. + */ + public String getTemplateID() { + return templateID; + } + + /** + * Returns the Values that should be used to Query the data. + * @return the Values that should be used to Query the data. + */ + public String[] getQueryValues() { + return queryValues; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,774 @@ +package de.intevation.gnv.state.layer; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.OutputStateBase; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.ArtifactXMLUtilities; +import de.intevation.gnv.utils.ExclusiveExec; +import de.intevation.gnv.utils.FileUtils; +import de.intevation.gnv.utils.MapfileGenerator; +import de.intevation.gnv.utils.MetaWriter; +import de.intevation.gnv.utils.ShapeFileWriter; + +/** + * This OutputState is used for Layer-Products. + * @author Tim Englich + * + */ +public class LayerOutputState extends OutputStateBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(LayerOutputState.class); + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 9180957321704424049L; + + /** + * The Basename of the Templates for the WMS-Exports + */ + public static final String LAYER_MODEL = "layer"; + + /** + * The Name of the Shapefile which will be generated. + */ + public static final String SHAPEFILE_NAME = "data"; + + /** + * The ID for the Query fetching the Layer from the DB + */ + private String dataQueryID = null; + + /** + * The ID for the Query fetching the Geometry from the DB + * which should be used to Clip the Layerdata + */ + private String geometryQueryID = null; + + /** + * The ID of the Query for fetching the Columnnames of the Table which + * should put into the Shapefile. + */ + private String columnQueryID = null; + + /** + * The ID of the Query for fetching the Information which kind of Geometry + * should be put into the Shapefile. + */ + private String geometryTypeQueryID = null; + + /** + * The ID for the Value which will hold the Geometry-Value + */ + private String geometryID = null; + + /** + * Flag for synchronized Access of the Shapefile. + */ + private Boolean shapeFileLock = new Boolean(true); + + /** + * The Path where the Shapefile is stored. + */ + private String shapeFilePath; + + /** + * Constructor + */ + public LayerOutputState() { + super(); + } + + public void out(Document format, Collection inputData, + OutputStream outputStream, String uuid, + CallContext callContext) throws StateException { + log.debug("LayerOutputState.out"); + String outputMode = XMLUtils.xpathString( + format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); + if (outputMode.equalsIgnoreCase("wms")) { + + Collection layerMetaData = + this.getRequestedLayerMetadata(); + if (layerMetaData != null && !layerMetaData.isEmpty()){ + XMLUtils.toStream(this.getWMS(uuid, callContext, + layerMetaData,inputData), + outputStream); + }else{ + this.writeExceptionReport2Stream(outputStream); + } + }else if (outputMode.equalsIgnoreCase("zip")){ + Collection layerMetaData = + this.getRequestedLayerMetadata(); + + if (layerMetaData != null && !layerMetaData.isEmpty()){ + this.writeZip(uuid, callContext, + outputStream, layerMetaData); + }else{ + this.writeExceptionReport2Stream(outputStream); + } + + } + } + + /** + * Writes an exception to an output stream. + * + * @param outputStream The output stream used to write the exception to. + */ + private void writeExceptionReport2Stream(OutputStream outputStream) { + Document document = XMLUtils.newDocument(); + ArtifactXMLUtilities. + createExceptionReport("No Data to Export", document); + XMLUtils.toStream(document,outputStream); + } + + /** + * Returns the Metadata for the requested Layers for fetching the data + * of the Layer and generating the Layer and WMS. + * @return the Metadata for the requested Layers + */ + private Collection getRequestedLayerMetadata(){ + log.debug("LayerOutputState.getRequestedLayerMetadata"); + Collection result = this.getData(this.queryID); + Collection returnValue = null; + if (result != null){ + QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() + .getQueryExecutor(); + Iterator it = result.iterator(); + returnValue = new ArrayList(result.size()); + while (it.hasNext()){ + Result resultValue = it.next(); + String table = resultValue.getString(0); + String geometryType = this.getGeometryType(table, queryExecutor); + String where = resultValue.getString(1); + String columns = this.fetchColumns(table); + String templateID = resultValue.getString(2); + String[] queryValues = null; + String geometryWKT = null; + if (this.geometryID != null){ + InputData geometryInputData = + this.inputData.get(this.geometryID); + if (geometryInputData != null){ + try { + + Collection geometryData = queryExecutor + .executeQuery(this.geometryQueryID, + new String[]{geometryInputData.getValue()}); + Iterator git = geometryData.iterator(); + if (git.hasNext()){ + Result geometryValue = git.next(); + geometryWKT = geometryValue.getString(0); + } + } catch (QueryException e) { + log.error(e,e); + } + queryValues = new String[]{columns, + table, + where, + geometryWKT}; + }else{ + //Look into the presetting for an WKT + InputData geometryWKTData = this.preSettings != null ? + this.preSettings.get("geometry") : + null ; + if (geometryWKTData != null){ + queryValues = new String[]{columns, + table, + where, + geometryWKTData.getValue()}; + }else{ + queryValues = new String[]{columns,table,where}; + } + } + }else{ + //Look into the presetting for an WKT + InputData geometryWKTData = this.preSettings != null ? + this.preSettings.get("geometry") : + null ; + if (geometryWKTData != null){ + queryValues = new String[]{columns, + table, + where, + geometryWKTData.getValue()}; + }else{ + queryValues = new String[]{columns,table,where}; + } + } + returnValue.add(new LayerMetaData(table, geometryType, + where, columns, + templateID, queryValues, + geometryWKT)); + } + } + return returnValue; + } + + /** + * Fetches the Data from the Databasebackend. + * + * @return the resultdata. + */ + protected Collection fetchData(LayerMetaData layerMetaData){ + log.debug("LayerOutputState.fetchData"); + Collection data = null; + QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() + .getQueryExecutor(); + try { + data = queryExecutor.executeQuery(dataQueryID, + layerMetaData.getQueryValues()); + if (data != null && layerMetaData.getGeometryWKT() != null){ + WKTReader wktReader = new WKTReader(); + Geometry border = wktReader.read(layerMetaData.getGeometryWKT()); + Iterator dataIt = data.iterator(); + while (dataIt.hasNext()){ + // Trim the Geometries using the + // Geometry if one is available. + Result current = dataIt.next(); + String currentWKT = current.getString(0); + Geometry currentGeometry = null; + try { + currentGeometry = wktReader.read(currentWKT); + } catch (Exception e) { + log.error("Error parsing Geometry "+ currentWKT); + log.error(e,e); + } + if (currentGeometry != null){ + Geometry newGeometry = currentGeometry.intersection(border); + current.addColumnValue(0, newGeometry.toText()); + } + } + } + } catch (QueryException e) { + log.error(e,e); + } catch (ParseException e){ + log.error(e,e); + } + return data; + } + + + /** + * This method determines the geometry type on basis of a table name. + * + * @param tableName Name of the table in the database. + * @param queryExecutor The QueryExecutor. + * @return the geometry type as string (e.g. MultiPolygon, Polygon, etc). + */ + private String getGeometryType(String tableName, + QueryExecutor queryExecutor){ + String returnValue = null; + String[] tables = tableName.toUpperCase().split(","); + String[] filter = tables[0].split("\\."); + try { + Collection result = + queryExecutor.executeQuery(this.geometryTypeQueryID, filter); + if (result != null && !result.isEmpty()) + { + int geometryCode = result.iterator().next().getInteger(0); + if (geometryCode == 11 || + geometryCode == 10){ + returnValue = "MultiPolygon"; + }else if (geometryCode == 9 || + geometryCode == 8){ + returnValue = "MultiLineString"; + }else if (geometryCode == 7){ + returnValue = "MultiPoint"; + }else if (geometryCode == 6){ + returnValue = "GeometryCollection"; + }else if (geometryCode == 5 || + geometryCode == 4){ + returnValue = "Polygon"; + }else if (geometryCode == 3 || + geometryCode == 2){ + returnValue = "LineString"; + }else if (geometryCode == 1){ + returnValue = "Point"; + }else if (geometryCode == 0){ + returnValue = "Geometry"; + } + } + } catch (QueryException e) { + log.error(e,e); + } + return returnValue; + } + + + /** + * Fetch the columns of a specific table. + * + * @param tableName The name of the table. + * @return the columns as string. + */ + private String fetchColumns(String tableName){ + String returnValue = null; + try { + String[] tables = tableName.toUpperCase().split(","); + String[] filter = tables[0].split("\\."); + // Only use the first Table the second one will be ignored. + QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() + .getQueryExecutor(); + Collection columnData = queryExecutor. + executeQuery(this.columnQueryID, + filter); + if (columnData != null && !columnData.isEmpty()){ + StringBuffer sb = new StringBuffer(); + synchronized (sb) { + Iterator it = columnData.iterator(); + while(it.hasNext()){ + Result current = it.next(); + sb.append(current.getString(0)); + if (it.hasNext()){ + sb.append(" , "); + } + } + } + returnValue = sb.toString(); + } + } catch (QueryException e) { + log.error(e,e); + } + return returnValue; + } + + + @Override + public void setup(Node configuration) { + log.debug("LayerOutputState.setup"); + super.setup(configuration); + this.dataQueryID = Config.getStringXPath(configuration, + "queryID-layerdata"); + this.geometryID = Config.getStringXPath(configuration, + "inputvalue-geometry"); + this.geometryQueryID = Config.getStringXPath(configuration, + "queryID-geometry"); + + this.columnQueryID = "layer_colums"; //Config.getStringXPath(configuration, + // "queryID-columns"); + this.geometryTypeQueryID = "geometry_type"; + } + + + /** + * Write the resultdata to shapefiles. + * + * @param uuid The UUID of the current artifact. + * @param data The finalized data used for shapefile creation. + * @param callContext The CallContext object. + * @param geometryType The geometry type. + * @return the shapefile path. + */ + protected String writeToShapeFile( + String uuid, + Collection data, + CallContext callContext, + String geometryType, + int layerNumber + ) { + boolean success = false; + if (data != null && !data.isEmpty()){ + File shapeDir = new File(shapeFilePath); + try { + File shapeFile = new File(shapeDir, createShapeFileName(layerNumber)); + if (!ShapeFileWriter.writeDataToFile(shapeFile, "data", data,geometryType)){ + log.error("writing data into shapefile failed"); + return null; + } + success = true; + callContext.afterCall(CallContext.STORE); + return shapeFilePath; + } + finally { + if (!success) { + FileUtils.deleteRecursive(shapeDir); + } + } + }else{ + return null; + } + } + + /** + * Check if the ShapeDir exists and if it exists delete all Contents + * in it. If it not exists the Director will be created. + * @param baseDir the BaseDirectory for all ShapeDirs + * @param uuid the UUID which is used to create the Directory + * @return true if the directory exists or could be created. + * false if the directory could not be created. + */ + private boolean createShapeDir(File baseDir, String uuid){ + File shapeDir = new File(baseDir, uuid); + boolean createdDir = false; + synchronized (shapeFileLock) { + if (shapeDir.exists()) { + FileUtils.deleteContent(shapeDir); // TODO Place on getZip and getWMS + } + else if (!shapeDir.mkdirs()) { + log.error("cannot create directory '" + + shapeDir.getAbsolutePath() + "'"); + return false; + } + createdDir = true; + } + shapeFilePath = shapeDir.getAbsolutePath(); + return createdDir; + } + + /** + * Create a zip archive with the shapefiles of the given shapefiles path and + * write it to output. + * + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @param output The output stream. + * @param data The data to be written to shapefile. + * @param geometryType The geometry type. + * @throws StateException if an error occured while zipfile creation. + */ + protected void writeZip( + String uuid, + CallContext callContext, + OutputStream output, + Collection layerMetaData + ) + throws StateException + { + try { + String p = getShapeFilePath(); + if (p != null) { + File dir = new File(p); + if (dir.isDirectory()) { + FileUtils.createZipArchive(dir, output); + } + } + else { + File baseDir = shapefileDirectory(callContext); + if (!this.createShapeDir(baseDir, uuid)){ + return; + } + Iterator it = layerMetaData.iterator(); + int i = 1; + while(it.hasNext()){ + LayerMetaData lmd = it.next(); + Collection data = this.fetchData(lmd); + p = writeToShapeFile(uuid, data, callContext,lmd.getGeometryType(),i++); + } + if (p != null) { + FileUtils.createZipArchive(new File(p), output); + } + } + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + } + + /** + * Returns the shapefile path. + * + * @return the shapefile path. + */ + public String getShapeFilePath() { + synchronized (shapeFileLock) { + return shapeFilePath; + } + } + + /** + * Returns the basic-directory where the Shapefiles should be placed in. + * @param callContext the Context of this Call + * @return the Directory where the Shapefiles could be placed in. + * (Please create an own directory in this dir and not put the + * Files directly in it) + */ + private static File shapefileDirectory(CallContext callContext) { + // Code was taken from HorizontalCrossSectionMeshOutputState + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + File dir = (File)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY); + return dir != null + ? dir + : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH; + } + + + @Override + public void endOfLife(Object globalContext) { + super.endOfLife(globalContext); + // do it in background + new Thread() { + @Override + public void run() { + String path = resetShapeFilePath(); + if (path == null) { + return; + } + File dir = new File(path); + for (int i = 0; i < 10; ++i) { + if (!dir.exists() || FileUtils.deleteRecursive(dir)) { + MapfileGenerator.getInstance().update(); + return; + } + try { + Thread.sleep(10000L); + } + catch (InterruptedException ie) { + } + } + + log.error("failed to remove directory '" + path + "'"); + } // run + }.start(); + } + + /** + * Resets the Settings e.g shapeFilePath and templateID + * @return + */ + private String resetShapeFilePath() { + synchronized (shapeFileLock) { + String path = shapeFilePath; + shapeFilePath = null; + return path; + } + } + + + /** + * Write data to shapefiles and feed a map service with information about + * these shapefiles. The map service can be queried for displaying + * corresponding layers as WMS. + * + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @param layerMetaData The Metadata which is required to create the + * different Layers. + * @param inputData the Parameters which are send by the out-Call. + * @return a document with some meta information (shapefile path, geometry + * type, time to live of the current artifact, etc). + * @throws StateException if an error occured while shapefile writing. + */ + protected Document getWMS(String uuid, + CallContext callContext, + Collection layerMetaData, + Collection inputData) + throws StateException + { + String path = getShapeFilePath(); + if (path != null && new File(path).isDirectory()){ + return this.refreshMetaFile(layerMetaData, inputData, + uuid, callContext); + }else{ + Document document = XMLUtils.newDocument(); + if (this.shapeFilePath == null){ + File baseDir = shapefileDirectory(callContext); + if (!this.createShapeDir(baseDir, uuid)){ + // TODO Insert Error Report + return document; + } + } + path = getShapeFilePath(); + Iterator it = layerMetaData.iterator(); + Node meta = null; + int layerNumber = 0; + while (it.hasNext()){ + LayerMetaData lmd = it.next(); + layerNumber ++; + String geometryType = lmd.getGeometryType(); + String templateId = lmd.getTemplateID(); + ExclusiveExec.UniqueKey key = ExclusiveExec.INSTANCE.acquire(uuid); + try{ + Collection data = this.fetchData(lmd); + if (data != null && + (this.writeToShapeFile(uuid, data, callContext, + geometryType,layerNumber)) != null) { + String paramType = findParameterTitle(geometryType,templateId); + String title = getLayerTitle(inputData); + if (title == null) { + title = uuid+"_"+layerNumber; + }else{ + title = title+"_"+layerNumber; + } + if (meta == null){ + meta = MetaWriter.writeLayerMeta(callContext,document); + } + MetaWriter.writeLayerMeta(callContext, document, + meta, uuid, paramType, + this.determineGeometryType(geometryType), + createShapeFileName(layerNumber), + title); + } + if (meta != null && !it.hasNext()) { + MetaWriter.writeMetaFile(path,document); + MapfileGenerator.getInstance().update(); + return document; + } + }finally{ + ExclusiveExec.INSTANCE.release(key); + } + } + return document; + } + } + + /** + * Creates the name of the Shapefile + * @param layerNumber the Number of the Layer + * @return the create name of the Shapefile. + */ + private String createShapeFileName(int layerNumber) { + return SHAPEFILE_NAME+"_"+layerNumber+".shp"; + } + + /** + * Method that refreshes the Metadatafile for publishing the WMS + * Without generating the Data ones again. + * @param layerMetaData the Metadata which is required to create the Layers + * @param inputData the Inputdata which was sent by the Client + * @param uuid the uuid of the Artifact + * @param callContext the context of this Call + * @return a refreshed Metadata-Document + */ + private Document refreshMetaFile(Collection layerMetaData, + Collection inputData, + String uuid, + CallContext callContext){ + Document document = XMLUtils.newDocument(); + Node meta = null; + int layerNumber = 0; + Iterator it = layerMetaData.iterator(); + while (it.hasNext()){ + LayerMetaData lmd = it.next(); + layerNumber ++; + String geometryType = lmd.getGeometryType(); + String templateId = lmd.getTemplateID(); + String title = getLayerTitle(inputData); + if (title == null) { + title = uuid+"_"+layerNumber; + }else{ + title = title+"_"+layerNumber; + } + callContext.putContextValue( + MetaWriter.CONTEXT_LAYER_TITLE, title); + String paramType = findParameterTitle(geometryType,templateId); + if (log.isDebugEnabled()) { + log.debug("Layer title: " + title); + log.debug("Layer type: " + paramType); + } + if (meta == null){ + meta = MetaWriter.writeLayerMeta(callContext,document); + } + MetaWriter.writeLayerMeta(callContext, document, + meta, uuid, paramType, + this.determineGeometryType(geometryType), + createShapeFileName(layerNumber), + title); + if (meta != null && !it.hasNext()) { + MetaWriter.writeMetaFile(getShapeFilePath(),document); + MapfileGenerator.getInstance().update(); + return document; + } + } + return document; + } + + /** + * Returns the parameterType for the Layer. + * @param geometryType + * @return + */ + private String findParameterTitle(String geometryType, String templateID) { + String paramType = LAYER_MODEL+"_"+templateID; + if (!MapfileGenerator.getInstance().templateExists(paramType)){ + // If the template doesn't exist the Defaulttemplates will be used. + paramType = LAYER_MODEL+"_"+ + this.determineDefaultTemplateName(geometryType); + } + return paramType; + } + + /** + * Find the title for a wms layer specified by the user. + * + * @param inputData A collection with InputData objects. + * @return the title. + */ + protected String getLayerTitle(Collection inputData) { + for (InputData data: inputData) { + String name = data.getName(); + if (name != null && name.equals("title")) { + return (String) data.getValue(); + } + } + return null; + } + + + /** + * Turns the geometry type into a form used for the templating mechanism + * while mapfile generation. + * + * @param geometryType The original geometry type. + * @return a valid geometry type fpr the template mechanism. + */ + private String determineGeometryType(String geometryType){ + String returnValue = geometryType.toLowerCase(); + if (returnValue.equalsIgnoreCase("linestring")){ + returnValue = "Line"; + }else if (returnValue.equalsIgnoreCase("multilinestring")){ + returnValue ="Line"; + }else if (returnValue.equalsIgnoreCase("multipolygon")){ + returnValue = "Polygon"; + } + return returnValue; + } + + + /** + * Determine the default template name if no special template is existing + * for this layer. + * + * @param geometryType The geometry type. + * @return a default geometry fitting to the original geometry type. + */ + private String determineDefaultTemplateName(String geometryType){ + String returnValue = geometryType.toLowerCase(); + if (returnValue.equalsIgnoreCase("multilinestring")){ + returnValue ="linestring"; + }else if (returnValue.equalsIgnoreCase("multipolygon")){ + returnValue = "polygon"; + }else if (returnValue.equalsIgnoreCase("multipoint")){ + returnValue = "point"; + } + return returnValue; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing Layer to handle input and +output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +Classes in this package handle specific input/output of artifacts and even play a +decisive role for creating describe-documents of the current artifact's state. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshCrossOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,430 @@ +package de.intevation.gnv.state.profile.horizontal; + +import com.vividsolutions.jts.geom.Coordinate; + +import de.intevation.artifactdatabase.Config; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.artifacts.cache.CacheFactory; + +import de.intevation.gnv.artifacts.context.GNVArtifactContext; + +import de.intevation.gnv.chart.Chart; +import de.intevation.gnv.chart.ChartLabels; +import de.intevation.gnv.chart.HorizontalCrossProfileChart; + +import de.intevation.gnv.geobackend.base.DefaultResult; +import de.intevation.gnv.geobackend.base.DefaultResultDescriptor; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import de.intevation.gnv.math.Interpolation2D; +import de.intevation.gnv.math.LinearMetrics; +import de.intevation.gnv.math.Point2d; + +import de.intevation.gnv.state.InputData; + +import de.intevation.gnv.utils.DistanceCalculator; +import de.intevation.gnv.utils.StringUtils; +import de.intevation.gnv.utils.WKTUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +import org.w3c.dom.Node; + +/** + * This OutputState is used for 'Horizontalschnitt' products. + * + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class HorizontalProfileMeshCrossOutputState +extends HorizontalProfileMeshOutputState +{ + + public static final boolean USE_INDEX_BUFFER = + Boolean.getBoolean("gnv.horizontal.profile.mesh.cross.index.buffer"); + + private static final long serialVersionUID = 2205958041745637263L; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger( + HorizontalProfileMeshCrossOutputState.class); + + private String ijkQueryID = null; + + /** + * Constructor + */ + public HorizontalProfileMeshCrossOutputState() { + super(); + } + + + @Override + public void setup(Node configuration) { + super.setup(configuration); + this.ijkQueryID = Config.getStringXPath(configuration,"queryID-ijk"); + + } + + + /** + * This method creates a chart and returns it. + * + * @param chartLables Labels used to decorate the chart. + * @param theme The theme used to adjust the look of the chart. + * @param parameters A collection with parameters this chart contains. + * @param measurements A collection with measurement this chart contains. + * @param dates A collection with dates this chart contains. + * @param result The data collection used to be displayed in this chart. + * @param locale The Locale used to determine the language. + * @param uuid The uuid of the current artifact. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two points in a chart (not used in this chart type). + * @param shapesVisible A boolean property to determine the visiblity of + * datapoints in this chart (not used in this chart type). + * @param callContext The CallContext object. + * @return a HorizontalCrossProfileChart. + */ + @Override + protected Chart getChart( + ChartLabels chartLables, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Object result, + Locale locale, + String uuid, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = null; + if (CACHE_CHART) { + log.info("Try to get horizontalprofilemeshcross chart from cache."); + chart = (Chart) getChartFromCache(uuid, callContext); + } + + if (chart != null) + return chart; + + log.info("Chart not in cache yet."); + chart = new HorizontalCrossProfileChart( + chartLables, + theme, + parameters, + measurements, + dates, + (Collection)result, + null, + locale, + linesVisible, + shapesVisible + ); + chart.generateChart(); + + if (CACHE_CHART) { + log.info("Put chart into cache."); + purifyChart(chart, uuid); + } + + return chart; + } + + private static int numSamples(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Integer samples = (Integer)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES_KEY); + return samples != null + ? samples.intValue() + : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SAMPLES; + } + + @Override + protected Object getChartResult(String uuid, CallContext callContext) { + log.debug("HorizontalProfileMeshCrossOutputState.getChartResult"); + Collection result = null; + if (CacheFactory.getInstance().isInitialized()) { + String key = uuid + super.getID(); + log.debug("Hash for Queryelements: " + key); + net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); + if (value != null) { + result = (Collection) (value.getObjectValue()); + }else{ + + InputData meshLine = inputData.get("mesh_linestring"); + InputData meshId = inputData.get("meshid"); + + if (meshLine == null) { + log.error("mesh_linestring is not defined"); + throw new IllegalStateException("missing mesh_linestring"); + } + + if (meshId == null) { + log.error("meshid is not defined"); + throw new IllegalStateException("missing meshid"); + } + + Coordinate [] coords = WKTUtils.toCoordinates( + meshLine.getValue()); + + if (coords == null) { + throw new IllegalStateException("cannot read coordinates"); + } + + try { + String additionWhere = USE_INDEX_BUFFER + ? WKTUtils.worldCoordinatesToIndex( + coords, + result, + meshId.getValue(), + ijkQueryID) + : WKTUtils.TRUE_EXPRESSION; + + String[] addedFilterValues = StringUtils.append( + generateFilterValuesFromInputData(), + additionWhere); + + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + + result = process( + Arrays.asList(coords), + numSamples(callContext), + queryExecutor.executeQuery( + queryID, + addedFilterValues)); + } + catch (QueryException e) { + log.error(e,e); + } + + if (CacheFactory.getInstance().isInitialized()) { + CacheFactory.getInstance().getCache().put(new net.sf.ehcache.Element(key, result)); + } + + } + } + return result; + } + + + /** + * Prepares the input data for chart creation. + * + * @param path The coordinates describing the path the data is processed + * for. + * @param numSamples Number of samples. + * @param input The input data. + * @return finalized data ready for chart creation. + */ + public static Collection process( + List path, + int numSamples, + Collection input + ) { + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("--- number of points before processing: " + input.size()); + log.debug(" number samples: " + numSamples); + } + + ArrayList output = new ArrayList(); + + Result last = null; + + int [] diffColums = null; + + SectionHandler sectionHandler = null; + + for (Result result: input) { + + if (sectionHandler == null) { + + ResultDescriptor rd = result.getResultDescriptor(); + diffColums = rd.getColumnIndices(DIFF_COLUMS); + int columns = rd.getColumnCount(); + + DefaultResultDescriptor resultDescriptor = + new DefaultResultDescriptor(); + + for (int j = 0; j < columns; ++j) { + String columnName = rd.getColumnName(j); + if (!StringUtils.contains(COLUMN_BLACKLIST, columnName)) { + resultDescriptor.addColumn( + columnName, + rd.getColumnClassName(j)); + } + } + + sectionHandler = new SectionHandler( + path, + numSamples, + output, + resultDescriptor); + + sectionHandler.setPrototyp(result); + } + + if (last != null && WKTUtils.different(last, result, diffColums)) { + sectionHandler.finish(); + sectionHandler.setPrototyp(result); + } + + sectionHandler.handle(result); + + last = result; + } + + if (sectionHandler != null) { + sectionHandler.finish(); + } + + if (debug) { + log.debug("--- number of points after processing: " + output.size()); + } + + return output; + } + + + private static final String [] DIFF_COLUMS = { + "GROUP1", + "GROUP2", + "GROUP3" + }; + + private static final String [] COLUMN_BLACKLIST = { + "MEDIAN.MESHPOINT.JPOSITION", + "MEDIAN.MESHPOINT.IPOSITION" + }; + + public static final double EPSILON = 1e-5d; + + public static final class SectionHandler + implements Interpolation2D.Consumer + { + private ArrayList points; + private List path; + private Collection output; + private Result prototyp; + private ResultDescriptor descriptor; + private boolean lastWasSuccess; + private int numSamples; + + public SectionHandler() { + } + + public SectionHandler( + List path, + int numSamples, + Collection output, + ResultDescriptor descriptor + ) { + this.path = path; + this.numSamples = numSamples; + this.output = output; + this.descriptor = descriptor; + points = new ArrayList(); + lastWasSuccess = true; + } + + public void finish() { + if (!points.isEmpty()) { + double distance = WKTUtils.toKM( + DistanceCalculator.calculateDistance(path)); + + if (distance > EPSILON) { + + Interpolation2D.interpolate( + path, + points, + 0d, + distance, + numSamples, + LinearMetrics.INSTANCE, + this); + } + + points.clear(); + } + lastWasSuccess = true; + } + + public void setPrototyp(Result prototyp) { + this.prototyp = prototyp; + } + + public void handle(Result result) { + Coordinate coordinate = + WKTUtils.toCoordinate(result.getString("SHAPE")); + double value = result.getDouble("YORDINATE"); + int iPos = result.getInteger("IPOSITION"); + int jPos = result.getInteger("JPOSITION"); + Point2d p = new Point2d( + coordinate.x, + coordinate.y, + value, + iPos, jPos); + points.add(p); + } + + public void interpolated(Coordinate coordinate, boolean success) { + + if (!success && !lastWasSuccess) { + // only insert null if last was valid. + // This prevents flooding the result set with nulls + // if interpolating over a large gap. + return; + } + + DefaultResult result = new DefaultResult(descriptor); + ResultDescriptor pd = prototyp.getResultDescriptor(); + + int pcolums = pd.getColumnCount(); + for (int i = 0, j = 0; i < pcolums; ++i) { + String colname = pd.getColumnName(i); + if (StringUtils.contains(COLUMN_BLACKLIST, colname)) { + continue; + } + if (colname.equals("SHAPE")) { + result.addColumnValue(j, WKTUtils.toWKT(coordinate)); + } + else if (colname.equals("YORDINATE")) { + result.addColumnValue(j, success + ? Double.valueOf(coordinate.z) + : null); + } + else { + result.addColumnValue(j, prototyp.getObject(i)); + } + ++j; + } + output.add(result); + lastWasSuccess = success; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileMeshOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.gnv.state.profile.horizontal; + +import java.util.Locale; + +import org.apache.log4j.Logger; + +public class HorizontalProfileMeshOutputState +extends HorizontalProfileOutputState +{ + private static Logger logger = + Logger.getLogger(HorizontalProfileMeshOutputState.class); + + + public HorizontalProfileMeshOutputState() { + super(); + } + + + /** + * Creates and returns the subtitle of a chart. + * + * @param locale The Locale used to adjust the language of the subtitle. + * @param uuid The UUID of the current artifact. + * @return the timeperiod of this chart and the start coordinate. + */ + @Override + protected String createChartSubtitle(Locale locale, String uuid) { + logger.debug("create chart subtitle."); + + StringBuilder sb = new StringBuilder(); + String time = getData(locale, "dateid"); + if (time != null) { + sb.append(time); + } + + String coordinate = getData(locale, "mesh_point"); + if (coordinate != null) { + sb.append("\n"); + sb.append(coordinate); + } + + String depth = getData(locale, "depthid"); + if (depth != null) { + sb.append("\n"); + sb.append(depth); + } + + return sb.toString(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,371 @@ +package de.intevation.gnv.state.profile.horizontal; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.Locale; + +import org.apache.log4j.Logger; +import org.jfree.chart.ChartTheme; + +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.chart.Chart; +import de.intevation.gnv.chart.ChartLabels; +import de.intevation.gnv.chart.HorizontalProfileChart; +import de.intevation.gnv.exports.DefaultExport; +import de.intevation.gnv.exports.DefaultProfile; +import de.intevation.gnv.exports.ShapeDataCollector; +import de.intevation.gnv.exports.Export.Profile; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.State; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.state.timeseries.TimeSeriesOutputState; +import de.intevation.gnv.statistics.HorizontalProfileStatistics; +import de.intevation.gnv.statistics.Statistics; + +/** + * This OutputState is used for 'Horizontalprofile' products. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class HorizontalProfileOutputState +extends TimeSeriesOutputState +{ + public static final String [] HORIZONTAL_PROFILE_MESH_COLUMNS = { + "SHAPE", + "YORDINATE", + "GROUP1", + "MESHID" + }; + + public static final String [] HORIZONTAL_PROFILE_MEASUREMENT_COLUMNS = { + "SHAPE", + "YORDINATE", + "GROUP1", + "SURVEYID" + }; + + + public static final String [] HORIZONTAL_MESH_CSV_COLUMN_LABEL = { + "Longitude", + "Latitude", + "Value", + "ParameterID", + "MeshID" + }; + + + public static final String [] HORIZONTAL_MEASUREMENT_CSV_COLUMN_LABEL = { + "Longitude", + "Latitude", + "Value", + "ParameterID", + "SurveyID" + }; + + /** + * The UID of this class + */ + private static final long serialVersionUID = 4401516087492028840L; + + private static Logger log = Logger + .getLogger(HorizontalProfileOutputState.class); + + public static final String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss"; + + public static final String [] CHART_TITLE_META = { + "CRUISE", + "DEPTH", + "SHAPE" + }; + + + public static final String [] CHART_TITLE_META_RESSOURCES = { + "cruiseid", + "depth", + "coordinate" + }; + + public static final String [] TIMESERIES_CSV_PROFILE_NAMES = { + "SHAPE", + "YORDINATE", + "GROUP1", + "GROUP2", + "GROUP3" + }; + + public static final Profile TIMESERIES_CSV_PROFILE = + new DefaultProfile( + null, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + + /** + * Constructor + */ + public HorizontalProfileOutputState() { + super(); + super.domainLable = "chart.horizontalprofile.title.xaxis"; + } + + + /** + * This method creates a chart and returns it. + * + * @param chartLables Labels used to decorate the chart. + * @param theme The theme used to adjust the look of the chart. + * @param parameters A collection with parameters this chart contains. + * @param measurements A collection with measurement this chart contains. + * @param dates A collection with dates this chart contains. + * @param result The data collection used to be displayed in this chart. + * @param locale The Locale used to determine the language. + * @param uuid The uuid of the current artifact. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two points in a chart (not used in this chart type). + * @param shapesVisible A boolean property to determine the visiblity of + * datapoints in this chart (not used in this chart type). + * @param callContext The CallContext object. + * @return a HorizontalProfileChart. + */ + @Override + protected Chart getChart( + ChartLabels chartLables, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Object result, + Locale locale, + String uuid, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = null; + + if (CACHE_CHART) { + log.info("Try to get horizontalprofile chart from cache."); + chart = (Chart) getChartFromCache(uuid, callContext); + } + + if (chart != null) + return chart; + + log.info("Chart not in cache yet."); + chart = new HorizontalProfileChart( + chartLables, + theme, + parameters, + measurements, + dates, + (Collection)result, + null, + locale, + linesVisible, + shapesVisible + ); + chart.generateChart(); + + if (CACHE_CHART) { + log.info("Put chart into cache."); + purifyChart(chart, uuid); + } + + return chart; + } + + + @Override + protected Statistics getStatisticsGenerator() { + return new HorizontalProfileStatistics(); + } + + + @Override + protected void createCSV(OutputStream out, Collection results) + throws UnsupportedEncodingException, IOException, StateException + { + log.debug("Create csv export for horizontal profiles."); + Iterator iter = results.iterator(); + Result res = iter.hasNext() ? (Result) iter.next() : null; + + if (res == null) + return; + + Profile profile = null; + int dataid = res.getInteger("DATAID").intValue(); + DefaultExport export = null; + // on meshes + if (dataid == 2) { + profile = new DefaultProfile( + HORIZONTAL_MESH_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + export = new DefaultExport( + new ShapeDataCollector(HORIZONTAL_PROFILE_MESH_COLUMNS)); + } + + // on measurements + else { + profile = new DefaultProfile( + HORIZONTAL_MEASUREMENT_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + export = new DefaultExport( + new ShapeDataCollector(HORIZONTAL_PROFILE_MEASUREMENT_COLUMNS)); + } + + + export.create(profile, out, results); + } + + + /** + * Creates and returns the chart title. + * + * @param locale The Locale used to adjust the language of the title. + * @param uuid The UUID of the current artifact. + * @return the name of the selected fis. + */ + @Override + protected String createChartTitle(Locale locale, String uuid) { + String fisName = getFisName(locale); + log.debug("created title for horizontal profile chart: " + fisName); + + return fisName; + } + + + @Override + protected String createChartSubtitle(Locale locale, String uuid) { + log.debug("Create subtitle for horizontalprofile chart on meshes."); + + StringBuilder sb = new StringBuilder(); + String ship = getData(locale, "vehicleid"); + if (ship != null) { + sb.append(ship); + } + + String cruise = getData(locale, "cruiseid"); + if (cruise != null) { + if (ship != null) + sb.append("\n"); + + sb.append(cruise); + } + + String track = getData(locale, "trackid"); + if (track != null) { + if (cruise != null) + sb.append("\n"); + + sb.append(track); + } + + return sb.toString(); + } + + + protected String getData(Locale locale, String data) { + InputData input = null; + + State parent = this; + do { + input = inputData.get(data); + + if (input != null) + break; + } + while ((parent = parent.getParent()) != null); + + if (input == null) { + log.warn("No data found for: " + data); + return null; + } + + String value = input.getDescription(input.getValue()); + String title = RessourceFactory.getInstance().getRessource( + locale, data, data); + + return (title + ": " + value); + } + + + /** + * Creates a timeperiod taking account for all data items used in charts. + * + * @param locale The Locale used to adjust the language of the subtitle. + * @param uuid The UUID of the current artifact. + * @return a human readable timeperiod. + */ + protected String createTimePeriod(Locale locale, String uuid) { + log.debug("create time period for chart subtitle."); + String subTitle = null; + Date startDate = null; + Date endDate = null; + + Collection dates = getDates(uuid); + if (dates == null) { + log.debug("No time period for subtitle."); + return ""; + } + + SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); + KeyValueDescibeData data = null; + + Iterator iter = dates.iterator(); + while (iter.hasNext()) { + try { + data = (KeyValueDescibeData)iter.next(); + + if (!data.isSelected()) + continue; + + Date current = format.parse(data.getValue()); + long time = current.getTime(); + + if (startDate == null) { + startDate = current; + endDate = current; + } + else if (time < startDate.getTime()) { + startDate = current; + } + else if (time > endDate.getTime()) { + endDate = current; + } + } + catch (ParseException pe) { + log.warn("Error while parsing date: " + data.getValue(), pe); + } + } + + if (startDate != null && endDate != null) + subTitle = format.format(startDate)+" - "+format.format(endDate); + + subTitle = subTitle == null ? "" : subTitle; + + log.debug("created title for horizontal profile chart: " + subTitle); + + return subTitle; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/NorthSouthEastWestState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,81 @@ +package de.intevation.gnv.state.profile.horizontal; + +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.StateBase; + +import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; + +import de.intevation.gnv.state.exception.StateException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * This states handles coordinate inputs. + * + * @author Tim Englich + */ +public class NorthSouthEastWestState extends StateBase { + + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -7989531326553305293L; + + protected String ipos; + protected String jpos; + + /** + * Constructor + */ + public NorthSouthEastWestState() { + } + + + @Override + protected List purifyResult(Collection result, String uuid) { + List describeData = new ArrayList(); + + NamedCollection keyValueDescibeData = + new NamedArrayList(dataName, 2); + + keyValueDescibeData.setMultiSelect(super.dataMultiSelect); + keyValueDescibeData.add(new DefaultKeyValueDescribeData( + "IPOSITION", ipos)); + keyValueDescibeData.add(new DefaultKeyValueDescribeData( + "JPOSITION", jpos)); + describeData.add(keyValueDescibeData); + + return describeData; + } + + + @Override + public void initialize(String uuid, CallContext context) + throws StateException + { + CallMeta callMeta = context.getMeta(); + RessourceFactory factory = RessourceFactory.getInstance(); + + // XXX Workarround - we need these strings in purifyResult, but have no + // CallMeta object there which is necessary to get resources from + // RessourceFactory. Storing the strings here is not nice, because the + // Locale object could change! + ipos = factory.getRessource( + callMeta.getLanguages(), "iposition", "iposition"); + jpos = factory.getRessource( + callMeta.getLanguages(), "jposition", "jposition"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontal/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing 'Horizontalprofile' to handle input +and output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,886 @@ +package de.intevation.gnv.state.profile.horizontalcrosssection; + +import java.awt.Dimension; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Polygon; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.cache.CacheFactory; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.geobackend.sde.datasources.RasterObject; +import de.intevation.gnv.math.AreaInterpolation; +import de.intevation.gnv.math.AttributedPoint2ds; +import de.intevation.gnv.math.Point2d; +import de.intevation.gnv.math.QueriedXYDepth; +import de.intevation.gnv.raster.ExternalIndexConverter; +import de.intevation.gnv.raster.IsoAttributeGenerator; +import de.intevation.gnv.raster.JTSMultiLineStringProducer; +import de.intevation.gnv.raster.JTSMultiPolygonProducer; +import de.intevation.gnv.raster.Palette; +import de.intevation.gnv.raster.PaletteManager; +import de.intevation.gnv.raster.Raster; +import de.intevation.gnv.raster.Vectorizer; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.OutputStateBase; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.utils.ExclusiveExec; +import de.intevation.gnv.utils.FileUtils; +import de.intevation.gnv.utils.MapfileGenerator; +import de.intevation.gnv.utils.MetaWriter; +import de.intevation.gnv.utils.Pair; +import de.intevation.gnv.utils.ShapeFileWriter; +import de.intevation.gnv.utils.StringUtils; +import de.intevation.gnv.utils.WKTUtils; + +/** + * @author Tim Englich + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public class HorizontalCrossSectionMeshOutputState +extends OutputStateBase +{ + private static Logger log = Logger + .getLogger(HorizontalCrossSectionMeshOutputState.class); + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 3233620652465061860L; + + public static final boolean USE_INDEX_BUFFER = + Boolean.getBoolean("gnv.horizontal.cross.section.mesh.index.buffer"); + + /** + * Shapefile name for isolines. + */ + public static final String ISOLINES_NAME = "isolines.shp"; + + /** + * Shapefile name for polygons. + */ + public static final String POLYGON_NAME = "polygons.shp"; + + public static final String LAYER_MODEL = "horizontalcrosssection"; + + private String ijkQueryID; + + private Boolean shapeFileLock = new Boolean(true); + + private String shapeFilePath; + + /** + * Constructor + */ + public HorizontalCrossSectionMeshOutputState() { + } + + @Override + public void initialize(String uuid, CallContext callContext) + throws StateException { + super.initialize(uuid, callContext); + if (log.isDebugEnabled()) { + log.debug("initialize output state " + uuid); + } + // fill the cache + getResult(uuid, callContext); + } + + /** + * Returns the shapefile directory path. + * + * @return the shapefile path. + */ + public String getShapeFilePath() { + synchronized (shapeFileLock) { + return shapeFilePath; + } + } + + /** + * Set the shapefile path. + * + * @param shapeFilePath Destination path to write shapefiles. + */ + public void setShapeFilePath(String shapeFilePath) { + synchronized (shapeFileLock) { + this.shapeFilePath = shapeFilePath; + } + } + + /** + * Method to reset the shapefile path. + * + * @return the old path. + */ + public String resetShapeFilePath() { + synchronized (shapeFileLock) { + String path = shapeFilePath; + shapeFilePath = null; + return path; + } + } + + + /** + * This method removes all shapefiles which might have been written by this + * artifact and resets the shapefile path. + * + * @param globalContext CallContext + */ + @Override + public void endOfLife(Object globalContext) { + super.endOfLife(globalContext); + + // do it in background + new Thread() { + @Override + public void run() { + String path = resetShapeFilePath(); + + if (path == null) { + return; + } + + File dir = new File(path); + + for (int i = 0; i < 10; ++i) { + if (!dir.exists() || FileUtils.deleteRecursive(dir)) { + MapfileGenerator.getInstance().update(); + return; + } + + try { + Thread.sleep(10000L); + } + catch (InterruptedException ie) { + } + } + + log.error("failed to remove directory '" + path + "'"); + } // run + }.start(); + } + + + /** + * This out target has two options:
+ *
    + *
  1. zip: Write the resulting data to shapefiles and export them as + * zip-archive.
  2. + *
  3. wms: Write the resulting data to shapefiles and feed a map service + * with a layer displaying these shapefiles.
  4. + *
+ * + * @param format + * @param inputData + * @param outputStream + * @param uuid + * @param callContext + * @throws StateException + */ + public void out( + Document format, + Collection inputData, + OutputStream outputStream, + String uuid, + CallContext callContext + ) + throws StateException + { + String outputMode = XMLUtils.xpathString( + format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); + + if (outputMode == null) { + throw new StateException("cannot find outputMode or mime"); + } + + outputMode = outputMode.toLowerCase(); + + if (log.isDebugEnabled()) { + log.debug("---- asking for: " + outputMode); + } + + if ("zip".equals(outputMode)) { + writeZip(uuid, callContext, outputStream); + } + else if ("wms".equals(outputMode)) { + XMLUtils.toStream( + getWMS(uuid, callContext, inputData), + outputStream); + } + else { + throw new StateException("unsupported output mode"); + } + } + + /** + * Create a zip archive with the shapefiles of the given shapefiles path and + * write it to output. + * + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @param output The output stream. + * @throws StateException if an error occured while zipfile creation. + */ + protected void writeZip( + String uuid, + CallContext callContext, + OutputStream output + ) + throws StateException + { + try { + String p = getShapeFilePath(); + if (p != null) { + File dir = new File(p); + if (dir.isDirectory()) { + FileUtils.createZipArchive(dir, output); + } + } + else { + AttributedPoint2ds result = getResult(uuid, callContext); + ExclusiveExec.UniqueKey k = ExclusiveExec.INSTANCE.acquire(uuid); + if (result != null + && (p = writeToShapeFile(uuid, result, callContext)) != null) { + FileUtils.createZipArchive(new File(p), output); + ExclusiveExec.INSTANCE.release(k); + } + } + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + } + + /** + * Write data to shapefiles and feed a map service with information about + * these shapefiles. The map service can be queried for displaying + * corresponding layers as WMS. + * + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @param inputData A collection with some input data. + * @return a document with some meta information (shapefile path, geometry + * type, time to live of the current artifact, etc). + * @throws StateException if an error occured while shapefile writing. + */ + protected Document getWMS( + String uuid, + CallContext callContext, + Collection inputData + ) + throws StateException + { + Document document = XMLUtils.newDocument(); + + Element pathElement = document.createElement("path"); + document.appendChild(pathElement); + + String path = getShapeFilePath(); + + if (path != null && new File(path).isDirectory()) { + String title = getLayerTitle(inputData); + if (title == null) { + title = uuid; + } + + callContext.putContextValue( + MetaWriter.CONTEXT_LAYER_TITLE, title); + + String paramType = findParameterType(callContext); + + if (log.isDebugEnabled()) { + log.debug("Layer title: " + title); + log.debug("Layer type: " + paramType); + } + + Document meta = MetaWriter.writeHorizontalcrosssectionMeta( + callContext, uuid, path, paramType); + if (meta != null) { + MapfileGenerator.getInstance().update(); + return meta; + } + + pathElement.setTextContent(path); + } + else { + AttributedPoint2ds result = getResult(uuid, callContext); + ExclusiveExec.UniqueKey key = ExclusiveExec.INSTANCE.acquire(uuid); + try{ + if (result != null + && (path = writeToShapeFile(uuid, result, callContext)) != null) { + + String paramType = findParameterType(callContext); + + String title = getLayerTitle(inputData); + if (title == null) { + title = uuid; + } + callContext.putContextValue( + MetaWriter.CONTEXT_LAYER_TITLE, title); + + if (log.isDebugEnabled()) { + log.debug("Parameter type: " + paramType); + log.debug("Layer title: " + title); + } + + Document meta = MetaWriter.writeHorizontalcrosssectionMeta( + callContext, uuid, path, paramType); + + if (meta != null) { + MapfileGenerator.getInstance().update(); + return meta; + } + + pathElement.setTextContent(path); + } + }finally{ + ExclusiveExec.INSTANCE.release(key); + } + } + + return document; + } + + /** + * Find the parameter name which is used during mapfile creation in + * MapfileGenerator. + * + * @param callContext The CallContext object. + * @return the parameter name of the current parameterization. + */ + protected String findParameterType(CallContext callContext) { + InputData inputParam = inputData.get("parameterid"); + + Map paletteManagers = getPalettes(callContext); + + if (inputParam == null || paletteManagers == null) { + log.warn("Parameter-id not found."); + return LAYER_MODEL; + } + else { + Integer parameterId = Integer.parseInt(inputParam.getValue()); + PaletteManager paletteManager = paletteManagers.get(parameterId); + + return LAYER_MODEL + "_" + paletteManager.getName(); + } + } + + + /** + * Find the title for a wms layer specified by the user. + * + * @param inputData A collection with InputData objects. + * @return the title. + */ + protected String getLayerTitle(Collection inputData) { + for (InputData data: inputData) { + String name = data.getName(); + if (name != null && name.equals("title")) { + return (String) data.getValue(); + } + } + + return null; + } + + /** + * Write the resulting data to shapefiles. + * + * @param uuid The UUID of the current artifact. + * @param result The finalized data used for shapefile creation. + * @param callContext The CallContext object. + * @return the shapefile path. + */ + protected String writeToShapeFile( + String uuid, + AttributedPoint2ds result, + CallContext callContext + ) { + File baseDir = shapefileDirectory(callContext); + + File shapeDir = new File(baseDir, uuid); + + boolean success = false; + boolean createdDir = false; + + try { + synchronized (shapeFileLock) { + if (shapeDir.exists()) { + FileUtils.deleteContent(shapeDir); + } + else if (!shapeDir.mkdirs()) { + log.error("cannot create directory '" + + shapeDir.getAbsolutePath() + "'"); + return null; + } + createdDir = true; + } + + Map polygons = result.getPolygons(); + + List> isolines = + result.getLineStrings(); + + File polygonsFile = new File(shapeDir, POLYGON_NAME); + File isolinesFile = new File(shapeDir, ISOLINES_NAME); + + if (!ShapeFileWriter.writeMultiPolygonsToFile( + polygonsFile, + (Integer)result.getAttribute("parameter"), + (Integer)result.getAttribute("layer"), + (Date) result.getAttribute("date"), + polygons) + ) { + log.error("writing polygons failed"); + return null; + } + + if (!ShapeFileWriter.writeMultiLineStringsToFile( + isolinesFile, + (Integer)result.getAttribute("parameter"), + (Integer)result.getAttribute("layer"), + (Date) result.getAttribute("date"), + isolines) + ) { + log.error("writing isolines failed"); + return null; + } + + shapeFilePath = shapeDir.getAbsolutePath(); + success = true; + + callContext.afterCall(CallContext.STORE); + + return shapeFilePath; + } + finally { + if (!success && createdDir) { + FileUtils.deleteRecursive(shapeDir); + } + } + } + + + /** + * Return the processed results ready for being written to shapefile. + * + * @param uuid The UUID of the current artifacts. + * @param callContext The CallContext object. + * @return the processed data. + * @throws StateException if an error occured while processing data. + */ + protected AttributedPoint2ds getResult(String uuid, CallContext callContext) + throws StateException + { + CacheFactory cf = CacheFactory.getInstance(); + String key = getHash(); + + if (cf.isInitialized()) { + net.sf.ehcache.Element value = cf.getCache().get(key); + if (value != null) { + return (AttributedPoint2ds)value.getObjectValue(); + } + } + + AttributedPoint2ds result = produceResult(callContext); + + if (result != null && cf.isInitialized()) { + cf.getCache().put(new net.sf.ehcache.Element(key, result)); + } + + return result; + } + + /** + * Query the database for result data and turn it into a useful format to + * write this data into shapefiles. + * + * @param callContext The CallContext object. + * @return the processed data. + * @throws StateException if an error occured while processing data. + */ + protected AttributedPoint2ds produceResult(CallContext callContext) + throws StateException + { + InputData meshPolygon = inputData.get("mesh_polygon"); + InputData meshId = inputData.get("meshid"); + + if (meshPolygon == null) { + log.error("mesh_polygon is not defined"); + throw new StateException("missing mesh_linestring"); + } + + if (meshId == null) { + log.error("meshid is not defined"); + throw new StateException("missing meshid"); + } + + Polygon p = WKTUtils.toPolygon(meshPolygon.getValue()); + + if (p == null) { + log.error("no valid polygon"); + throw new StateException("no valid polygon"); + } + + try { + Envelope env = p.getEnvelopeInternal(); + + String additionWhere; + + if (USE_INDEX_BUFFER) { + Coordinate [] coords = new Coordinate [] { + new Coordinate(env.getMinX(), env.getMinY()), + new Coordinate(env.getMinX(), env.getMaxY()), + new Coordinate(env.getMaxX(), env.getMaxY()), + new Coordinate(env.getMaxX(), env.getMinY()) }; + + additionWhere = + WKTUtils.worldEnvelopeCoordinatesToIndex( + coords, + meshId.getValue(), + ijkQueryID); + } + else { + additionWhere = WKTUtils.TRUE_EXPRESSION; + } + + String[] addedFilterValues = StringUtils.append( + generateFilterValuesFromInputData(), + additionWhere); + + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + + return process( + env, + p, + callContext, + preProcess( + queryExecutor.executeQuery( + queryID, + addedFilterValues))); + } + catch (QueryException e) { + log.error(e,e); + } + + throw new StateException("no result produced"); + } + + /** + * First step of finalizing the data returned from database. + * + * @param results Resulting data from database. + * @return the pre-processed data which is still not useful for being + * written to shapefiles. + */ + public AttributedPoint2ds preProcess(Collection results) { + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("--- preProcess: " + results.size() + " results"); + } + + AttributedPoint2ds ap2ds = new AttributedPoint2ds(); + + ArrayList points = new ArrayList(results.size()); + + int sIdx = -1; + int iIdx = -1; + int jIdx = -1; + int vIdx = -1; + + boolean firstWarn = true; + + for (Result result: results) { + + if (sIdx == -1) { + ResultDescriptor rd = result.getResultDescriptor(); + sIdx = rd.getColumnIndex("SHAPE"); + iIdx = rd.getColumnIndex("IPOSITION"); + jIdx = rd.getColumnIndex("JPOSITION"); + vIdx = rd.getColumnIndex("YORDINATE"); + int kIdx = rd.getColumnIndex("KPOSITION"); + int tIdx = rd.getColumnIndex("TIMEVALUE"); + int pIdx = rd.getColumnIndex("PARAMETERID"); + + if (sIdx == -1 || iIdx == -1 + || jIdx == -1 || kIdx == -1 + || vIdx == -1 || tIdx == -1 + || pIdx == -1 + ) { + log.error("missing column in result set"); + return null; + } + + ap2ds.setAttribute("date", result.getDate(tIdx)); + ap2ds.setAttribute("parameter", result.getInteger(pIdx)); + ap2ds.setAttribute("layer", result.getInteger(kIdx)); + } + Coordinate coord = WKTUtils.toCoordinate(result.getString(sIdx)); + if (coord == null) { + if (firstWarn) { + firstWarn = false; + log.warn("cannot fetch coordinate from result"); + } + continue; + } + double v = result.getDouble(vIdx); + int i = result.getInteger(iIdx); + int j = result.getInteger(jIdx); + + Point2d p2d = new Point2d(coord.x, coord.y, v, i, j); + points.add(p2d); + + } + ap2ds.setPoints(points); + + return ap2ds; + } + + /** + * The last step of finalizing the data. The returned data is useful for + * shapefile creation. + * + * @param boundingBox The bounding box. + * @param polygon A polygon. + * @param callContext CallContext. + * @param input The pre-processed data. + * @return the finalized data ready for shapefile creation. + */ + public AttributedPoint2ds process( + Envelope boundingBox, + Polygon polygon, + CallContext callContext, + AttributedPoint2ds input + ) { + if (input == null) { + log.error("no data to interpolate"); + return null; + } + + Integer parameterId = + (Integer)input.getAttribute("parameter"); // XXX: hardcoded + + if (parameterId == null) { + log.error("missing parameter id"); + return null; + } + + Map paletteManagers = + getPalettes(callContext); + + PaletteManager paletteManager = paletteManagers.get(parameterId); + + if (paletteManager == null) { + log.error("no palette found for parameter id " + parameterId); + return null; + } + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("interpolation"); + } + + AreaInterpolation interpolation = + new AreaInterpolation(); + + int numSamples = numSamples(callContext); + int groundInterpolation = getGroundInterpolation(callContext); + int extrapolationRounds = extrapolationRounds(callContext); + + if (!interpolation.interpolate( + input.getPoints(), + boundingBox, + new Dimension(numSamples, numSamples), + new QueriedXYDepth(groundInterpolation), + extrapolationRounds + )) { + log.error("interpolation failed"); + return null; + } + + // Do the post processing + Raster raster = new Raster( + interpolation.getRaster(), + numSamples); + + // TODO: Filter operations. + + if (debug) { + log.debug("to indexed raster"); + } + + // scan for regions with base palette + Palette basePalette = paletteManager.getBase(); + + int [] intRaster = raster.toIndexed(basePalette); + + // produce JFreeChart compatible polygons + + if (debug) { + log.debug("vectorize indexed raster"); + } + + // produce JTS compatible polygons + + JTSMultiPolygonProducer jtsmpp = new JTSMultiPolygonProducer( + polygon, + boundingBox.getMinX(), boundingBox.getMinY(), + boundingBox.getMaxX(), boundingBox.getMaxY()); + + int numRegions = new Vectorizer(intRaster, numSamples) + .process(jtsmpp); + + Map polygons = jtsmpp.getMultiPolygons( + new ExternalIndexConverter(basePalette)); + + jtsmpp.clear(); jtsmpp = null; // help gc + + int numColors = polygons.size(); + + if (debug) { + log.debug("number of regions: " + numRegions); + log.debug("number of colors: " + numColors); + } + // generate iso lines + + int numIso; + + if (numColors < 5) { numIso = 5; } + else if (numColors < 10) { numIso = 2; } + else { numIso = 0; } + + Palette isoPalette; + + if (numIso == 0) { // same palette + isoPalette = basePalette; + /* intRaster = intRaster; */ + } + else { + isoPalette = paletteManager.getLevel(numIso); + intRaster = raster.toIndexed(isoPalette); + } + + JTSMultiLineStringProducer jtslsp = new JTSMultiLineStringProducer( + polygon, + boundingBox.getMinX(), boundingBox.getMinY(), + boundingBox.getMaxX(), boundingBox.getMaxY()); + + numRegions = new Vectorizer(false, intRaster, numSamples) + .process(jtslsp); + + IsoAttributeGenerator iag = new IsoAttributeGenerator(isoPalette); + + List> lineStrings = + jtslsp.getMultiLineStrings(iag); + + jtslsp.clear(); jtslsp = null; // help gc + + input.setInterpolation(interpolation); + + input.setPolygons(polygons); + input.setLineStrings(lineStrings); + + return input; + } + + + @Override + public void setup(Node configuration) { + super.setup(configuration); + this.ijkQueryID = Config.getStringXPath(configuration,"queryID-ijk"); + + } + + private static int numSamples(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Integer samples = (Integer)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_SAMPLES_KEY); + return samples != null + ? samples.intValue() + : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_SAMPLES; + } + + private static int extrapolationRounds(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Integer extrapolationRounds = (Integer)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS_KEY); + return extrapolationRounds != null + ? extrapolationRounds.intValue() + : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_EXTRAPOLATION_ROUNDS; + } + + private static File shapefileDirectory(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + File dir = (File)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY); + return dir != null + ? dir + : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH; + } + + private static int getGroundInterpolation(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + + String interpolation = (String)context.get( + GNVArtifactContext.HORIZONTAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY); + + return RasterObject.getInterpolationType(interpolation); + } + + private static Map getPalettes( + CallContext callContext + ) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Map palettes = + (Map)context.get( + GNVArtifactContext.PALETTES_KEY); + return palettes != null + ? palettes + : new HashMap(); + } + + + @Override + public void cleanup(Object context) { + resetShapeFilePath(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing 'Horizontalschnitte' to handle input +and output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/vertical/VerticalProfileOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,235 @@ +package de.intevation.gnv.state.profile.vertical; + +import de.intevation.artifacts.CallContext; + +import de.intevation.gnv.chart.Chart; +import de.intevation.gnv.chart.ChartLabels; +import de.intevation.gnv.chart.VerticalProfileChart; + +import de.intevation.gnv.exports.DefaultDataCollector; +import de.intevation.gnv.exports.DefaultExport; +import de.intevation.gnv.exports.DefaultProfile; + +import de.intevation.gnv.exports.Export.Profile; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.exception.StateException; + +import de.intevation.gnv.state.timeseries.TimeSeriesOutputState; + +import de.intevation.gnv.statistics.Statistics; +import de.intevation.gnv.statistics.VerticalProfileStatistics; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; + +/** + * @author Tim Englich + * + */ +public class VerticalProfileOutputState extends TimeSeriesOutputState { + + public static final String [] VERTICAL_PROFILE_COLUMNS = { + "XORDINATE", // not quite sure if this is depth + "YORDINATE", + "GROUP1", + "FEATUREID", + "TIMESERIESID" + }; + + public static final String [] VERTICAL_PROFILE_MESH_COLUMNS = { + "XORDINATE", // not quite sure if this is depth + "YORDINATE", + "GROUP1", + "FEATUREID", + "MESHID" + }; + + public static final String [] VERTICAL_PROFILE_MEASUREMENT_COLUMNS = { + "XORDINATE", // not quite sure if this is depth + "YORDINATE", + "GROUP1", + "FEATUREID", + "SERIESID" + }; + + + public static final String [] VERTICAL_MESH_CSV_COLUMN_LABEL = { + "CentralDepth", + "Value", + "ParameterID", + "FeatureID", + "MeshID" + }; + + + public static final String [] VERTICAL_TIMESERIES_CSV_COLUMN_LABEL = { + "Depth", + "Value", + "ParameterID", + "FeatureID", + "TimeseriesID" + }; + + + public static final String [] VERTICAL_MEASUREMENT_CSV_COLUMN_LABEL = { + "Depth", + "Value", + "ParameterID", + "FeatureID", + "SeriesID" + }; + + + /** + * The UID of this class + */ + private static final long serialVersionUID = 4401516087492028840L; + + private static Logger log = Logger + .getLogger(TimeSeriesOutputState.class); + + /** + * Creates a new VerticalProfileOutputState object. + */ + public VerticalProfileOutputState() { + super(); + super.domainLable = "chart.verticalprofile.title.xaxis"; + } + + + @Override + protected Chart getChart( + ChartLabels chartLables, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Object result, + Locale locale, + String uuid, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = null; + + if (CACHE_CHART) { + log.info("Try to get verticalprofile chart from cache."); + chart = (Chart) getChartFromCache(uuid, callContext); + } + + if (chart != null) + return chart; + + log.info("Chart not in cache yet."); + chart = new VerticalProfileChart( + chartLables, + theme, + parameters, + measurements, + dates, + (Collection)result, + null, + locale, + linesVisible, + shapesVisible + ); + chart.generateChart(); + + if (CACHE_CHART) { + log.info("Put chart into cache."); + purifyChart(chart, uuid); + } + + return chart; + } + + + /** + * Creates a csv file of the resulting data and writes it to output stream. + * + * @param out The output stream. + * @param results The data used to create the csv file. + * @throws UnsupportedEncodingException if the encoding is not supported. + * @throws IOException if an error occured while writing to output stream. + * @throws StateException if an error occured while creating the csv file. + */ + @Override + protected void createCSV(OutputStream out, Collection results) + throws UnsupportedEncodingException, IOException, StateException + { + Iterator iter = results.iterator(); + Result res = iter.hasNext() ? iter.next() : null; + + if (res == null) + return; + + Profile profile = null; + int dataid = res.getInteger("DATAID").intValue(); + DefaultExport export = null; + // on meshes + if (dataid == 2) { + profile = new DefaultProfile( + VERTICAL_MESH_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + export = new DefaultExport( + new DefaultDataCollector(VERTICAL_PROFILE_MESH_COLUMNS)); + } + + // on timeseries + else if (dataid == 1) { + profile = new DefaultProfile( + VERTICAL_TIMESERIES_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + export = new DefaultExport( + new DefaultDataCollector(VERTICAL_PROFILE_COLUMNS)); + } + + // on measurements + else { + profile = new DefaultProfile( + VERTICAL_MEASUREMENT_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + export = new DefaultExport( + new DefaultDataCollector(VERTICAL_PROFILE_MEASUREMENT_COLUMNS)); + } + export.create(profile, out, results); + } + + + @Override + protected String createChartSubtitle(Locale locale, String uuid) { + return getSelectedFeatureName(uuid); + } + + + @Override + protected Statistics getStatisticsGenerator() { + return new VerticalProfileStatistics(); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/vertical/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/vertical/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing 'Vertikalprofile' to handle input +and output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/OutputHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/OutputHelper.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,97 @@ +package de.intevation.gnv.state.profile.verticalcrosssection; + +import de.intevation.gnv.jfreechart.CompactXYItems; +import de.intevation.gnv.jfreechart.PolygonSeries; + +import de.intevation.gnv.math.Interpolation3D; + +import gnu.trove.TDoubleArrayList; + +import org.apache.log4j.Logger; + +/** + * @author Sascha L. Teichmann + */ +public class OutputHelper +{ + private static Logger log = Logger.getLogger(OutputHelper.class); + + public static final double EPS = 1e-5d; + + private OutputHelper() { + } + + + /** + * Creates a PolygonSeries representing the seabed used to be displayed in a + * 2D-chart. + * + * @param interpolation The interpolation which supports information about + * the max depth, the cell width and height. + * @param fill The fill color as integer. + * @return a PolygonSeries representing the seabed. + */ + public static PolygonSeries createSeabedPolygon( + Interpolation3D interpolation, + Integer fill + ) { + double maxDepth = interpolation.getMaxDepth(); + double cellWidth = interpolation.getCellWidth(); + double cellHeight = interpolation.getCellHeight(); + + double [] depths = interpolation.getDepths(); + + double x = 0d; + + TDoubleArrayList vertices = new TDoubleArrayList(); + + PolygonSeries ps = new PolygonSeries(); + + for (int i = 0; i < depths.length; ++i, x += cellWidth) { + double depth = depths[i]; + + if (vertices.isEmpty()) { + if (Double.isNaN(depth) || depth == maxDepth) { + continue; + } + if (depth > 0d) depth = 0d; + vertices.add(x); vertices.add(maxDepth); + vertices.add(x); vertices.add(depth); + vertices.add(x+cellWidth); vertices.add(depth); + } + else { // in polygon + if (Double.isNaN(depth) || depth == maxDepth) { + vertices.add(x); vertices.add(maxDepth); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + vertices.reset(); + } + else { + if (depth > 0d) depth = 0d; + int N = vertices.size(); + if (N > 2 && Math.abs(depth - vertices.get(N-1)) < EPS) { + vertices.set(N-2, x+cellWidth); + } + else { + vertices.add(vertices.get(N-2)); vertices.add(depth); + vertices.add(x+cellWidth); vertices.add(depth); + } + } + } + } // for all depths + + if (!vertices.isEmpty()) { + vertices.add(vertices.get(vertices.size()-2)); + vertices.add(maxDepth); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + } + + if (ps.getItemCount() == 0) { + return null; + } + + ps.setAttribute("fill", fill); + + return ps; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,739 @@ +package de.intevation.gnv.state.profile.verticalcrosssection; + +import au.com.bytecode.opencsv.CSVWriter; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Paint; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; + +import org.apache.log4j.Logger; +import org.jfree.chart.ChartTheme; + +import com.vividsolutions.jts.geom.Coordinate; + +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.cache.CacheFactory; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.chart.Chart; +import de.intevation.gnv.chart.ChartLabels; +import de.intevation.gnv.chart.VerticalCrossSectionChart; +import de.intevation.gnv.exports.DefaultProfile; +import de.intevation.gnv.exports.Export; +import de.intevation.gnv.exports.VerticalCrossODVExport; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; +import de.intevation.gnv.geobackend.base.query.exception.QueryException; +import de.intevation.gnv.geobackend.sde.datasources.RasterObject; +import de.intevation.gnv.jfreechart.PolygonDataset; +import de.intevation.gnv.jfreechart.PolygonSeries; +import de.intevation.gnv.math.AttributedXYColumns; +import de.intevation.gnv.math.HeightValue; +import de.intevation.gnv.math.IJKey; +import de.intevation.gnv.math.Interpolation3D; +import de.intevation.gnv.math.LinearMetrics; +import de.intevation.gnv.math.QueriedXYDepth; +import de.intevation.gnv.math.XYColumn; +import de.intevation.gnv.raster.Filter; +import de.intevation.gnv.raster.IsoAttributeGenerator; +import de.intevation.gnv.raster.IsoPolygonSeriesProducer; +import de.intevation.gnv.raster.Palette; +import de.intevation.gnv.raster.PaletteManager; +import de.intevation.gnv.raster.PolygonDatasetProducer; +import de.intevation.gnv.raster.Raster; +import de.intevation.gnv.raster.Vectorizer; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.state.timeseries.TimeSeriesOutputState; +import de.intevation.gnv.statistics.Statistics; +import de.intevation.gnv.statistics.VerticalCrossSectionStatistics; +import de.intevation.gnv.utils.DistanceCalculator; +import de.intevation.gnv.utils.StringUtils; +import de.intevation.gnv.utils.WKTUtils; + +/** + * @author Tim Englich + * @author Ingo Weinzierl + * @author Sascha L. Teichmann + */ +public class VerticalCrossSectionOutputState extends TimeSeriesOutputState { + + public static final String CHART_TYPE = "verticalcrosssection"; + + public static final Integer GROUND_FILL_INDEX = Integer.valueOf(-2); + + public static final boolean USE_INDEX_BUFFER = + Boolean.getBoolean("gnv.vertical.cross.section.index.buffer"); + + public static final String[] ATTRIBUTE_LIST = { + "SHAPE", + "Z", + "YORDINATE", + "IPOSITION", + "JPOSITION", + "KPOSITION" + }; + + private static Logger log = Logger.getLogger( + VerticalCrossSectionOutputState.class); + + private String ijkQueryID = "horizontalprofile_meshpoint_cross_ij"; + + private String rangeLabel; + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 3233620652465061860L; + + /** + * Constructor + */ + public VerticalCrossSectionOutputState() { + super(); + super.domainLable = "chart.verticalcrosssection.title.xaxis"; + this.rangeLabel = "chart.verticalcrosssection.title.yaxis"; + } + + @Override + public void initialize(String uuid, CallContext callContext) + throws StateException { + super.initialize(uuid, callContext); + + getChartResult(uuid, callContext); + } + + @Override + protected ChartLabels createChartLabels(Locale locale, String uuid) { + RessourceFactory factory = RessourceFactory.getInstance(); + InputData input = inputData.get(parameterValuesName); + String parameterName = input.getDescription()[0]; + + if (parameterName == null) + parameterName = "parameterid"; + + return new ChartLabels( + createChartTitle(locale, uuid), + createChartSubtitle(locale, uuid), + factory.getRessource(locale, domainLable, domainLable), + factory.getRessource(locale, rangeLabel, rangeLabel), + parameterName + ); + } + + + @Override + protected String createChartSubtitle(Locale locale, String uuid) { + InputData data = inputData.get(dateValueName); + String date = data.getDescription()[0]; + + if (date == null) + date = "dateid"; + + RessourceFactory factory = RessourceFactory.getInstance(); + String chartType = factory.getRessource( + locale, CHART_TYPE, CHART_TYPE); + + return chartType + ": " + date; + } + + + @Override + protected Object getChartResult(String uuid, CallContext callContext) { + log.debug("VerticalCrossSectionOutputState.getChartResult"); + String key = getHash(); + log.debug("Hash: "+key); + + CacheFactory factory = CacheFactory.getInstance(); + if (factory.isInitialized()) { + log.info("Using a cachce."); + Cache cache = factory.getCache(); + + Element element = cache.get(key); + if (element != null) + return element.getObjectValue(); + + log.debug("No results in cache yet."); + Object obj = getData(uuid, callContext); + cache.put(new Element(key, obj)); + + return obj; + } + else { + log.info("Not using a cache."); + return getData(uuid, callContext); + } + } + + + /** + * Retrieves the data used to create a VerticalCrossProfileChart. + * + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @return the data used to create a VerticalCrossProfileChart. + */ + protected Object getData(String uuid, CallContext callContext) { + Collection result = null; + InputData meshLine = inputData.get("mesh_linestring"); + InputData meshId = inputData.get("meshid"); + + if (meshLine == null) { + log.error("mesh_linestring is not defined"); + throw new IllegalStateException("missing mesh_linestring"); + } + + if (meshId == null) { + log.error("meshid is not defined"); + throw new IllegalStateException("missing meshid"); + } + + Coordinate [] coords = WKTUtils.toCoordinates( + meshLine.getValue()); + + if (coords == null) { + throw new IllegalStateException("cannot read coordinates"); + } + + try { + String additionWhere = USE_INDEX_BUFFER + ? WKTUtils.worldCoordinatesToIndex( + coords, + result, + meshId.getValue(), + ijkQueryID) + : WKTUtils.TRUE_EXPRESSION; + + String[] addedFilterValues = StringUtils.append( + generateFilterValuesFromInputData(), + additionWhere); + + QueryExecutor exec = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + + result = exec.executeQuery(queryID, addedFilterValues); + } + catch (QueryException qe) { + log.error(qe, qe); + } + + Object obj = process( + Arrays.asList(coords), + preProcess(result), + callContext); + + return obj; + } + + + @Override + protected String getSelectedInputDataName(String uuid, String id) { + Collection values = getCollection(id, uuid); + + if (values != null) { + Iterator it = values.iterator(); + + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + + if (data.isSelected()) { + return data.getValue(); + } + } + } + return null; + } + + private static int getGroundInterpolation(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + + String interpolation = (String)context.get( + GNVArtifactContext.VERTICAL_CROSS_SECTION_GROUND_INTERPOLATION_KEY); + + return RasterObject.getInterpolationType(interpolation); + } + + private static Dimension getRasterSize(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Dimension size = (Dimension)context.get( + GNVArtifactContext.VERTICAL_CROSS_SECTION_SAMPLES_KEY); + return size != null + ? size + : GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_SAMPLES; + } + + private static List getFilterFactories( + CallContext callContext + ) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + List factories = (List)context.get( + GNVArtifactContext.VERTICAL_CROSS_SECTION_FILTER_FACTORIES_KEY); + return factories != null + ? factories + : new ArrayList(); + } + + private static Map getPalettes( + CallContext callContext + ) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Map palettes = + (Map)context.get( + GNVArtifactContext.PALETTES_KEY); + return palettes != null + ? palettes + : new HashMap(); + } + + private static Paint getGroundFill(CallContext callContext) { + GNVArtifactContext context = + (GNVArtifactContext)callContext.globalContext(); + Paint fill = (Paint)context.get( + GNVArtifactContext.VERTICAL_CROSS_SECTION_GROUND_FILL_KEY); + return fill != null + ? fill + : GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_GROUND_FILL; + } + + public static final double EPSILON = 1e-5d; + + + /** + * Finalize the data used for chart generation. Isolines are added, colors + * are assigned to polygons and the seabed is added. + * + * @param path The path which have been inserted while parameterization. + * @param columns The data used to be displayed in a 2D chart. + * @param callContext The CallContext object. + * @return the finalized data ready for chart generation. + */ + protected Object process( + List path, + AttributedXYColumns columns, + CallContext callContext + ) { + Integer parameterId = + (Integer)columns.getAttribute("GROUP1"); // XXX: hardcoded + + if (parameterId == null) { + log.error("missing parameter id"); + return null; + } + + Map paletteManagers = + getPalettes(callContext); + + PaletteManager paletteManager = paletteManagers.get(parameterId); + + if (paletteManager == null) { + log.error("no palette found for parameter id " + parameterId); + return null; + } + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("using palette '" + paletteManager.getName() + "'"); + } + + Dimension rasterSize = getRasterSize(callContext); + List filterFactories = getFilterFactories(callContext); + Interpolation3D interpolation = new Interpolation3D(rasterSize); + + double distance = DistanceCalculator.calculateDistance(path); + + if (distance < EPSILON) { + log.warn("distance too short for interpolation"); + return null; + } + + boolean success = interpolation.interpolate( + path, + columns.getXYColumns(), + 0d, + distance, + LinearMetrics.INSTANCE, + new QueriedXYDepth( + getGroundInterpolation(callContext))); + + if (!success) { + log.warn("interpolation failed"); + return null; + } + + // Do the post processing + Raster raster = new Raster( + interpolation.getRaster(), + rasterSize.width); + + for (Filter.Factory factory: filterFactories) { + raster = factory.create().filter(raster); + } + + if (debug) { + log.debug("to indexed raster"); + } + + // scan for regions with base palette + Palette basePalette = paletteManager.getBase(); + + int [] intRaster = raster.toIndexed(basePalette); + + // produce JFreeChart compatible polygons + + if (debug) { + log.debug("vectorize indexed raster"); + } + + double maxDepth = interpolation.getMaxDepth(); + + PolygonDatasetProducer pdsp = new PolygonDatasetProducer( + 0, 0, + distance, maxDepth); + + int numRegions = new Vectorizer(intRaster, rasterSize.width) + .process(pdsp); + + PolygonDataset pds = pdsp.getPolygonDataset(); + + // Count number of colors before generating seabed + // because its used to determine the number of iso lines. + int numColors = pds.getSeriesCount(); + + if (debug) { + log.debug("number of regions: " + numRegions); + log.debug("number of colors: " + numColors); + } + + // generate seabed polygon + + PolygonSeries seabed = OutputHelper.createSeabedPolygon( + interpolation, + GROUND_FILL_INDEX); + + if (seabed != null) { + pds.addSeries(seabed); + } + + // generate iso lines + + int numIso; + + if (numColors < 5) { numIso = 5; } + else if (numColors < 10) { numIso = 2; } + else { numIso = 0; } + + Palette isoPalette; + + if (numIso == 0) { // same palette + isoPalette = basePalette; + /* intRaster = intRaster; */ + } + else { + isoPalette = paletteManager.getLevel(numIso); + intRaster = raster.toIndexed(isoPalette); + } + + IsoPolygonSeriesProducer ipsp = new IsoPolygonSeriesProducer( + 0, 0, + distance, maxDepth); + + numRegions = new Vectorizer(false, intRaster, rasterSize.width) + .process(ipsp); + + IsoAttributeGenerator iag = new IsoAttributeGenerator(isoPalette); + Collection ps = ipsp.getSeries(iag); + ipsp.clear(); + + if (debug) { + log.debug("num of iso regions: " + numRegions); + log.debug("num of iso series: " + ps.size()); + } + + pds.addAllSeries(ps); + + columns.setInterpolation(interpolation); + columns.setPolygonDataset(pds); + + return columns; + } + + + /** + * Pre-process the data returned by database query. The resulting data is + * not ready for chart creation! + * + * @param results Data returned by database. + * @return Pre-processed data which is not ready for chart creation yet. + */ + protected AttributedXYColumns preProcess(Collection results) { + + AttributedXYColumns attColumns = new AttributedXYColumns(); + Map map = new HashMap(1013); + Iterator iter = results.iterator(); + + int sIdx = -1; + int iIdx = -1; + int jIdx = -1; + int kIdx = -1; + int vIdx = -1; + int zIdx = -1; + + while (iter.hasNext()) { + Result result = (Result) iter.next(); + + if (sIdx == -1) { + ResultDescriptor rd = result.getResultDescriptor(); + int columnCount = rd.getColumnCount(); + + sIdx = rd.getColumnIndex("SHAPE"); + iIdx = rd.getColumnIndex("IPOSITION"); + jIdx = rd.getColumnIndex("JPOSITION"); + kIdx = rd.getColumnIndex("KPOSITION"); + vIdx = rd.getColumnIndex("YORDINATE"); + zIdx = rd.getColumnIndex("Z"); + + for (int i = 0; i < columnCount; i++) { + String colName = rd.getColumnName(i); + + if (!StringUtils.contains(ATTRIBUTE_LIST, colName)) { + attColumns.setAttribute( + colName, + result.getObject(colName)); + } + } + } + + double v = result.getDouble(vIdx); + double z = result.getDouble(zIdx); + int i = result.getInteger(iIdx); + int j = result.getInteger(jIdx); + int k = result.getInteger(kIdx); + + IJKey key = new IJKey(i, j); + + XYColumn col = (XYColumn)map.get(key); + + if (col == null) { + Coordinate coord = WKTUtils.toCoordinate(result.getString(sIdx)); + if (coord == null) coord = new Coordinate(); + col = new XYColumn(coord.x, coord.y, i, j); + map.put(key, col); + } + + col.add(new HeightValue(z, v, k)); + } + + ArrayList cols = new ArrayList(map.values()); + attColumns.setXYColumns(cols); + + return attColumns; + } + + + /** + * This getChart method returns a 2D VerticalCrossSectionChart + * displaying polygon data with isolines and a legend describing the colors + * used in that chart. + * + * @param chartLables Labels used to decorate the chart. + * @param theme The theme used to adjust the look of the chart. + * @param parameters A collection with parameters this chart contains. + * @param measurements A collection with measurement this chart contains. + * @param dates A collection with dates this chart contains. + * @param result The data collection used to be displayed in this chart. + * @param locale The Locale used to determine the language. + * @param uuid The uuid of the current artifact. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two points in a chart (not used in this chart type). + * @param shapesVisible A boolean property to determine the visiblity of + * datapoints in this chart (not used in this chart type). + * @param callContext The CallContext object. + * @return a 2D chart representing the data as polygons. + */ + @Override + protected Chart getChart( + ChartLabels chartLables, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Object result, + Locale locale, + String uuid, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = null; + + if (CACHE_CHART) { + log.info("Try to get verticalcrosssection chart from cache."); + chart = (Chart) getChartFromCache(uuid, callContext); + } + + if (chart != null) + return chart; + + log.info("Chart not in cache yet."); + + if (!(result instanceof AttributedXYColumns)) { + log.error("result of wrong type"); + return null; + } + + AttributedXYColumns columns = (AttributedXYColumns)result; + + Integer parameterId = + (Integer)columns.getAttribute("GROUP1"); // XXX: hardcoded + + if (parameterId == null) { + log.error("missing parameter id"); + return null; + } + + Map paletteManagers = + getPalettes(callContext); + + PaletteManager paletteManager = paletteManagers.get(parameterId); + + if (paletteManager == null) { + log.error("no palette found for parameter id " + parameterId); + return null; + } + + HashMap special = new HashMap(); + special.put(GROUND_FILL_INDEX, getGroundFill(callContext)); + + chart = new VerticalCrossSectionChart( + columns, + paletteManager.getBase(), + special, + locale, + chartLables); + + chart.generateChart(); + ((VerticalCrossSectionChart)chart).setBackgroundPaint(Color.WHITE); + + if (CACHE_CHART) { + log.info("Put chart into cache."); + purifyChart(chart, uuid); + } + + return chart; + } + + + @Override + protected Statistics getStatisticsGenerator() { + return new VerticalCrossSectionStatistics(); + } + + /** + * Nothing happens here. This method should never be called until + * there is a wise implementation of a csv representation of the polygon + * data. + * + * @param outputStream The output stream used to write the csv file to. + * @param chartResult The data used to be written to csv file. + * @throws UnsupportedEncodingException if the encoding is not supported. + * @throws IOException if an error occured while writing to output stream. + * @throws StateException if an error occured while csv file creation. + */ + @Override + protected void createCSV( + OutputStream outputStream, + Collection chartResult + ) + throws UnsupportedEncodingException, IOException, StateException + { + // TODO: Implement a substitution which makes sense. + } + + @Override + protected void createODV( + OutputStream outputStream, + String uuid, + CallContext callContext) + throws IOException, StateException + { + // 'Profilschnitte' contain one parameter only + Collection tmp = getParameters(uuid); + KeyValueDescibeData param = (KeyValueDescibeData) tmp.toArray()[0]; + + String [] COLUMN_HEADER = { + "Cruise", + "Station", + "Type", + "yyyy-mm-dd hh:mm", + "Lon (°E)", + "Lat (°N)", + "Bot. Depth [m]", + "Depth [m]", + "QF", + param.getValue() + }; + + Export.Profile ODV_PROFILE = new DefaultProfile( + COLUMN_HEADER, + '\t', + CSVWriter.NO_QUOTE_CHARACTER, + CSVWriter.NO_ESCAPE_CHARACTER, + "ODV", + "ISO-8859-1"); + + Object chartResult = getChartResult(uuid, callContext); + + if (chartResult == null) { + log.error("No data for export found."); + return; + } + + List result = new ArrayList(1); + result.add(chartResult); + + InputData data = inputData.get(dateValueName); + String date = data.getDescription()[0]; + + Interpolation3D interpol = ((AttributedXYColumns) + chartResult).getInterpolation(); + + Coordinate[] coords = interpol.getCoordinates(); + double[] depth = interpol.getDepths(); + double[] raster = interpol.getRaster(); + + Export export = new VerticalCrossODVExport( + interpol.getCoordinates(), + interpol.getCellHeight(), + interpol.getCellWidth(), + interpol.getRaster(), + date, + interpol.getWidth(), + interpol.getHeight()); + + export.create(ODV_PROFILE, outputStream, null); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing 'Profilschnitte' to handle input and +output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1318 @@ +package de.intevation.gnv.state.timeseries; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import java.text.DateFormat; +import java.text.NumberFormat; +import java.text.ParseException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.jfree.chart.ChartTheme; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import au.com.bytecode.opencsv.CSVWriter; +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.artifacts.ressource.RessourceFactory; +import de.intevation.gnv.chart.Chart; +import de.intevation.gnv.chart.ChartLabels; +import de.intevation.gnv.chart.DefaultHistogram; +import de.intevation.gnv.chart.TimeSeriesChart; +import de.intevation.gnv.chart.XMLChartTheme; +import de.intevation.gnv.chart.exception.TechnicalChartException; +import de.intevation.gnv.exports.ChartExportHelper; +import de.intevation.gnv.exports.DefaultDataCollector; +import de.intevation.gnv.exports.DefaultExport; +import de.intevation.gnv.exports.DefaultProfile; +import de.intevation.gnv.exports.Export; +import de.intevation.gnv.exports.ODVExport; +import de.intevation.gnv.exports.SimpleOdvDataCollector; +import de.intevation.gnv.exports.Export.Profile; +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.histogram.HistogramHelper; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.OutputStateBase; +import de.intevation.gnv.state.State; +import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.statistics.Statistic; +import de.intevation.gnv.statistics.StatisticSet; +import de.intevation.gnv.statistics.Statistics; +import de.intevation.gnv.statistics.TimeseriesStatistics; +import de.intevation.gnv.statistics.exception.StatisticsException; +import de.intevation.gnv.timeseries.gap.DefaultTimeGap; +import de.intevation.gnv.timeseries.gap.TimeGap; +import de.intevation.gnv.utils.ArtifactXMLUtilities; + +/** + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class TimeSeriesOutputState extends OutputStateBase { + + /** + * A boolean property to enable caching of charts after they have been + * created. This property can be adjusted via system property 'cache.chart'. + * 'true' of 'false' are valid options - defaults to 'false'.
+ * NOTE: If chart caching is enabled, charts aren't sensible to + * changes in the parameterization anymore, after a first chart has been + * created for an artifact. + */ + protected static final boolean CACHE_CHART = + Boolean.parseBoolean(System.getProperty("cache.chart", "false")); + + /** + * A field parsing a system property to adjust the alignment of pdf exports. + * The system property is 'export.pdf.landscape' and should be true or + * false. If this property is true, PDFs will be created in landscape + * format. + */ + protected static final boolean PDF_FORMAT_LANDSCAPE = + Boolean.parseBoolean(System.getProperty("export.pdf.landscape","true")); + + /** + * Supported image export formats. + */ + protected static final String[] IMG_EXPORT_FORMAT = { + "PNG", "JPEG", "GIF" + }; + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 4178407570503098858L; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(TimeSeriesOutputState.class); + + private List timeGapDefinitions = null; + + /** + * Key in resource bundle the x-axis title is stored. + */ + protected String domainLable = "chart.timeseries.title.xaxis"; + + protected String featureValuesName = "featureid"; + protected String parameterValuesName = "parameterid"; + protected String measuremenValueName = "measurementid"; + protected String dateValueName = "dateid"; + protected String timeIntervalValueName = "timeinterval"; + + + /** + * Array used to specify the columns used in csv exports. + */ + public static final String [] TIMESERIES_CSV_PROFILE_COLUMNS = { + "XORDINATE", + "YORDINATE", + "GROUP1", + "GROUP2", + "GROUP3" + }; + + + /** + * Column labels used in csv exports. + */ + public static final String [] TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL = { + "Date/Time", + "Value", + "ParameterID", + "MeasurementID", + "TimeseriesID" + }; + + + /** + * Array used to specify the column in csv exports on meshes. + */ + public static final String [] TIMESERIES_MESH_CSV_COLUMN_LABEL = { + "Date/Time", + "Value", + "ParameterID", + "FeatureID", + "MeshID" + }; + + + /** + * Array used to specify the columns in odv exports. + */ + public static final String [] TIMESERIES_ODV_PROFILE_NAMES = { + "CRUISE", + "STATION", + "TYPE", + "TIMEVALUE", + "SHAPE", + "BOTDEPTH", + "DEPTH", + "QF" + }; + + + /** + * Column labels used in odv exports. + */ + public static final String [] ODV_COLUMN_HEADER = { + "Cruise", + "Station", + "Type", + "yyyy-mm-dd hh:mm", + "Lon (°E)", + "Lat (°N)", + "Bot. Depth [m]", + "Depth [m]", + "QF" + }; + + + /** + * Profile for exporting data to odv + */ + public static final Profile TIMESERIES_ODV_PROFILE = + new DefaultProfile( + ODV_COLUMN_HEADER, + '\t', + CSVWriter.NO_QUOTE_CHARACTER, + CSVWriter.NO_ESCAPE_CHARACTER, + "ODV", + "ISO-8859-1"); + + + /** + * Constructor + */ + public TimeSeriesOutputState() { + super(); + } + + + /** + * Calls getChartResult which puts the data used for chart + * creation into cache. This redruces waiting periods after selecting an + * output type. + * + * @param uuid The UUID of the current artifact. + * @param context The CallContext object. + * @throws StateException if an error occured while fetching the data used + * for chart creation. + */ + @Override + public void initialize(String uuid, CallContext context) + throws StateException + { + getChartResult(uuid, context); + } + + + /** + * This out target has following modes:
+ *
    + *
  1. chart: Creates a chart displaying the data corresponding to the + * current parameterization. A chart has following export modes:
    + *
      + *
    1. img: Image representation of a chart.
    2. + *
    3. pdf: PDF representation of a chart.
    4. + *
    5. svg: SVG representation of a chart.
    6. + *
    + * All selected parameters are drawn into a single chart.
    + *
  2. + *
  3. histogram: Creates a histogram displaying the data corresponding to + * the current parameterization. A histogram has following export modes:
    + *
      + *
    1. img: Image representation of a histogram.
    2. + *
    3. pdf: PDF representation of a histogram.
    4. + *
    5. svg: SVG representation of a histogram.
    6. + *
    + * A single histogram is created for each selected parameter.
    + *
  4. + *
  5. statistic: Creates a statistic with important figures.
  6. + *
  7. csv: Creates a csv file.
  8. + *
  9. odv: Creates a odv file.
  10. + *
+ * + * @param format Document which contains some export specific information. + * @param inputData Contains some meta information to adjust the export + * (e.g. width and height of a chart). + * @param outputStream The output stream used to return the export. + * @param uuid The UUID of the current artifact. + * @param callContext The CallContext object. + * @throws StateException if an error occured while creating the export + * object. + */ + public void out( + Document format, + Collection inputData, + OutputStream outputStream, + String uuid, + CallContext callContext + ) throws StateException + { + log.debug("TimeSeriesOutputTransition.out"); + + String outputMode = XMLUtils.xpathString( + format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); + + String mode = XMLUtils.xpathString( + format, XPATH_EXPORT_MODE, ArtifactNamespaceContext.INSTANCE); + + if (mode == null || mode.equals("")) { + mode = "img"; + } + + String mimeType = XMLUtils.xpathString( + format, XPATH_MIME_TYPE, ArtifactNamespaceContext.INSTANCE); + + CallMeta callMeta = callContext.getMeta(); + + int chartWidth = 600; + int chartHeight = 400; + boolean sVisible = false; + int binCount = 0; + int binWidth = 0; + + Map requestParameter = new HashMap(); + + // lines are always visible. if lines should be configurable we need a + // parameter in the user interface + boolean lVisible = true; + + try { + if (inputData != null) { + Iterator it = inputData.iterator(); + while (it.hasNext()) { + InputData ip = it.next(); + String optionName = ip.getName().trim(); + requestParameter.put(optionName, ip.getValue()); + + if (optionName.equals("width")) { + chartWidth = Integer.parseInt(ip.getValue()); + } + else if (optionName.equals("height")) { + chartHeight = Integer.parseInt(ip.getValue()); + } + else if (optionName.equals("points")) { + sVisible = Boolean.parseBoolean(ip.getValue()); + } + } + } + } catch (NumberFormatException e) { + log.warn(e, e); + XMLUtils.toStream( + feedFailure("not.a.number"), + outputStream); + return; + } + + try { + Collection parameters = + getParameters(uuid); + Collection measurements = + getMeasurements(uuid); + Collection dates = + getDates(uuid); + + Locale[] serverLocales = + RessourceFactory.getInstance().getLocales(); + Locale locale = + callMeta.getPreferredLocale(serverLocales); + + ChartLabels chartLables = createChartLabels(locale, uuid); + + log.debug( + "Best locale - regarding intersection of server and " + + "browser locales - is " + locale.toString() + ); + + String exportFormat = getExportFormat(mimeType); + + // CHART + if (outputMode.equalsIgnoreCase("chart")) { + log.debug("Chart will be generated."); + + if (mode.equalsIgnoreCase("img")) { + createChart( + outputStream, + parameters, + measurements, + dates, + chartLables, + callContext, + uuid, + exportFormat, + locale, + chartWidth, + chartHeight, + lVisible, + sVisible, + callContext + ); + } + else if (mode.equalsIgnoreCase("pdf")) { + createPDF( + outputStream, + parameters, + measurements, + dates, + chartLables, + uuid, + "A4", + true, + lVisible, + sVisible, + locale, + callContext + ); + } + else if (mode.equalsIgnoreCase("svg")) { + createSVG( + outputStream, + getParameters(uuid), + getMeasurements(uuid), + getDates(uuid), + createChartLabels(locale, uuid), + uuid, + locale, + chartWidth, + chartHeight, + lVisible, + sVisible, + callContext + ); + } + } + // HISTOGRAM + else if (outputMode.equalsIgnoreCase("histogram")) { + Collection results = (Collection) getChartResult(uuid, callContext); + requestParameter.put("locale", locale); + + Object[][] data = HistogramHelper.prepareHistogramData( + results, parameters, measurements, dates); + + int size = data.length; + Chart[] histograms = new Chart[size]; + + for (int i = 0; i < size; i++) { + ChartLabels labels = createHistogramLabels( + uuid, callContext, locale, data[i]); + + ChartTheme theme = createStyle(callContext); + + histograms[i] = new DefaultHistogram( + labels, data[i], theme, requestParameter); + } + + if (mode.equalsIgnoreCase("img")) { + ChartExportHelper.exportHistograms( + outputStream, + histograms, + exportFormat, + chartWidth, + chartHeight + ); + } + else if (mode.equalsIgnoreCase("pdf")) { + ChartExportHelper.exportHistogramsAsPDF( + outputStream, + histograms, + "A4", + PDF_FORMAT_LANDSCAPE, + 50F, 50F, 50F, 50F + ); + } + else if (mode.equalsIgnoreCase("svg")) { + ChartExportHelper.exportHistogramsAsSVG( + outputStream, + histograms, + null, + chartWidth, + chartHeight + ); + } + } + else if (outputMode.equalsIgnoreCase("csv")) { + log.debug("CSV-File will be generated."); + Object result = getChartResult(uuid, callContext); + if (result instanceof Collection) { + this.createCSV( + outputStream, + (Collection)result); + } + } else if (outputMode.equalsIgnoreCase("statistics")) { + log.debug("Statistics will be generated."); + + Collection statistics; + + Statistics s = getStatisticsGenerator(); + Object result = getChartResult(uuid, callContext); + + if (result != null && s != null) { + statistics = s.calculateStatistics( + result, + parameters, + measurements, + dates); + } + else { + statistics = new ArrayList(); + } + + Document doc = writeStatistics2XML(statistics, locale); + + XMLUtils.toStream(doc, outputStream); + + } + else if (outputMode.equalsIgnoreCase("odv")) { + createODV(outputStream, uuid, callContext); + } + } catch (IOException e) { + log.error(e, e); + throw new StateException(e); + } catch (TechnicalChartException e) { + log.error(e, e); + throw new StateException(e); + } catch (StatisticsException e) { + log.error(e, e); + throw new StateException(e); + } + } + + + /** + * @param outputStream + * @param uuid + * @throws IOException + * @throws StateException + */ + protected void createODV(OutputStream outputStream, + String uuid, + CallContext callContext) + throws IOException, + StateException { + Collection odvResult = this.getODVResult(uuid); + this.createODV(outputStream, odvResult,uuid); + } + + + /** + * Retrieves the export format (e.g. png, gif, jpeg). + * + * @param mime Export format specified by the incoming request. + * @return mime if it is supported - otherwise the first format in + * {@link #IMG_EXPORT_FORMAT}. + */ + protected String getExportFormat(String mime) { + for(int i = 0; i < IMG_EXPORT_FORMAT.length; i++) { + if (mime.trim().toUpperCase().indexOf(IMG_EXPORT_FORMAT[i]) > 0) + return IMG_EXPORT_FORMAT[i]; + } + + // no format found relating to mimeType, default export as PNG + return IMG_EXPORT_FORMAT[0]; + } + + + /** + * Returns a collection containing all selected KeyValueDescibeData objects + * of parameters. + * + * @param parameters A collection with KeyValueDescibeData objects. + * @return a collection cleaned from unselected objects. + * @deprecated + */ + protected Collection getCleanedParameters(Collection parameters) { + Iterator iter = parameters.iterator(); + Collection parameter = new Vector(parameters); + while (iter.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData)iter.next(); + if (!data.isSelected()) + parameter.remove(data); + } + + return parameter; + } + + + /** + * Calls {@link #getCleanedParameters(java.util.Collection)} with the + * collection returned by {@link #getParameters(java.lang.String)}. + * + * @param uuid The UUID of the current artifact. + * @return a cleaned collection. + */ + protected Collection getCleanedParameters(String uuid) { + return getCleanedParameters(getParameters(uuid)); + } + + + /** + * Create a csv file representing the data corresponding to the current + * parameterization. + * + * @param out The output stream used to export the csv file. + * @param results The data used for csv file creation. + * @throws UnsupportedEncodingException if the encoding is not supported. + * @throws IOException if an error occured while writing to output stream. + * @throws StateException if an error occured while creating the csv file. + */ + protected void createCSV(OutputStream out, Collection results) + throws UnsupportedEncodingException, IOException, StateException + { + Iterator iter = results.iterator(); + Result res = iter.hasNext() ? (Result) iter.next() : null; + + if (res == null) + return; + + Profile profile = null; + int dataid = res.getInteger("DATAID").intValue(); + + // on meshes + if (dataid == 2) { + profile = new DefaultProfile( + TIMESERIES_MESH_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + } + + // on timeseries + else { + profile = new DefaultProfile( + TIMESERIES_TIMESERIES_CSV_COLUMN_LABEL, + ',', + '"', + '"', + "CSV", + "ISO-8859-1"); + } + + DefaultExport export = new DefaultExport( + new DefaultDataCollector(TIMESERIES_CSV_PROFILE_COLUMNS)); + export.create(profile, out, results); + } + + + /** + * Create an odv file representing the data corresponding to the current + * parameterization. + * + * @param outputStream The output stream used to export the odv file. + * @param result The data used for odv file creation. + * @param uuid The UUID of the current artifact. + * @throws IOException if an error occured while writing to output stream. + * @throws StateException if an error occured while creating the odv file. + */ + protected void createODV(OutputStream outputStream, + Collection result, + String uuid) + throws IOException, StateException { + + Export export = new ODVExport(new SimpleOdvDataCollector( + TIMESERIES_ODV_PROFILE_NAMES), + this.getParameters(uuid), + this.getStartTime()); + + if (result == null) + log.error("#################### RESULT == NULL #################"); + export.create(TIMESERIES_ODV_PROFILE, outputStream, result); + } + + /** + * Method that returns the Starttime of an TimeSeries or + * null if it is not a TimeSeries. + * @return the Starttime of an TimeSeries or null if it is not a TimeSeries. + */ + protected String getStartTime(){ + InputData data = inputData.get(this.timeIntervalValueName); + if (data != null){ + Object describeData = data.getObject(); + if (describeData instanceof MinMaxDescribeData){ + String value = ((MinMaxDescribeData)describeData) + .getMinValue().toString(); + return value.substring(0,value.lastIndexOf(':')); + } + return null; + }else{ + return null; + } + + } + + /** + * Returns the statistic generator. + * + * @return the statistic generator. + */ + protected Statistics getStatisticsGenerator() { + Statistics s = new TimeseriesStatistics(); + return s; + } + + + /** + * Writes the statistic into an xml document. + * + * @param statistic Statistic to be written to xml document. + * @return the xml document containing the statistic. + */ + protected Document writeStatistics2XML( + Collection statistic, Locale locale) + { + ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); + Document doc = XMLUtils.newDocument(); + + NumberFormat format = NumberFormat.getInstance(locale); + + if (statistic != null) { + Node statisticResults = ArtifactXMLUtilities.createArtifactElement(doc, + "statistics"); + doc.appendChild(statisticResults); + Iterator it = statistic.iterator(); + while (it.hasNext()) { + StatisticSet set = it.next(); + Element setElement = ArtifactXMLUtilities.createArtifactElement(doc, + "statistic"); + setElement.setAttribute("name", set.getName()); + + Iterator sit = set.getStatistics().iterator(); + while (sit.hasNext()){ + Statistic s = sit.next(); + Element result = ArtifactXMLUtilities.createArtifactElement(doc, + "statistic-value"); + result.setAttribute("name", s.getKey()); + result.setAttribute("value", format.format(s.getValue())); + setElement.appendChild(result); + } + statisticResults.appendChild(setElement); + } + + } + return doc; + } + + + /** + * Returns the name of the selected feature. + * + * @param uuid The UUID of the current artifact. + * @return the name of the selectef feature. + */ + protected String getSelectedFeatureName(String uuid) { + Collection values = getCollection(featureValuesName, uuid); + + if (values != null) { + Iterator it = values.iterator(); + + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + return data.getValue(); + } + + return ""; + } + return ""; + } + + + /** + * Creates a chart and writes it to outputStream. + * + * @param outputStream The stream used to write the chart to. + * @param parameters A collection with parameters. + * @param measurements A collection with measurements. + * @param dates A collection with dates. + * @param chartLables The labels used to decorate the chart. + * @param context The CallContext. + * @param uuid The UUID of the current artifact. + * @param exportFormat The format the chart used to be exported as. + * @param locale The Locale to specify the language. + * @param width The width of the chart. + * @param height The height of the chart. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two datapoins. + * @param shapesVisible A boolean property to determine the visibility of + * datapoints. + * @param callContext The CallContext object. + * @throws IOException if an error occured while writing to output stream. + * @throws TechnicalChartException if an error occured while chart creation. + */ + protected void createChart( + OutputStream outputStream, + Collection parameters, + Collection measurements, + Collection dates, + ChartLabels chartLables, + CallContext context, + String uuid, + String exportFormat, + Locale locale, + int width, + int height, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) + throws IOException, TechnicalChartException + { + log.debug("Create chart."); + Chart chart = getChart( + chartLables, + createStyle(context), + parameters, + measurements, + dates, + getChartResult(uuid, callContext), + locale, // Locale + uuid, + linesVisible, + shapesVisible, + callContext + ); + + if (chart == null) { + log.error("Could not initialize chart."); + return; + } + + log.debug( + "export chart as " + exportFormat + + " in " + width + "x" + height + ); + + ChartExportHelper.exportImage( + outputStream, + chart.generateChart(), + exportFormat, + width, + height + ); + } + + + /** + * Creates a chart and writes it as pdf to outputStream. + * + * @param outputStream The stream used to write the chart to. + * @param parameters A collection with parameters. + * @param measurements A collection with measurements. + * @param dates A collection with dates. + * @param chartLables The labels used to decorate the chart. + * @param uuid The UUID of the current artifact. + * @param exportFormat The format the chart used to be exported as. + * @param landscape A boolean property to determine the alignment of the + * chart. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two datapoins. + * @param shapesVisible A boolean property to determine the visibility of + * datapoints. + * @param locale The Locale to specify the language. + * @param context The CallContext object. + */ + protected void createPDF( + OutputStream outputStream, + Collection parameters, + Collection measurements, + Collection dates, + ChartLabels chartLables, + String uuid, + String exportFormat, + boolean landscape, + boolean linesVisible, + boolean shapesVisible, + Locale locale, + CallContext context + ) { + Chart chart = getChart( + chartLables, + createStyle(context), + parameters, + measurements, + dates, + getChartResult(uuid, context), + locale, + uuid, + linesVisible, + shapesVisible, + context + ); + + if (chart == null) { + log.error("Could not initialize chart."); + return; + } + + ChartExportHelper.exportPDF( + outputStream, + chart.generateChart(), + "A4", + PDF_FORMAT_LANDSCAPE, + 50F, 50F, 50F, 50F + ); + } + + + /** + * Creates a chart and writes it as svg to outputStream. + * + * @param outputStream The stream used to write the chart to. + * @param parameters A collection with parameters. + * @param measurements A collection with measurements. + * @param dates A collection with dates. + * @param chartLables The labels used to decorate the chart. + * @param uuid The UUID of the current artifact. + * @param locale The Locale to specify the language. + * @param width The width of the chart. + * @param height The height of the chart. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two datapoins. + * @param shapesVisible A boolean property to determine the visibility of + * datapoints. + * @param callContext The CallContext object. + */ + protected void createSVG( + OutputStream outputStream, + Collection parameters, + Collection measurements, + Collection dates, + ChartLabels chartLables, + String uuid, + Locale locale, + int width, + int height, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = getChart( + chartLables, + createStyle(callContext), + parameters, + measurements, + dates, + getChartResult(uuid, callContext), + locale, + uuid, + linesVisible, + shapesVisible, + callContext + ); + + if (chart == null) { + log.error("Could not initialize chart."); + return; + } + + ChartExportHelper.exportSVG( + outputStream, + chart.generateChart(), + null, + 600, 400 + ); + + log.debug("svg export finished."); + } + + + /** + * This method creates a chart and returns it. In normal case, this is the + * only method to be overriden by subclasses to create other types of + * charts. + * + * @param chartLables Labels used to decorate the chart. + * @param theme The theme used to adjust the look of the chart. + * @param parameters A collection with parameters this chart contains. + * @param measurements A collection with measurement this chart contains. + * @param dates A collection with dates this chart contains. + * @param result The data collection used to be displayed in this chart. + * @param locale The Locale used to determine the language. + * @param uuid The uuid of the current artifact. + * @param linesVisible A boolean property to determine the visibility of + * lines connecting two points in a chart (not used in this chart type). + * @param shapesVisible A boolean property to determine the visiblity of + * datapoints in this chart (not used in this chart type). + * @param callContext The CallContext object. + * @return a timeseries chart. + */ + protected Chart getChart( + ChartLabels chartLables, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Object result, + Locale locale, + String uuid, + boolean linesVisible, + boolean shapesVisible, + CallContext callContext + ) { + Chart chart = null; + + if (CACHE_CHART) { + log.info("Try to get timeseries chart from cache."); + chart = (Chart) getChartFromCache(uuid, callContext); + } + + if (chart != null) + return chart; + + log.info("Chart not in cache yet."); + chart = new TimeSeriesChart( + chartLables, + theme, + parameters, + measurements, + dates, + (Collection)result, + timeGapDefinitions, + locale, + linesVisible, + shapesVisible + ); + chart.generateChart(); + + if (CACHE_CHART) { + log.info("Put chart into cache."); + purifyChart(chart, uuid); + } + + return chart; + } + + + /** + * Fetches the ChartTheme from callContext and returns it. + * + * @param callContext CallContext objects storing a chart theme. + * @return a chart theme. + */ + protected ChartTheme createStyle(CallContext callContext) { + log.debug("Fetch chart theme from global context"); + + GNVArtifactContext context = + (GNVArtifactContext) callContext.globalContext(); + + XMLChartTheme theme = (XMLChartTheme) context.get( + GNVArtifactContext.CHART_TEMPLATE_KEY); + + return theme; + } + + /** + * Creates a ChartLabels object storing different labels used to decorate a + * chart. + * + * @param locale The Locale object to adjust the language of labels. + * @param uuid The UUID of the current artifact. + * @return the chart labels. + */ + protected ChartLabels createChartLabels(Locale locale, String uuid) { + return new ChartLabels( + createChartTitle(locale, uuid), + createChartSubtitle(locale, uuid), + RessourceFactory.getInstance().getRessource( + locale, + domainLable, + domainLable + ) + ); + } + + + /** + * Creates and returns the chart title. + * + * @param locale The Locale used to adjust the language of the title. + * @param uuid The UUID of the current artifact. + * @return the name of the selected fis. + */ + protected String createChartTitle(Locale locale, String uuid) { + return getFisName(locale); + + } + + + /** + * Creates and returns the subtitle of a chart. The subtitle in this class + * contains the station and the time interval. + * + * @param locale The Locale used to adjust the language of the subtitle. + * @param uuid The UUID of the current artifact. + * @return the selected feature. + */ + protected String createChartSubtitle(Locale locale, String uuid) { + String subtitle = ""; + subtitle += getSelectedFeatureName(uuid); + + InputData data = inputData.get(timeIntervalValueName); + if (data != null){ + Object describeData = data.getObject(); + if (describeData instanceof MinMaxDescribeData) { + MinMaxDescribeData tmp = (MinMaxDescribeData) describeData; + + DateFormat format = DateFormat.getDateTimeInstance( + DateFormat.MEDIUM, DateFormat.SHORT, locale); + + String lDateStr = (String) tmp.getMinValue(); + String rDateStr = (String) tmp.getMaxValue(); + + try { + Date lDate = srcFormat.parse(lDateStr); + Date rDate = srcFormat.parse(rDateStr); + + String interval = format.format(lDate); + interval += " - "; + interval += format.format(rDate); + + if (subtitle != null && subtitle.length() > 0) + subtitle += ", "; + + subtitle += interval; + } + catch (ParseException pe) { + log.error(pe, pe); + } + } + } + + return subtitle; + } + + + /** + * Creates and returns labels to decorate histograms. + * + * @param uuid The UUID of the current artifact. + * @param context The CallContext object. + * @param data An array storing strings. + * @return A ChartLabels object with the 1st string in data as title. + */ + protected ChartLabels createHistogramLabels( + String uuid, CallContext context, Locale locale, Object[] data) + { + RessourceFactory fac = RessourceFactory.getInstance(); + + return new ChartLabels( + (String) data[0], + "", + "", + fac.getRessource(locale, "histogram.axis.range.title", "")); + } + + + /** + * Returns the selected fis name. + * + * @param locale The Locale object used to adjust the language. + * @return the name of the fis. + */ + protected String getFisName(Locale locale) { + String returnValue = ""; + InputData input = inputData.get("fisname"); + + if (input != null) { + String value = input.getValue(); + + returnValue = RessourceFactory.getInstance().getRessource( + locale, + value, + value + ); + } + return returnValue; + } + + + /** + * Returns the name of the selected object in the collection specified by + * key. + * + * @param uuid The UUID of the current artifat. + * @param key A key to specify a collection. + * @return the name of the selected item. + */ + protected String getSelectedInputDataName(String uuid, String key) { + Collection values = getCollection(key, uuid); + + if (values != null) { + Iterator it = values.iterator(); + + while (it.hasNext()) { + KeyValueDescibeData data = (KeyValueDescibeData) it.next(); + + if (data.isSelected()) { + return data.getValue(); + } + } + } + return null; + } + + + /** + * Returns a collection of selected parameters. + * + * @param uuid The UUID of the current artifact. + * @return selected parameters. + */ + protected Collection getParameters(String uuid) { + return this.getCollection(parameterValuesName, uuid); + } + + /** + * Returns a collection of selected measurements. + * + * @param uuid The UUID of the current artifact. + * @return selected measurements. + */ + protected Collection getMeasurements(String uuid) { + return this.getCollection(measuremenValueName, uuid); + } + + /** + * Returns a collection of selected dates. + * + * @param uuid The UUID of the current artifact. + * @return selected dates. + */ + protected Collection getDates(String uuid) { + return this.getCollection(dateValueName,uuid); + } + + @Override + public void setup(Node configuration) { + super.setup(configuration); + String featureNameValue = Config.getStringXPath(configuration, + "value-names/value-name[@name='feature']/@value"); + if (featureNameValue != null) { + this.featureValuesName = featureNameValue; + } + String parameterNameValue = Config.getStringXPath(configuration, + "value-names/value-name[@name='parameter']/@value"); + if (parameterNameValue != null) { + this.parameterValuesName = parameterNameValue; + } + String measurementNameValue = Config.getStringXPath(configuration, + "value-names/value-name[@name='measurement']/@value"); + if (measurementNameValue != null) { + this.measuremenValueName = measurementNameValue; + } + String timeIntervalValue = Config.getStringXPath(configuration, + "value-names/value-name[@name='timeinterval']/@value"); + if (timeIntervalValue != null){ + this.timeIntervalValueName = timeIntervalValue; + } + + String dateNameValue = Config.getStringXPath(configuration, + "value-names/value-name[@name='date']/@value"); + if (dateNameValue != null) { + this.dateValueName = dateNameValue; + } + if (timeGapDefinitions == null){ + Element gapDefinition = (Element)Config.getNodeXPath(configuration, + "time-gap-definition"); + synchronized (this.getClass()) { + if (gapDefinition != null){ + String link = gapDefinition.getAttribute("xlink:href"); + if (link != null ){ + String absolutFileName = Config.replaceConfigDir(link); + gapDefinition = (Element)new ArtifactXMLUtilities(). + readConfiguration(absolutFileName); + } + + NodeList gapDefinitions = Config.getNodeSetXPath(gapDefinition, + "/time-gaps/time-gap"); + if (gapDefinition != null){ + timeGapDefinitions = new ArrayList(gapDefinitions. + getLength()); + for (int i = 0; i < gapDefinitions.getLength(); i++){ + Element gapNode = (Element)gapDefinitions.item(i); + String unit = gapNode.getAttribute("unit"); + int key = Integer.parseInt(gapNode.getAttribute("key")); + int value = Integer.parseInt(gapNode.getAttribute("gap")); + log.info("Add new Timegap: "+key+" "+value+" "+ unit); + timeGapDefinitions.add(new DefaultTimeGap(unit, + key, + value)); + } + } + } + } + } + } + + + /** + * Creates a NamedArrayList storing some + * KeyValueDescibeData objects found in the input data with the key + * collectionName. + * + * @param collectionName String to specify the input data. + * @param uuid The UUID of the current artifact. + * @return a collection with values from input data. + */ + protected Collection getCollection( + String collectionName, + String uuid) + { + log.debug("Search for input data: " + collectionName); + NamedCollection c = new NamedArrayList(collectionName); + + InputData data = null; + State parent = this; + do { + data = parent.inputData().get(collectionName); + + if (data != null) { + break; + } + } + while ((parent = parent.getParent()) != null); + + if (data == null) { + log.warn("No collection found with name: " + collectionName); + return c; + } + + String[] descs = data.getDescription(); + String[] values = data.splitValue(); + int size = values.length; + + for (int i = 0; i < size; i++){ + c.add(new DefaultKeyValueDescribeData( + values[i], descs[i], getID())); + } + + return c; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +State classes used by artifacts representing 'Zeitserien' to handle input and +output. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/AbstractStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/AbstractStatistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,110 @@ +package de.intevation.gnv.statistics; + +import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; + +import org.apache.commons.math.stat.regression.SimpleRegression; + +import org.apache.log4j.Logger; + +/** + * An abstract implementation of Statistics with a default + * implementation of the {@link #generateStatisticsValues(org.apache.commons.math.stat.descriptive.DescriptiveStatistics, org.apache.commons.math.stat.regression.SimpleRegression, java.lang.String)} + * method. + * + * @author Sascha L. Teichmann + */ +public abstract class AbstractStatistics +implements Statistics +{ + private static Logger log = Logger.getLogger( + AbstractStatistics.class); + + public AbstractStatistics() { + } + + /** + * This method takes a statistics object and puts relevant values into a + * StatisticSet. + * + * @param lStatistics A statistics object. + * @param lRegression A simple regression. + * @param statisticName Name for the resulting statistic. + * @return a set of statistics. + */ + protected StatisticSet generateStatisticsValues( + DescriptiveStatistics lStatistics, + SimpleRegression lRegression, + String statisticName + ) { + StatisticSet statisticSet = new StatisticSet(statisticName); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.arithmeticMean", + lStatistics.getMean())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.kurtosis", + lStatistics.getKurtosis())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.max", + lStatistics.getMax())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.min", + lStatistics.getMin())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.n", + lStatistics.getN())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.percentile.90", + lStatistics.getPercentile(90))); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.percentile.75", + lStatistics.getPercentile(75))); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.percentile.50", + lStatistics.getPercentile(50))); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.percentile.10", + lStatistics.getPercentile(10))); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.deviation", + lStatistics.getStandardDeviation())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.variance", + lStatistics.getVariance())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.intercept", + lRegression.getIntercept())); + + statisticSet.addStatistic( + new Statistic( + "gnviewer.statistics.descriptive.slope", + lRegression.getSlope())); + + return statisticSet; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/HorizontalProfileStatistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,79 @@ +package de.intevation.gnv.statistics; + +import java.sql.SQLException; +import java.util.Collection; + +import org.apache.log4j.Logger; + +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.utils.DistanceCalculator; + +/** + * This class is used to create a statistic for 'Horizontalprofil' products. + * + * @author Tim Englich + * + */ +public class HorizontalProfileStatistics extends TimeseriesStatistics { + + private static Logger log = Logger.getLogger(HorizontalProfileStatistics.class); + + private WKTReader wktReader = new WKTReader(); + + private DistanceCalculator dc = new DistanceCalculator(); + + private double distance = 0; + + /** + * Constructor + */ + public HorizontalProfileStatistics() { + super(); + } + + + @Override + protected double calculateXOrdinateValue(Result previousRow,Result row) + throws SQLException { + try { + Point start = (Point)this.wktReader.read(previousRow.getString("SHAPE")); + Point current = (Point)this.wktReader.read(row.getString("SHAPE")); + double delta = DistanceCalculator.calculateDistance(start, current); + + if (!Double.isNaN(delta)){ + this.distance = this.distance + delta; + } + } catch (ParseException e) { + log.error(e,e); + } + return this.distance; + } + + + @Override + protected String generateStatisticsName( + String break1, + String break2, + String break3, + Collection parameters, + Collection measurements, + Collection dates) { + return (this.findValueTitle(parameters, break1)+ " "+ + this.findValueTitle(measurements,break2)).trim()+" "+ + this.findValueTitle(dates,break3); + } + + + @Override + protected void clearStatistics() { + log.debug("HorizontalProfileStatistics.clearStatistics"); + super.clearStatistics(); + this.distance = 0; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/Statistic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/Statistic.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,73 @@ +/** + * Title: Statistic, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/Statistic.java,v 1.2 2007/12/21 12:31:15 blume Exp $ + * Source: $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/Statistic.java,v $ + * created by: Stefan Blume (blume) + * erstellt am: 14.12.2007 + * Copyright: con terra GmbH, 2005 + * + * modified by: $Author: blume $ + * modified on: $Date: 2007/12/21 12:31:15 $ + * Version: $Revision: 1.2 $ + * TAG: $Name: $ + * locked from: $Locker: $ + * CVS State: $State: Exp $ + * Project: $ProjectName$ + */ +package de.intevation.gnv.statistics; + +import org.apache.log4j.Logger; + +/** + * This class stores a double value with a specific key. + * + * @author blume + */ +public class Statistic { + + /** + * Default Logging instance + */ + private static Logger sLogger = Logger.getLogger(Statistic.class); + private static boolean sDebug = sLogger.isDebugEnabled(); + + private double mValue; + private String mKey; + + /** + * Creates a new Statistic with a given key and a value. + * @param pKey The key. + * @param pValue The value. + */ + public Statistic(String pKey, double pValue) { + mKey = pKey; + mValue = pValue; + } + + /** + * Returns the value. + * @return the value. + */ + public double getValue() { + return mValue; + } + + /** + * Returns the key. + * @return the key. + */ + public String getKey() { + return mKey; + } + + /** + * Turns the value into string representation and returns it.
+ * Attention: This method doesn't take a locale into account. + * + * @return the value as string. + */ + public String getStringValue() { + java.text.DecimalFormat df = new java.text.DecimalFormat("#.##"); + return df.format(mValue); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/StatisticSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/StatisticSet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +package de.intevation.gnv.statistics; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * A container to store several statistics. + * + * @author Tim Englich + */ +public class StatisticSet { + + + private String name = null; + + private Collection statistics = new ArrayList(); + + /** + * Constructor + * @param name Name of this container. + */ + public StatisticSet(String name) { + this.name = name; + } + + + /** + * Add a further statistic to this container. + * + * @param statistic A statistic. + */ + public void addStatistic(Statistic statistic){ + this.statistics.add(statistic); + } + + /** + * Returns all statistics in this container. + * @return all statistics. + */ + public Collection getStatistics(){ + return this.statistics; + } + + /** + * Returns the name of this container. + * @return the name. + */ + public String getName(){ + return this.name; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/Statistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/Statistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +/** + * Title: Statistics, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/Statistics.java,v 1.2 2008/01/30 12:38:34 blume Exp $ + * Source: $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/Statistics.java,v $ + * created by: Stefan Blume (blume) + * erstellt am: 14.12.2007 + * Copyright: con terra GmbH, 2005 + * + * modified by: $Author: blume $ + * modified on: $Date: 2008/01/30 12:38:34 $ + * Version: $Revision: 1.2 $ + * TAG: $Name: $ + * locked from: $Locker: $ + * CVS State: $State: Exp $ + * Project: $ProjectName$ + */ +package de.intevation.gnv.statistics; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import de.intevation.gnv.statistics.exception.StatisticsException; + +import java.util.Collection; + +/** + * This interface defines one single method to calculate a statistic for a + * given data set. + * + * @author blume + */ +public interface Statistics { + + /** + * This method takes a data set and creates a statistic from it. + * + * @param resultSet The resulting statistic is about this data set. + * @param parameters A collection of parameters. + * @param measurements A collection of measurements. + * @param dates A collection of dates. + * @return a collection of statistics. + * @throws StatisticsException if an error occured while creating the + * statistic. + */ + public Collection calculateStatistics( + Object resultSet, + Collection parameters, + Collection measurements, + Collection dates + ) + throws StatisticsException; +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/TimeseriesStatistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,226 @@ +/** + * Title: TimeseriesStatistics, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/TimeseriesStatistics.java,v 1.3 2008/08/18 14:50:33 drewnak Exp $ + * Source: $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/statistics/TimeseriesStatistics.java,v $ + * created by: Stefan Blume (blume) + * erstellt am: 06.12.2007 + * Copyright: con terra GmbH, 2005 + * + * modified by: $Author: drewnak $ + * modified on: $Date: 2008/08/18 14:50:33 $ + * Version: $Revision: 1.3 $ + * TAG: $Name: $ + * locked from: $Locker: $ + * CVS State: $State: Exp $ + * Project: $ProjectName$ + */ +package de.intevation.gnv.statistics; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import de.intevation.gnv.statistics.exception.StatisticsException; + +import java.sql.SQLException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; + +import org.apache.commons.math.stat.regression.SimpleRegression; + +import org.apache.log4j.Logger; + +/** + * This class is used to create a statistic in timeseries products. + * + * @author blume + */ +public class TimeseriesStatistics +extends AbstractStatistics +{ + + /** + * Default Logging instance + */ + private static Logger log = Logger.getLogger(TimeseriesStatistics.class); + + /** + * Constructor + */ + public TimeseriesStatistics() { + } + + + public Collection calculateStatistics( + Object result, + Collection parameters, + Collection measurements, + Collection dates + ) + throws StatisticsException { + + if (!(result instanceof Collection)) { + return new ArrayList(); + } + + Collection resultSet = (Collection)result; + + clearStatistics(); + + DescriptiveStatistics lStatistics = null; + SimpleRegression lRegression = null; + Collection statisticSets = new ArrayList(); + String break1, break2, break3; + int lSeries = 1; + + if (resultSet == null) { + return statisticSets; + } + + int b1Idx = -1; + int b2Idx = -1; + int b3Idx = -1; + int yIdx = -1; + try { + + Iterator resultIterator = resultSet.iterator(); + if (resultIterator.hasNext()) { + Result row = resultIterator.next(); + Result previousRow = row; + + if (b1Idx == -1) { + ResultDescriptor rd = row.getResultDescriptor(); + b1Idx = rd.getColumnIndex("GROUP1"); + b2Idx = rd.getColumnIndex("GROUP2"); + b3Idx = rd.getColumnIndex("GROUP3"); + yIdx = rd.getColumnIndex("YORDINATE"); + + if (b1Idx == -1 || b2Idx == -1 || b3Idx == -1 || yIdx == -1) { + return statisticSets; + } + } + break1 = row.getString(b1Idx); + break2 = row.getString(b2Idx); + break3 = row.getString(b3Idx); + lRegression = new SimpleRegression(); + lStatistics = new DescriptiveStatistics(); + while (resultIterator.hasNext()) { + + if (!break1.equals(row.getString(b1Idx)) + || !break2.equals(row.getString(b2Idx)) + || !break3.equals(row.getString(b3Idx)) + ) { + String statisticsName = generateStatisticsName( + break1, break2, + break3, parameters, + measurements, dates); + + statisticSets.add( + generateStatisticsValues( + lStatistics, + lRegression, + statisticsName)); + + lStatistics.clear(); + lRegression.clear(); + + clearStatistics(); + + Double yValue = row.getDouble(yIdx); + + if (yValue != null) { + lStatistics.addValue(yValue); + Double x = calculateXOrdinateValue(previousRow,row); + lRegression.addData(x, yValue); + } + + break1 = row.getString(b1Idx); + break2 = row.getString(b2Idx); + break3 = row.getString(b3Idx); + previousRow = row; + row = resultIterator.next(); + lSeries++; + } else { + + Double value = row.getDouble(yIdx); + if (value != null) { + lStatistics.addValue(value.doubleValue()); + Double x = calculateXOrdinateValue(previousRow,row); + lRegression.addData(x, value.doubleValue()); + } + previousRow = row; + row = resultIterator.next(); + } + + } + + Double yValue = row.getDouble(yIdx); + + if (yValue != null) { + lStatistics.addValue(yValue); + Double x = calculateXOrdinateValue(previousRow, row); + lRegression.addData(x, yValue); + } + + String statisticsName = generateStatisticsName( + break1, break2, + break3, parameters, + measurements, dates); + + statisticSets.add(generateStatisticsValues( + lStatistics, + lRegression, + statisticsName)); + lStatistics.clear(); + lRegression.clear(); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + return statisticSets; + } + + /** + * Nothing is done here. + */ + protected void clearStatistics(){} + + + protected String generateStatisticsName(String break1, + String break2, + String break3, + Collection parameters, + Collection measurements, + Collection dates){ + log.debug("TimeseriesStatistics.generateStatisticsName"); + return this.findValueTitle(parameters,break1)+ " "+ + this.findValueTitle(measurements,break2) + "m"; + } + + + protected String findValueTitle(Collection values, + String id) { + log.debug("TimeseriesStatistics.findValueTitle "+ id); + if (values != null) { + Iterator it = values.iterator(); + while (it.hasNext()) { + KeyValueDescibeData data = it.next(); + if (id.equals(data.getKey())) { + return data.getValue(); + } + } + } + return ""; + } + + + protected double calculateXOrdinateValue(Result previousRow, Result row) throws SQLException { + return new Double((row.getDate("XORDINATE")).getTime() / 1000 / 3600); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/VerticalCrossSectionStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/VerticalCrossSectionStatistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.statistics; + +import de.intevation.gnv.math.AttributedXYColumns; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import de.intevation.gnv.statistics.exception.StatisticsException; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; + +/** + * This class is used to create a statistic in 'Profilschnitt' products. + * + * @author Sascha L. Teichmann + */ +public class VerticalCrossSectionStatistics +extends AbstractStatistics +{ + private static Logger log = Logger.getLogger( + VerticalCrossSectionStatistics.class); + + public VerticalCrossSectionStatistics() { + } + + + public Collection calculateStatistics( + Object result, + Collection parameters, + Collection measurements, + Collection dates + ) + throws StatisticsException { + + boolean debug = log.isDebugEnabled(); + + if (debug) { + log.debug("calculateStatistics --------------"); + } + + ArrayList statisticSet = + new ArrayList(); + + if (!(result instanceof AttributedXYColumns)) { + log.error("wrong type of result"); + return statisticSet; + } + AttributedXYColumns columns = (AttributedXYColumns)result; + + return statisticSet; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/VerticalProfileStatistics.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,43 @@ +package de.intevation.gnv.statistics; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.state.describedata.KeyValueDescibeData; + +import java.sql.SQLException; + +import java.util.Collection; + +/** + * This class is used to create a statistic in 'Vertikalprofil' products. + * + * @author Tim Englich + */ +public class VerticalProfileStatistics extends TimeseriesStatistics { + + /** + * Constructor + */ + public VerticalProfileStatistics() { + super(); + } + + @Override + protected double calculateXOrdinateValue(Result previousRow, Result row) throws SQLException { + return row.getDouble("XORDINATE"); + } + + @Override + protected String generateStatisticsName( + String break1, + String break2, + String break3, + Collection parameters, + Collection measurements, + Collection dates) { + + return (this.findValueTitle(parameters, break1)+ " "+ + this.findValueTitle(measurements,break2)).trim(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/exception/StatisticsException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/exception/StatisticsException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,48 @@ +package de.intevation.gnv.statistics.exception; + +/** + * @author Tim Englich + * + */ +public class StatisticsException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -7324280565076343394L; + + /** + * Constructor + */ + public StatisticsException() { + } + + /** + * Constructor + * + * @param arg0 + */ + public StatisticsException(String arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + */ + public StatisticsException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + * @param arg1 + */ + public StatisticsException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains exception classes used to be thrown if error occur while +generating statistics. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/statistics/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/statistics/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes and interfaces used to create statistics for the +different types of artifacts. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/TimeSeriesArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.timeseries; + +import de.intevation.artifacts.ArtifactFactory; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * Artifact used for product timeseries product. + * + * @author Tim Englich + * @author Ingo Weinzierl + * + */ +public class TimeSeriesArtifact extends GNVArtifactBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(TimeSeriesArtifact.class); + + /** + * The UID of this class + */ + private static final long serialVersionUID = -8291547966693867205L; + + /** + * Constructor + */ + public TimeSeriesArtifact() { + super(); + log.debug("TimeSeriesArtifact.Constructor"); + this.name = "timeSeries"; + } + + + @Override + public void setup(String identifier, ArtifactFactory factory, + Object context, Document data) { + log.debug("TimeSeriesArtifact.setup"); + super.setup(identifier, factory, context, data); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/TimeSeriesMeshArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/TimeSeriesMeshArtifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.gnv.timeseries; + +/** + * Artifact used for timeseries on meshes. + * + * @author Tim Englich + */ +public class TimeSeriesMeshArtifact extends TimeSeriesArtifact { + + private static final long serialVersionUID = 5680432486700275986L; + + /** + * Constructor + */ + public TimeSeriesMeshArtifact() { + super(); + super.name = super.name + "Mesh"; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/DefaultTimeGap.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,59 @@ +package de.intevation.gnv.timeseries.gap; + +/** + * The default implementation of TimeGap. + * + * @author Tim Englich + */ +public class DefaultTimeGap implements TimeGap { + + /** + * The UNIT of the TimeGap + * See the Constants in de.intevation.gnv.timeseries.gap.TimeGap + */ + private String unit; + + /** + * The Key of the TimeGap which must be equivalent to the + * Key used in the DWH + */ + private int key; + + /** + * The Value of the Gap. + * Use the Unit and the Time Constants to Calculate the + * value in Milliseconds + */ + private int value; + + /** + * Constructor + * + * @param unit Unit of this value. + * @param key The key of this time gap. + * @param value The value of this gap. + */ + public DefaultTimeGap(String unit, int key, int value) { + super(); + this.unit = unit; + this.key = key; + this.value = value; + } + + + public String getUnit() { + return this.unit; + } + + + public int getKey() { + return this.key; + } + + + public int getValue() { + return this.value; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/TimeGap.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.timeseries.gap; + +import java.io.Serializable; + +/** + * A class representing a timegap. TimeGaps are used in timeseries + * charts to identify gaps taking account for the resolution of the x-axis + * range. + * + * @author Tim Englich + */ +public interface TimeGap extends Serializable { + + public final static String TIME_UNIT_MINUTE = "m"; + public final static String TIME_UNIT_HOUR = "h"; + public final static String TIME_UNIT_DAY = "D"; + public final static String TIME_UNIT_WEEK = "W"; + public final static String TIME_UNIT_MONTH = "M"; + public final static String TIME_UNIT_YEAR = "Y"; + + public final static long MINUTE_IN_MILLIS = 60 * 1000; + public final static long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS; + public final static long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS; + public final static long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS; + + + /** + * Returns the Lookup-Key for the TimeGap + * + * @return the timegap key. + */ + int getKey(); + + /** + * Returns the Value of the TimeValue in the Unit which is also given. + * + * @return the timegap value. + */ + int getValue(); + + /** + * Returns the Unit of the Timegap (e.g. Minutes, Hours, Days, Weeks, Months, Years) + * + * @return the timegap unit. + */ + String getUnit(); + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/gap/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package provides classes and interfaces representing time gaps used in +timerseries charts. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/timeseries/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +This package contains classes providing specific artifacts representing +'Zeitserien'. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/DefaultTransition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/DefaultTransition.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ +package de.intevation.gnv.transition; + +import de.intevation.gnv.state.State; + +/** + * The default implementation of a Transition. + * + * @author Tim Englich + * + */ +public class DefaultTransition extends TransitionBase { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -2610338646743984581L; + + /** + * Constructor + */ + public DefaultTransition() { + super(); + } + + + public boolean isValid(State state) { + return true; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/PresettingsValueCompareTransition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/PresettingsValueCompareTransition.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +package de.intevation.gnv.transition; + +import java.util.Map; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; + +import de.intevation.artifactdatabase.Config; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.State; + +/** + * Class which supports the possibility to validate if a + * Transition could be done using simple Valuecompare Operations. + * The Compareoperations will use the preSettings of an Artifact. + * At this Time equal and notequal-operations are supported. + * The Comparation is casesensitive. + * @author Tim Englich + * + */ +public class PresettingsValueCompareTransition extends TransitionBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(PresettingsValueCompareTransition.class); + + /** + * The Name of the Datafield the Value that should be compared + * should be fetched from. + */ + private String dataName = null; + /** + * The Value that should be set to the State. + */ + private String dataValue = null; + /** + * The Operation that should be used (equal notequal) + */ + private String operator = null; + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -7846722158776823205L; + + /** + * Constructor + */ + public PresettingsValueCompareTransition() { + super(); + } + + + public boolean isValid(State state) { + Map preSettings = state.getPreSettings(); + if (preSettings != null){ + boolean dataAvailable = preSettings.containsKey(dataName); + if (dataAvailable){ + if (operator.equals("equal")){ + return preSettings.get(dataName).getValue().startsWith(dataValue); + }else if (operator.equals("notequal")){ + return !preSettings.get(dataName).getValue().startsWith(dataValue); + } + } + } + if (operator.equals("notequal")){ + return true; + } + return false; + } + + + @Override + public void setup(Node configuration) { + super.setup(configuration); + this.dataName = Config.getStringXPath(configuration,"condition/@inputvalue"); + this.dataValue = Config.getStringXPath(configuration,"condition/@value"); + this.operator = Config.getStringXPath(configuration,"condition/@operator"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/Transition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/Transition.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,44 @@ +package de.intevation.gnv.transition; + +import de.intevation.gnv.state.State; + +import java.io.Serializable; + +import org.w3c.dom.Node; + +/** + * This interface describes basic methods necessary for a transition model. + * + * @author Tim Englich + * + */ +public interface Transition extends Serializable{ + + /** + * Returns the ID of the State from which the Transition could be used + * @return the ID of the State from which the Transition could be used + */ + public String getFrom(); + + /** + * Returns the ID of the State where it is possible to go as next. + * @return the ID of the State where it is possible to go as next. + */ + public String getTo(); + + /** + * Determines if it is possible to go along this Transition or not. + * @param state the current State + * @return true, if this transition is valid for the given state - otherwise + * false. + */ + public boolean isValid(State state); + + /** + * Configures the Transition. + * @param configuration + */ + public void setup(Node configuration); + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.gnv.transition; + +import de.intevation.artifactdatabase.Config; + +import org.w3c.dom.Node; + +/** + * An abstract implementation of Transition. + * + * @author Tim Englich + * + */ +public abstract class TransitionBase implements Transition { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -8542097519466477977L; + + private String from = null; + + private String to = null; + /** + * Constructor + */ + public TransitionBase() { + } + + + public String getFrom() { + return this.from; + } + + + public String getTo() { + return this.to; + } + + + public void setup(Node configuration) { + this.from = Config.getStringXPath(configuration,"from/@state"); + this.to = Config.getStringXPath(configuration,"to/@state"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,67 @@ +package de.intevation.gnv.transition; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +/** + * This Factoryclass instantiates Objects of Type Transition. + * @author Tim Englich + * + */ +public class TransitionFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactBase.class); + + /** + * The Singleton instance of the Transitionfactory. + */ + private static TransitionFactory instance = null; + + /** + * Constructor + */ + public TransitionFactory() { + super(); + } + + /** + * Returns the Instance of this Class. + * @return the Instance of this Class. + */ + public static TransitionFactory getInstance() { + if (instance == null) { + instance = new TransitionFactory(); + } + return instance; + } + + /** + * Creates a new Transition using the Configuration that is provided by the + * XML-Node. + * @param configuration The configuration that should be used to initialize + * the new Transition + * @return a new Transition. + */ + public Transition createTransition(Node configuration) { + log.debug("TransitionFactory.createTransition"); + Transition state = null; + try { + String classname = ((org.w3c.dom.Element)configuration).getAttribute("transition"); + state = (Transition) (Class.forName(classname).newInstance()); + state.setup(configuration); + } catch (InstantiationException e) { + log.error(e, e); + } catch (IllegalAccessException e) { + log.error(e, e); + } catch (ClassNotFoundException e) { + log.error(e, e); + } + return state; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/ValueCompareTransition.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/ValueCompareTransition.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,95 @@ +package de.intevation.gnv.transition; + +import java.util.Iterator; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; + +import de.intevation.artifactdatabase.Config; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.State; +import de.intevation.gnv.state.exception.StateException; + +/** + * Class which supports the possibility to validate if a + * Transition could be done using simple Valuecompare Operations. + * At this Time equal and notequal-operations are supported. + * The Comparation is casesensitive. + * @author Tim Englich + * + */ +public class ValueCompareTransition extends TransitionBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ValueCompareTransition.class); + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -7846722158776823205L; + + /** + * The Name of the Datafield the Value that should be compared + * should be fetched from. + */ + private String dataName = null; + /** + * The Value that should be set to the State. + */ + private String dataValue = null; + /** + * The Operation that should be used (equal notequal) + */ + private String operator = null; + + + /** + * Constructor + */ + public ValueCompareTransition() { + super(); + } + + /** + * validates if a Transition is valid and could be used using simple + * Comparevalue-Operations. + * @see de.intevation.gnv.transition.Transition#isValid(de.intevation.gnv.state.State) + */ + public boolean isValid(State state) { + + try { + Iterator it = state.getInputData().iterator(); + while (it.hasNext()){ + InputData inputData = it.next(); + if (inputData.getName().equals(this.dataName)){ + boolean returnValue = false; + if (operator.equals("equal")){ + returnValue = this.dataValue.equals(inputData.getValue()); + }else if (operator.equals("notequal")){ + returnValue = !this.dataValue.equals(inputData.getValue()); + } + return returnValue; + } + } + if (operator.equals("notequal")){ + // data is not given. So the constraint not Equals is fullfilled. + return true; + } + } catch (StateException e) { + log.error(e,e); + return false; + } + return false; + } + + + @Override + public void setup(Node configuration) { + super.setup(configuration); + this.dataName = Config.getStringXPath(configuration,"condition/@inputvalue"); + this.dataValue = Config.getStringXPath(configuration,"condition/@value"); + this.operator = Config.getStringXPath(configuration,"condition/@operator"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/transition/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + +This package contains interfaces and classes providing the Transitionlogic to +switch between different States and validate if the Transition to an State is +possible or not. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ArtifactXMLUtilities.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,230 @@ +package de.intevation.gnv.utils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import de.intevation.artifacts.ArtifactNamespaceContext; + +/** + * This class provides some methods for creating and working with xml documents. + * + * @author Tim Englich + * + */ +public class ArtifactXMLUtilities implements Serializable { + /** + * + */ + private static final long serialVersionUID = -6236340358303411758L; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(ArtifactXMLUtilities.class); + + public static final String XFORM_URL = "http://www.w3.org/2002/xforms"; + public static final String XFORM_PREFIX = "xform"; + + /** + * Constructor.
+ * Note: It should not be necessary to create an object of this + * class - which is a helper class. Call static methods instead. + */ + public ArtifactXMLUtilities() { + } + + /** + * Creates an Element and returns it. + * + * @param document A document + * @param name Name of a node. + * @return an Element. + */ + public static Element createArtifactElement(Document document, String name) { + Element node = document.createElementNS( + ArtifactNamespaceContext.NAMESPACE_URI, name); + node.setPrefix(ArtifactNamespaceContext.NAMESPACE_PREFIX); + return node; + } + + + /** + * Turns an xml document into a string. + * + * @param document An xml document. + * @return String representation of document. + */ + public static String writeDocument2String(Document document) { + try { + TransformerFactory transformerFactory = TransformerFactory + .newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(document); + StringWriter sw = new StringWriter(); + StreamResult result = new StreamResult(sw); + transformer.transform(source, result); + return sw.getBuffer().toString(); + } catch (TransformerConfigurationException e) { + log.error(e, e); + } catch (TransformerFactoryConfigurationError e) { + log.error(e, e); + } catch (TransformerException e) { + log.error(e, e); + } + return null; + } + + /** + * Read a document from input stream. + * + * @param inputStream The input stream. + * @return the document read from stream. + */ + public static Document readDocument(InputStream inputStream) { + Document returnValue = null; + try { + DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); + returnValue = docBuilder.parse(inputStream); + } catch (ParserConfigurationException e) { + log.error(e, e); + } catch (SAXException e) { + log.error(e, e); + } catch (IOException e) { + log.error(e, e); + } + return returnValue; + } + + + public Document reInitDocument(Document document) { + try { + byte[] barray = ArtifactXMLUtilities.writeDocument2String(document).getBytes( + "UTF-8"); + InputStream inputStream = new ByteArrayInputStream(barray); + return ArtifactXMLUtilities.readDocument(inputStream); + } catch (UnsupportedEncodingException e) { + log.error(e, e); + } + return document; + } + + + /** + * Creates an Element with {@link #XFORM_PREFIX} and name + * . + * + * @param document A document. + * @param name The node name. + * @return the created element. + */ + public static Element createXFormElement(Document document, String name) { + Element node = document.createElementNS(XFORM_URL, name); + node.setPrefix(XFORM_PREFIX); + return node; + } + + /** + * Creates an exception node. + * + * @param message The message in the node. + * @param document A document. + * @return the document containing the exception node. + */ + public static Document createExceptionReport(String message, Document document) { + log.debug("ArtifactXMLUtilities.createExceptionReport"); + Element exceptionReportNode = createArtifactElement(document, + "exceptionreport"); + document.appendChild(exceptionReportNode); + Element exceptionNode = createArtifactElement(document, + "exception"); + exceptionNode.setTextContent(message); + exceptionReportNode.appendChild(exceptionNode); + return document; + } + + /** + * Creates an input exception node. + * + * @param msg The message in the node. + * @param doc A document. + * @return the document containing the exception node. + */ + public static Document createInputExceptionReport(String msg, Document doc) { + Element exceptionReportNode = createArtifactElement( + doc,"exceptionreport"); + Element exceptionNode = createArtifactElement( + doc,"exception"); + Element inputNode = createArtifactElement( + doc, "input"); + inputNode.setTextContent(msg); + exceptionNode.appendChild(inputNode); + exceptionReportNode.appendChild(exceptionNode); + doc.appendChild(exceptionReportNode); + return doc; + } + + /** + * Creates a success node. + * + * @param message The message. + * @param document A document. + * @return the document containing the success node. + */ + public static Document createSuccessReport(String message, Document document) { + log.debug("ArtifactXMLUtilities.creatSuccessReport"); + Element reportNode = createArtifactElement(document, "result"); + document.appendChild(reportNode); + Element successNode = createArtifactElement(document, "success"); + successNode.setTextContent(message); + reportNode.appendChild(successNode); + return document; + } + + /** + * Read fileName and return the first child node. + * + * @param fileName An xml document. + * @return the first child node in this document. + */ + public Node readConfiguration(String fileName){ + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + return factory.newDocumentBuilder().parse(fileName).getChildNodes().item(0); + } catch (SAXException e) { + log.error(e,e); + return null; + } catch (IOException e) { + log.error(e,e); + return null; + } catch (ParserConfigurationException e) { + log.error(e,e); + return null; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/DistanceCalculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/DistanceCalculator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,106 @@ +package de.intevation.gnv.utils; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Point; + +import java.util.List; + +/** + * A helper class to calculate distances between points and coordinates. + * + * @author Tim Englich + * + */ +public class DistanceCalculator { + + private final static double flattening = 1.0 / 298.257233563; + + private final static double earthRadius = 6378137.0 / 1000.0 ; + + /** + * Constructor + */ + public DistanceCalculator() { + } + + + /** + * Calculates the distance between two points. + * + * @param p1 First point. + * @param p2 Second point. + * @return the distance. + */ + public static double calculateDistance(Point p1, Point p2){ + return calculateDistance(p1.getCoordinate(), p2.getCoordinate()); + } + + + /** + * Calculates the distance between two coordinates. + * + * @param p1 First coordinate. + * @param p2 Second coordinate. + * @return the distance. + */ + public static double calculateDistance(Coordinate p1, Coordinate p2){ + double resultValue = 0.0; + + double b1 = p1.y; + double b2 = p2.y; + + double l1 = p1.x; + double l2 = p2.x; + + + double F = (b1 + b2) / 2.0; + double G = (b1 - b2) / 2.0; + double l = (l1 - l2) / 2.0; + + F = (Math.PI / 180.0) * F; + G = (Math.PI / 180.0) * G; + l = (Math.PI / 180.0) * l; + + double S = ((Math.sin(G) * Math.sin(G)) * ((Math.cos(l) * Math.cos(l))))+ + ((Math.cos(F) * Math.cos(F)) * ((Math.sin(l) * Math.sin(l)))); + + double C = ((Math.cos(G) * Math.cos(G)) * ((Math.cos(l) * Math.cos(l))))+ + ((Math.sin(F) * Math.sin(F)) * ((Math.sin(l) * Math.sin(l)))); + + double w = Math.atan(Math.sqrt((S/C))); + + double D = 2.0 * w * earthRadius; + + double R = Math.sqrt((S*C)) / w; + + double H1 = (3.0 * R - 1.0 ) / (2.0 * C); + double H2 = (3.0 * R + 1.0 ) / (2.0 * S); + + resultValue = D * (1 + (flattening * H1 * (Math.sin(F) * Math.sin(F)) * + (Math.cos(G) * Math.cos(G))) - + (flattening * H2 * (Math.cos(F) * Math.cos(F)) * + (Math.sin(G) * Math.sin(G)))); + + return resultValue; + } + + /** + * Calculates the length of a path specified by coordinates in path. + * + * @param path A list of coordinates. + * @return the length of the given path. + */ + public static final double calculateDistance(List path) { + int N = path.size(); + if (N < 2) { + return 0d; + } + double sum = 0d; + for (int i = 1; i < N; ++i) { + sum += calculateDistance(path.get(i-1), path.get(i)); + } + return sum; + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/ExclusiveExec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ExclusiveExec.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,104 @@ +package de.intevation.gnv.utils; + +import java.util.HashMap; + +/** + * This class can be used to synchronize threads with a given key. To use this + * synchronization, you first need to do call {@link #acquire(java.lang.Object)} + * to retrieve a {@link UniqueKey}. After this, you can call the code being + * synchronized. After this execution, you need to call + * {@link #release(UniqueKey)} with your token you retrieved from {@link + * #acquire(java.lang.Object)}. A thread needs to wait for another thread if their keys + * are equal. Threads with different keys don't need to wait for each other. + * + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public final class ExclusiveExec +{ + /** + * The only instance of this singleton. + */ + public static final ExclusiveExec INSTANCE = new ExclusiveExec(); + + private HashMap tokens; + + /** + * This class represents a unique key with a reference counter. + */ + public static class UniqueKey { + Object key; + int [] refs; + + /** + * Constructs a new UniqueKey. + * + * @param key The key of this unique key. + */ + public UniqueKey(Object key) { + this.key = key; + refs = new int[1]; + } + } + + /** + * Private constructor. Use {@link #INSTANCE} instead. + */ + private ExclusiveExec() { + tokens = new HashMap(); + } + + /** + * This method serves a {@link UniqueKey} and starts a synchronized code + * block. + * + * @param key The key used to identify same threads. + * @return UniqueKey. Use this object to call {@link #release(UniqueKey)} + * at the end of your code being synchronized. + */ + public UniqueKey acquire(Object key) { + + try { + UniqueKey internalKey = null; + synchronized (tokens) { + internalKey = (UniqueKey)tokens.get(key); + + if (internalKey == null) { + tokens.put(key, internalKey = new UniqueKey(key)); + } + } + + synchronized (internalKey) { + ++internalKey.refs[0]; + while (internalKey.refs[0] > 1) { + internalKey.wait(10000L); + } + } + + return internalKey; + } + catch (InterruptedException ie) { + return null; + } + } + + /** + * This method releases a lock. Call this method at the end of your code + * being synchronized. + * + * @param internalKey Token retrieved by {@link #acquire(Object)}. + */ + public void release(UniqueKey internalKey) { + if (internalKey != null) { + synchronized (internalKey) { + if (--internalKey.refs[0] < 1) { + synchronized (tokens) { + tokens.remove(internalKey.key); + } + } + internalKey.notifyAll(); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/FileUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/FileUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,179 @@ +package de.intevation.gnv.utils; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.Stack; + +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * A helper class to provide some methods for working with files and + * directories. + * + * @author Sascha L. Teichmann + * @author Ingo Weinzierl + */ +public final class FileUtils +{ + private FileUtils() { + } + + /** + * Deletes everything in a directory. + * + * @param dir The directory. + */ + public final static void deleteContent(File dir) { + if (dir == null || !dir.isDirectory()) { + return; + } + + File[] files = dir.listFiles(); + if (files != null) { + for (File file: files) { + deleteRecursive(file); + } + } + + return; + } + + /** + * Delete file and everything in file if it is a directory. + * + * @param file The file or directory. + * @return true, if deletion was successful - otherwise false. + */ + public final static boolean deleteRecursive(File file) { + + if (file == null) { + return false; + } + + if (file.isDirectory()) { + File [] files = file.listFiles(); + if (files != null) { + for (File sub: files) { + if (!deleteRecursive(sub)) { + return false; + } + } + } + } + + return file.delete(); + } + + /** + * Put the given file or directory into a zip archive. + * + * @param file The file or directory. + * @param outputStream The stream to write the archive to. + * @throws IOException if an error occured while zip creation or writing to + * output stream. + */ + public static void createZipArchive( + File file, + OutputStream outputStream + ) + throws IOException + { + ZipOutputStream out = new ZipOutputStream(outputStream); + + if (file.isFile()) { + copyFileToZip("", file, out); + } + else if (file.isDirectory()) { + + Stack stack = new Stack(); + stack.push(new PrefixDir(file.getName() + "/", file)); + + while (!stack.isEmpty()) { + PrefixDir pd = stack.pop(); + + ZipEntry dirEntry = new ZipEntry(pd.prefix); + out.putNextEntry(dirEntry); + out.closeEntry(); + + File [] files = pd.dir.listFiles(); + if (files != null) { + for (File sub: files) { + if (sub.isDirectory()) { + stack.push(new PrefixDir( + pd.prefix + sub.getName() + "/", + sub)); + } + else if (sub.isFile()) { + copyFileToZip(pd.prefix, sub, out); + } + } + } + } + } + + out.finish(); + } + + /** + * A class representing a directory with a prefix. + */ + private static final class PrefixDir { + + String prefix; + File dir; + + public PrefixDir(String prefix, File dir) { + this.prefix = prefix; + this.dir = dir; + } + + } // class PrefixDir + + /** + * Write a file to zip archive. + * + * @param prefix A prefix. + * @param file The file. + * @param out The output stream. + * @throws IOException if an error occured while writing to zip output + * stream. + */ + private static void copyFileToZip( + String prefix, + File file, + ZipOutputStream out + ) + throws IOException + { + String entryName = prefix + file.getName(); + ZipEntry entry = new ZipEntry(entryName); + out.putNextEntry(entry); + InputStream in = null; + try { + in = + new BufferedInputStream( + new FileInputStream(file), 20*1024); + + byte [] buf = new byte[2048]; + + int r; + while ((r = in.read(buf)) > 0) { + out.write(buf, 0, r); + } + } + finally { + if (in != null) { + try { in.close(); } + catch (IOException ioe) {} + } + } + out.closeEntry(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/IndexBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/IndexBuffer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,169 @@ +package de.intevation.gnv.utils; + +import java.awt.Point; + +import java.awt.geom.Point2D; + +import java.util.List; + +/** + * Create buffers around integer pairs (i_1..n), j_1..n). + * + * @author Sascha L. Teichmann + */ +public class IndexBuffer +{ + public static final double EPSILON = 1e-6d; + public static final double OFFSET = 1.0d; + + public static final String I_COLUMN = "IPOSITION"; + public static final String J_COLUMN = "JPOSITION"; + + public static final class Segment { + + private Segment next; + + private Point2D.Double n; + private double d1; + private double d2; + + private int iMin; + private int iMax; + + private int jMin; + private int jMax; + + public Segment(Point a, Point b, Segment next) { + + this.next = next; + + iMin = Math.min(a.x, b.x)-1; + iMax = Math.max(a.x, b.x)+1; + + jMin = Math.min(a.y, b.y)-1; + jMax = Math.max(a.y, b.y)+1; + + if (a.x > b.x) { + Point p = a; a = b; b = p; + } + + Point2D.Double p1, p2, p3; + + if (a.y < b.y) { + p1 = new Point2D.Double(a.x - OFFSET, a.y + 1 + OFFSET); + p2 = new Point2D.Double(b.x - OFFSET, b.y + 1 + OFFSET); + p3 = new Point2D.Double(a.x + 1 + OFFSET, a.y - OFFSET); + } + else { + p1 = new Point2D.Double(a.x + 1 + OFFSET, a.y + 1 + OFFSET); + p2 = new Point2D.Double(b.x + 1 + OFFSET, b.y + 1 + OFFSET); + p3 = new Point2D.Double(b.x - OFFSET, b.y - OFFSET); + } + + n = normalize(orthogonal(sub(p1, p2))); + + d1 = dot(n, p1); + d2 = dot(n, p3); + + if (d1 > d2) { + double d = d1; + d1 = d2; + d2 = d; + } + } + + public boolean check(int i, int j) { + if (i < iMin || i > iMax || j < jMin || j > jMax) { + return false; + } + double v = dot(n, i, j); + return v >= d1 && v <= d2; + } + + public void toWhereClause(StringBuilder sb, String iColumn, String jColumn) { + sb.append('(') + .append(iColumn).append(" >= ").append(iMin).append(" AND ") + .append(iColumn).append(" <= ").append(iMax).append(" AND ") + .append(jColumn).append(" >= ").append(jMin).append(" AND ") + .append(jColumn).append(" <= ").append(jMax).append(" AND (") + .append(n.x).append('*').append(iColumn).append(" + ") + .append(n.y).append('*').append(jColumn) + .append(") BETWEEN ").append(d1).append(" AND ").append(d2).append(')'); + } + } // class Segment + + protected Segment head; + + protected String iColumn; + protected String jColumn; + + public IndexBuffer(List points) { + this(points, I_COLUMN, J_COLUMN); + } + + public IndexBuffer(List points, String iColumn, String jColumn) { + this.iColumn = iColumn; + this.jColumn = jColumn; + + for (int i = 1, N = points.size(); i < N; ++i) { + Point p1 = (Point)points.get(i-1); + Point p2 = (Point)points.get(i); + head = new Segment(p1, p2, head); + } + } + + public boolean check(int i, int j) { + + Segment current = head; + while (current != null) { + if (current.check(i, j)) { + return true; + } + current = current.next; + } + return false; + } + + public String toWhereClause() { + + StringBuilder sb = new StringBuilder(); + + Segment current = head; + + while (current != null) { + if (current != head) { + sb.append(" OR "); + } + current.toWhereClause(sb, iColumn, jColumn); + current = current.next; + } + + return sb.toString(); + } + + public static Point2D.Double sub(Point2D.Double p1, Point2D.Double p2) { + return new Point2D.Double(p1.x - p2.x, p1.y - p2.y); + } + + public static final double dot(Point2D.Double p1, Point2D.Double p2) { + return p1.x*p2.x + p1.y*p2.y; + } + + public static final double dot(Point2D.Double p1, double x, double y) { + return p1.x*x + p1.y*y; + } + + public static final Point2D.Double scale(Point2D.Double p, double s) { + return new Point2D.Double(s*p.x, s*p.y); + } + + public static final Point2D.Double normalize(Point2D.Double p) { + double len2 = Math.sqrt(dot(p, p)); + return len2 > EPSILON ? scale(p, 1d/len2) : p; + } + + public static final Point2D.Double orthogonal(Point2D.Double p) { + return new Point2D.Double(p.y, -p.x); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/InputValidator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/InputValidator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,241 @@ +package de.intevation.gnv.utils; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; + +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.util.DateUtils; + +import de.intevation.gnv.utils.exception.ValidationException; + +import java.util.Date; + +import org.apache.commons.validator.GenericValidator; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * @author Ingo Weinzierl + * + */ +public class InputValidator { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(InputValidator.class); + + + public final static String NODATASELECTEDVALUE = "n/n"; + + /** + * Constructor + */ + public InputValidator() { + super(); + } + + /** + * Validates the input of a range of double or date values. The input values + * need to be valid double or date values. minInput needs to be + * smaller or equal maxInput. + * + * @param minInput The lower bound. + * @param maxInput The upper bound. + * @param type One of 'Date' or 'Double'. + * @return true, if the input is valid, otherwise false. + */ + public static boolean isInputValid(String minInput, String maxInput, String type) { + log.debug("InputValidator.isInputValid " + minInput + " " + maxInput + " " +type); + boolean returnValue = false; + if ("Date".equalsIgnoreCase(type)) { + try { + Date min = DateUtils.getDateFromString(minInput,DateUtils.DATE_PATTERN); + Date max = DateUtils.getDateFromString(maxInput,DateUtils.DATE_PATTERN); + int value = max.compareTo(min); + returnValue = value >= 0; + } catch (Exception e) { + log.error(e,e); + } + } else if ("Double".equalsIgnoreCase(type)) { + try { + double min = Double.parseDouble(minInput); + double max = Double.parseDouble(maxInput); + returnValue = max >= min; + } catch (Exception e) { + log.error(e,e); + } + } + log.debug("Is valid? " + returnValue); + return returnValue; + } + + /** + * Validates an input. + * + * @param input The input value. + * @param type The input value type. + * @return true if the input is valid, otherwise false. + */ + public static boolean isInputValid(String input, String type) { + if (input.length() == 0 || input.equals("")) { + return false; + } + + log.debug("InputValidator.isInputValid " + input + " " + type); + + // Let's check polygons and linestrings first, because they might + // contain comma. A splitting at comma characters wouldn't be good here. + if ("Polygon".equalsIgnoreCase(type) || "Linestring".equalsIgnoreCase(type)) + { + try { + WKTReader reader = new WKTReader(); + reader.read(input); + + return true; + } + catch (ParseException pe) { + log.warn(pe, pe); + return false; + } + } + + // Check all the other input here + boolean returnValue = false; + String[] values = input.split(","); + + for (int i = 0; i < values.length; i++) { + boolean valid; + + if (NODATASELECTEDVALUE.equals(values[i].trim())){ + valid = true; + } else if ("Integer".equalsIgnoreCase(type)) { + valid = GenericValidator.isInt(values[i].trim()); + } else if ("Double".equalsIgnoreCase(type)) { + valid = GenericValidator.isDouble(values[i].trim()); + } else if ("String".equalsIgnoreCase(type)) { + valid = GenericValidator.matchRegexp(values[i], "[a-zA-Z0-9]"); // TODO: + // FIXME: + // VALIDATE + // REGEXP + } else if ("Date".equalsIgnoreCase(type)) { + valid = GenericValidator.isDate(values[i].trim(), + DateUtils.DATE_PATTERN, true); + } else if ("Point".equalsIgnoreCase(type) || "Geometry".equals(type)) { + valid = GenericValidator.matchRegexp(values[i], "[0-9]"); // TODO: + // FIXME: + // VALIDATE + // REGEXP + } else if ("AttributeName".equalsIgnoreCase(type)) { + valid = org.apache.commons.validator.GenericValidator + .matchRegexp(values[i], "[a-zA-Z0-9]"); // TODO: FIXME: + // VALIDATE + // REGEXP + } else if ("Coordinate".equalsIgnoreCase(type)) { + try { + valid = getPointValue(values[i]) != null; + } catch (ValidationException e) { + log.debug(e.getMessage()); + valid = false; + } + } else { + valid = false; + } + if (!valid) { + returnValue = false; + break; + } else { + returnValue = true; + } + } + log.debug("Is valid? " + returnValue); + return returnValue; + } + + + /** + * Returns a point from wkt string. + * + * @param value The wkt string. + * @return a point. + * @throws ValidationException if value is not valid. + */ + public static Point getPointValue(String value) throws ValidationException{ + log.debug("InputValidator.getPointValue " + value); + + if (value.toLowerCase().startsWith("point")){ + try { + return (Point)new WKTReader().read(value); + } catch (ParseException e) { + log.error(e,e); + throw new ValidationException(e); + } + }else{ + String[] s, p; + + double x=0,y=0; + log.info("Position :"+value); + s = value.split(" "); + if (s.length != 2) { + throw new ValidationException("Kein Blank separiert Breite und Länge"); + } + p = s[0].split("[nNsS]"); + try { + if (p.length == 1) + y = new Double(p[0]); + else + y = new Double(p[0]) + new Double(p[1]) / new Double(60.); + if (s[0].toLowerCase().contains("s")) + y = -y; + } + catch (Exception e) { + throw new ValidationException("Kein N|S oder nicht im ersten Substring, zB 56n42"); + + } + p = s[1].split("[eEwW]"); + try { + if (p.length ==1) + x = new Double(p[0]); + else + x = new Double(p[0]) + new Double(p[1]) / new Double(60.) ; + if (s[1].toLowerCase().contains("w")) + x = -x; + } + catch (Exception e) { + throw new ValidationException("Kein E|W oder nicht im zweiten Substring"); + } + return new GeometryFactory().createPoint(new Coordinate(x,y)); + } + } + + + /** + * Makes sure that tmp is between lo and up. + * + * @param tmp The value to validate. + * @param lo The lower range bound. + * @param up The upper range bound. + * @return true, if tmp is valid, otherwise false. + */ + public static boolean isDateValid(Date tmp, Date lo, Date up) { + // we need to transform the given dates into seconds, because + // they differ in milliseconds -> that's why we cannot use the + // Date.compareTo(Date) method. + long tmpTime = tmp.getTime() / 1000; + long tmpLow = lo.getTime() / 1000; + long tmpUp = up.getTime() / 1000; + + if (tmpTime < tmpLow || tmpTime > tmpUp) { + log.warn( + "Date [" + tmp.toString() + "] is out of range [" + + lo.toString() + " to "+ up.toString() + "]."); + return false; + } + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,588 @@ +package de.intevation.gnv.utils; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.ArtifactNamespaceContext; + +import de.intevation.gnv.wms.LayerInfo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; + +import org.apache.velocity.app.VelocityEngine; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This class iterates over a bunch of directories, searches for meta + * information coresponding to shapefiles and creates a mapfile which is used by + * a MapServer. + * + * @author Ingo Weinzierl + */ +public class MapfileGenerator +extends Thread +{ + /** + * The configured template path. + */ + public static final String TEMPLATE_PATH = + "/artifact-database/gnv/map-generator/templates/path/text()"; + + /** + * The configured template mapfile. + */ + public static final String TEMPLATE_MAPFILE = + "/artifact-database/gnv/map-generator/templates/maptemplate/text()"; + + /** + * The configured mapfile path. + */ + public static final String MAPFILE_PATH = + "/artifact-database/gnv/map-generator/mapfile/@path"; + + /** + * The configured shapefile base directory where the subdirectories for each + * artifact are stored. + */ + public static final String SHAPEFILE_BASE_DIR = + "/artifact-database/gnv/shapefile-directory/@path"; + + /** + * The configured velocity logfile. + */ + public static final String VELOCITY_LOGFILE = + "/artifact-database/velocity/logfile/@path"; + + /** + * The URL for calling the mapserver + */ + public static final String MAPSERVER_URL = + "/artifact-database/mapserver/server/@path"; + + /** + * The name of the file storing meta information coresponding to shapefiles. + */ + public static final String META_FILE_NAME = "meta.xml"; + + /** + * The XPath to layer nodes in the meta information xml file. + */ + public static final String XPATH_LAYER = "/art:meta/art:layer"; + + public static final String XPATH_LAYER_NAME = "art:name"; + public static final String XPATH_LAYER_TITLE = "art:title"; + public static final String XPATH_LAYER_TYPE = "art:type"; + public static final String XPATH_LAYER_DATA = "art:data"; + public static final String XPATH_LAYER_STATUS = "art:status"; + public static final String XPATH_LAYER_MODEL = "art:model"; + + protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds + + private static Logger logger = Logger.getLogger(MapfileGenerator.class); + + private static MapfileGenerator instance; + + private File mapfile; + private String mapServerUrl; + private String shapefileDirectory; + private String templatePath; + private String velocityLogfile; + + private VelocityEngine velocityEngine; + private boolean lock[]; + + + + private MapfileGenerator() { + lock = new boolean[1]; + } + + + /** + * A main method which can be used to create a mapfile without a running + * artifact server.
+ * NOTE: This method is not implemented yet! + * + * @param args Arguments. + */ + public static void main(String[] args) { + // TODO IMPLEMENT ME + } + + + /** + * Returns the instance of this generator. + * + * @return the instance. + */ + public static synchronized MapfileGenerator getInstance() { + if (instance == null) { + instance = new MapfileGenerator(); + instance.setDaemon(true); + instance.start(); + } + + return instance; + } + + + /** + * Triggers the mapfile generation process. + */ + public void update() { + synchronized (lock) { + logger.debug("update"); + lock[0] = true; + lock.notify(); + } + } + + + /** + * Thread to generate a mapfile. + */ + @Override + public void run() { + logger.debug("Start MapfileGenerator thread..."); + try { + for (;;) { + synchronized (lock) { + while (!lock[0]) { + lock.wait(SLEEPTIME); + } + lock[0] = false; + } + + logger.debug("Start sync process now..."); + generate(); + } + } + catch (InterruptedException ie) { + logger.debug("MapfileGenerator thread got an interrupt."); + } + finally { + logger.debug("THREAD END"); + } + } + + /** + * Method to check the existance of a template file. + * + * @param templateID The name of a template. + * @return true, of the template exists - otherwise false. + */ + public boolean templateExists(String templateID){ + Template template = getTemplateByName(templateID); + return template != null; + } + + + /** + * Method which starts searching for meta information file and mapfile + * generation. + */ + protected void generate() { + File basedir = new File(getShapefileBaseDir()); + List layers = new ArrayList(); + searchMetaInformation(basedir, layers); + writeMapfile(layers); + } + + + /** + * Returns the VelocityEngine used for the template mechanism. + * + * @return the velocity engine. + */ + protected VelocityEngine getVelocityEngine() { + if (velocityEngine == null) { + velocityEngine = new VelocityEngine(); + try { + setupVelocity(velocityEngine); + } + catch (Exception e) { + logger.error(e, e); + return null; + } + } + return velocityEngine; + } + + + /** + * Initialize velocity. + * + * @param engine Velocity engine. + * @throws Exception if an error occured while initializing velocity. + */ + protected void setupVelocity(VelocityEngine engine) + throws Exception + { + engine.setProperty( + "input.encoding", + "UTF-8"); + + engine.setProperty( + VelocityEngine.RUNTIME_LOG, + getVelocityLogfile()); + + engine.setProperty( + "resource.loader", + "file"); + + engine.setProperty( + "file.resource.loader.path", + getTemplateBaseDir()); + + engine.init(); + } + + + /** + * Returns the path specifying the logfile for velocity. + * + * @return Velocity logfile path. + */ + protected String getVelocityLogfile() { + if (velocityLogfile == null) + velocityLogfile = Config.getStringXPath(VELOCITY_LOGFILE); + + return velocityLogfile; + } + + + /** + * Returns the base directory storing the templates. + * + * @return the template base directory. + */ + protected String getTemplateBaseDir() { + if (templatePath == null) { + templatePath = Config.getStringXPath(TEMPLATE_PATH); + templatePath = Config.replaceConfigDir(templatePath); + } + + return templatePath; + } + + + /** + * Returns the URL for calling the MapServer. + * + * @return the url for calling the MapServer. + */ + protected String getMapServerUrl() { + if (mapServerUrl == null) { + mapServerUrl = Config.getStringXPath(MAPSERVER_URL); + mapServerUrl = Config.replaceConfigDir(mapServerUrl); + } + + return mapServerUrl; + } + + + /** + * Returns a template specified by model. + * + * @param model The name of the template. + * @return a template. + */ + protected Template getTemplateByName(String model) { + if (model.indexOf(".vm") < 0) { + model = model.concat(".vm"); + } + + try { + VelocityEngine engine = getVelocityEngine(); + if (engine == null) { + logger.error("Error while fetching VelocityEngine."); + return null; + } + + return engine.getTemplate(model); + } + catch (Exception e) { + logger.warn(e, e); + } + + return null; + } + + + /** + * Returns the mapfile template. + * + * @return the mapfile template. + * @throws Exception if an error occured while reading the configuration. + */ + protected Template getMapfileTemplate() + throws Exception + { + String mapfileName = Config.getStringXPath(TEMPLATE_MAPFILE); + return getTemplateByName(mapfileName); + } + + + /** + * Returns the base directory storing the shapefiles. + * + * @return the shapefile base directory. + */ + protected String getShapefileBaseDir() { + if (shapefileDirectory == null) { + shapefileDirectory = Config.getStringXPath(SHAPEFILE_BASE_DIR); + shapefileDirectory = Config.replaceConfigDir(shapefileDirectory); + } + + return shapefileDirectory; + } + + + /** + * Returns the mapfile. + * + * @return the mapfile. + */ + protected File getMapfile() { + if (mapfile == null) { + String tmp = Config.getStringXPath(MAPFILE_PATH); + tmp = Config.replaceConfigDir(tmp); + mapfile = new File(tmp); + } + + return mapfile; + } + + + /** + * Search for meta information file in file and store the layer + * information in store if a meta file was found. + * + * @param file The root directory to be searched for meta files. + * @param store A list storing LayerInfo objects. + */ + protected void searchMetaInformation(File file, List store) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + + if (files != null && files.length != 0) { + int size = files.length; + for (File tmp: files) { + searchMetaInformation(tmp, store); + } + } + } + else if (file.getName().equals(META_FILE_NAME)) { + LayerInfo[] info = parseMeta(file); + + int infoSize = info.length; + for (int j = 0; j < infoSize; j++) { + if (info[j] != null) { + store.add(info[j]); + } + } + } + } + + + /** + * Parses a meta information file and returns necessary information as + * LayerInfo array. + * + * @param file Meta information file. + * @return Array of LayerInfo objects. + */ + protected LayerInfo[] parseMeta(File file) { + Document meta = XMLUtils.parseDocument(file); + List layers = new ArrayList(); + + NodeList layerset = (NodeList) XMLUtils.xpath( + meta, + XPATH_LAYER, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int size = layerset.getLength(); + for (int i = 0; i < size; i++) { + LayerInfo info = parseLayer(layerset.item(i)); + + if (info != null && !info.isEmpty() && !info.isBroken()) { + layers.add(info); + } + else { + logger.warn("Found broken LayerInfo object."); + } + } + + return (LayerInfo[]) layers.toArray(new LayerInfo[layers.size()]); + } + + + /** + * Parses a node storing layer information and returns them. + * + * @param layer Node storing information about a layer. + * @return a LayerInfo object. + */ + protected LayerInfo parseLayer(Node layer) { + LayerInfo info = new LayerInfo(); + + String name = parseLayerAttr(layer, XPATH_LAYER_NAME); + if (name != null && !name.equals("")) { + info.setName(name); + } + + String title = parseLayerAttr(layer, XPATH_LAYER_TITLE); + if (title != null && !title.equals("")) { + info.setTitle(title); + } + else { + info.setTitle(name); + } + + String model = parseLayerAttr(layer, XPATH_LAYER_MODEL); + if (model != null && !model.equals("")) { + info.setModel(model); + } + + String type = parseLayerAttr(layer, XPATH_LAYER_TYPE); + if (type != null && !type.equals("")) { + info.setType(type); + } + + String data = parseLayerAttr(layer, XPATH_LAYER_DATA); + if (data != null && !data.equals("")) { + info.setData(data); + } + + String status = parseLayerAttr(layer, XPATH_LAYER_STATUS); + if (status != null && !status.equals("")) { + info.setStatus(status); + } + + return info; + } + + + /** + * Parses attributes in layer nodes. + * + * @param node A node containing layer information. + * @param xpath XPath specifying an attribute. + * @return Attribute as string. + */ + protected String parseLayerAttr(Node node, String xpath) { + return (String) XMLUtils.xpath( + node, + xpath, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * Creates a mapfile with the layer information stored in layers. + * + * @param layers Layer information. + */ + protected void writeMapfile(List layers) { + String tmpMapName = "mapfile" + new Date().getTime(); + + int layersize = layers.size(); + StringBuilder sb = new StringBuilder(); + StringWriter sw = null; + LayerInfo info = null; + + for (int i = 0; i < layersize; i++) { + sw = new StringWriter(); + info = (LayerInfo) layers.get(i); + + Template layerTemplate = getTemplateByName(info.getModel()); + VelocityContext context = new VelocityContext(); + context.put("info", info); + + try { + layerTemplate.merge(context, sw); + sb.append(sw.toString()); + } + catch (IOException ioe) { + logger.warn("Error while filling layer template."); + logger.warn(ioe, ioe); + } + } + + File map = getMapfile(); + Writer writer = null; + File tmp = null; + + try { + tmp = new File(map.getParent(), tmpMapName); + + tmp.createNewFile(); + writer = new FileWriter(tmp); + + VelocityContext context = new VelocityContext(); + context.put("MAPSERVERURL", getMapServerUrl()); + context.put("LAYERS", sb.toString()); + + Template mapTemplate = getMapfileTemplate(); + if (mapTemplate == null) { + logger.warn("No mapfile template found."); + return; + } + + mapTemplate.merge(context, writer); + + // we need to create a temporary mapfile first und rename it into + // real mapfile because we don't run into race conditions on this + // way. (iw) + tmp.renameTo(map); + } + catch (FileNotFoundException fnfe) { + logger.error(fnfe, fnfe); + } + catch (IOException ioe) { + logger.error(ioe, ioe); + } + catch (Exception e) { + logger.error(e, e); + } + finally { + try { + // close file writer + if (writer != null) { + writer.close(); + } + + // remove temporary mapfile if an error occured and it still + // exists + if (tmp.exists()) { + tmp.delete(); + } + } + catch (IOException ioe) { + logger.debug(ioe, ioe); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/MetaWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/MetaWriter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,375 @@ +package de.intevation.gnv.utils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Date; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.wms.LayerInfo; + +/** + * This class provides some methods to create files storing meta information + * about wms layers and a map service which serves these layers. + * + * @author Ingo Weinzierl + */ +public class MetaWriter { + + private static Logger logger = Logger.getLogger(MetaWriter.class); + + public static final String NODE_MAPSERVER = "mapserver"; + public static final String NODE_SERVER = "server"; + public static final String NODE_MAP = "map"; + public static final String NODE_TTL = "ttl"; + + public static final String META_FILE_NAME = "meta.xml"; + public static final String ISOLINES_NAME = "isolines.shp"; + public static final String POLYGON_NAME = "polygons.shp"; + + + public static final String CONTEXT_LAYER_TITLE = "wms.title"; + + /** + * Constructor. + */ + private MetaWriter() { + } + + /** + * Writes a meta information file for product type 'Layer'. + * + * @param context CallContext object. + * @param meta the document where the information should be placed in. + * @return the meta document. + */ + public static Node writeLayerMeta(CallContext context, Document meta){ + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + meta, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + Element root = creator.create("meta"); + meta.appendChild(root); + + writeAbstractMeta(context, meta, root); + return root; + } + + + /** + * Writes a meta information file for product type 'Horizontalschnitt'. + * + * @param context The CallContext object. + * @param uuid The UUID of the current artifact. + * @param path The destination of the meta file. + * @param paramType The parameter type. + * @return the meta document. + */ + public static Document writeHorizontalcrosssectionMeta( + CallContext context, + String uuid, + String path, + String paramType) + { + Document meta = XMLUtils.newDocument(); + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + meta, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element root = creator.create("meta"); + meta.appendChild(root); + + writeAbstractMeta(context, meta, root); + writePolygonMeta(context, meta, root, uuid, paramType); + writeIsolineMeta(context, meta, root, uuid, paramType); + + boolean success = writeMetaFile(path, meta); + + if (success){ + return meta; + }else{ + return null; + } + } + + /** + * Method to write the meta document down to a file. + * + * @param path The destination of the file. + * @param meta The xml document storing the meta information. + */ + public static boolean writeMetaFile(String path, Document meta) { + try { + File metaFile = new File(path, META_FILE_NAME); + + if (metaFile.exists()) { + logger.info("Delete old meta information file."); + metaFile.delete(); + } + + if (!metaFile.createNewFile() || !metaFile.canWrite()) { + logger.error("Error while writing meta file: "+metaFile.toString()); + return false; + } + + OutputStream out = null; + boolean success = false; + try { + out = new FileOutputStream(metaFile); + success = XMLUtils.toStream(meta, out); + } + finally { + if (out != null) { + try { out.close(); } + catch (IOException ioe) {} + } + } + + if (!success && metaFile.exists()) { + metaFile.delete(); + } + + return success; + } + catch (FileNotFoundException fnfe) { + logger.error(fnfe); + return false; + } + catch (IOException ioe) { + logger.error(ioe, ioe); + return false; + } + } + + + /** + * Append meta information about the mapservice itself. + * + * @param callContext The CallContext object. + * @param document The meta information document. + * @param meta The element where the new information need to be appended to. + */ + public static void writeAbstractMeta( + CallContext callContext, + Document document, + Element meta + ) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + GNVArtifactContext context = + (GNVArtifactContext) callContext.globalContext(); + + String server = (String) + context.get(GNVArtifactContext.MAPSERVER_SERVER_PATH_KEY); + + String map = (String) + context.get(GNVArtifactContext.MAPSERVER_MAP_PATH_KEY); + + if (logger.isDebugEnabled()) { + logger.debug("MAPSERVER PATH: " + server); + logger.debug("MAP PATH: " + map); + } + + Element mapserver = creator.create(NODE_MAPSERVER); + Element serverPath = creator.create(NODE_SERVER); + Element mapPath = creator.create(NODE_MAP); + + mapPath.setTextContent(map); + serverPath.setTextContent(server); + + mapserver.appendChild(serverPath); + mapserver.appendChild(mapPath); + meta.appendChild(mapserver); + } + + /** + * Append layer information to the meta document. + * + * @param callContext The CallContext object. + * @param document The meta document. + * @param root The element where the new information need to be appended to. + * @param uuid The UUID of the current artifact. + * @param paramType The parameter type (e.g. salinity). + * @param layerType The layer type. + * @param shapefileName the name of the Shapefile + * @param shapefileName the Title of the Layer + */ + public static void writeLayerMeta( + CallContext callContext, + Document document, + Node root, + String uuid, + String paramType, + String layerType, + String shapefileName, + String layerTitle + ) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Long time = callContext.getTimeToLive(); + time = time != null ? time + new Date().getTime() : null; + String ttl = time != null ? time.toString() : null; + + logger.debug("Artifacts time to live: " + ttl); + + Element layer = creator.create(LayerInfo.LAYER); + Element model = creator.create(LayerInfo.LAYER_MODEL); + Element name = creator.create(LayerInfo.LAYER_NAME); + Element title = creator.create(LayerInfo.LAYER_TITLE); + Element type = creator.create(LayerInfo.LAYER_TYPE); + Element status = creator.create(LayerInfo.LAYER_STATUS); + Element data = creator.create(LayerInfo.LAYER_DATA); + Element timeToLive = creator.create(NODE_TTL); + + model.setTextContent(paramType); + name.setTextContent(uuid); + type.setTextContent(layerType); + status.setTextContent("OFF"); + data.setTextContent(shapefileName); + timeToLive.setTextContent(ttl); + + title.setTextContent(layerTitle); + + layer.appendChild(model); + layer.appendChild(name); + layer.appendChild(title); + layer.appendChild(type); + layer.appendChild(status); + layer.appendChild(data); + layer.appendChild(timeToLive); + + root.appendChild(layer); + } + + + /** + * Append polygon layer information to meta document. + * + * @param context + * @param document The meta document. + * @param meta The element where the new information need to be appended to. + * @param uuid The UUID of the current artifact. + * @param paramType The parameter type (e.g. salinity). + */ + public static void writePolygonMeta( + CallContext context, + Document document, + Element meta, + String uuid, + String paramType + ) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Long time = context.getTimeToLive(); + time = time != null ? time + new Date().getTime() : null; + String ttl = time != null ? time.toString() : null; + + logger.debug("Artifacts time to live: " + ttl); + + Element layer = creator.create(LayerInfo.LAYER); + Element model = creator.create(LayerInfo.LAYER_MODEL); + Element name = creator.create(LayerInfo.LAYER_NAME); + Element title = creator.create(LayerInfo.LAYER_TITLE); + Element type = creator.create(LayerInfo.LAYER_TYPE); + Element status = creator.create(LayerInfo.LAYER_STATUS); + Element data = creator.create(LayerInfo.LAYER_DATA); + Element timeToLive = creator.create(NODE_TTL); + + model.setTextContent(paramType); + name.setTextContent(uuid); + title.setTextContent( + (String) context.getContextValue(CONTEXT_LAYER_TITLE)); + type.setTextContent("POLYGON"); + status.setTextContent("OFF"); + data.setTextContent(POLYGON_NAME); + timeToLive.setTextContent(ttl); + + layer.appendChild(model); + layer.appendChild(name); + layer.appendChild(title); + layer.appendChild(type); + layer.appendChild(status); + layer.appendChild(data); + layer.appendChild(timeToLive); + + meta.appendChild(layer); + } + + + /** + * Append isoline layer information to meta document. + * + * @param context + * @param document The meta document. + * @param meta The element where the new information need to be appended to. + * @param uuid The UUID of the current artifact. + * @param paramType The parameter type (e.g. salinity). + */ + public static void writeIsolineMeta( + CallContext context, + Document document, + Element meta, + String uuid, + String paramType + ) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Long time = context.getTimeToLive(); + time = time != null ? time + new Date().getTime() : null; + String ttl = time != null ? time.toString() : null; + + logger.debug("Artifacts time to live: " + ttl); + + Element layer = creator.create(LayerInfo.LAYER); + Element model = creator.create(LayerInfo.LAYER_MODEL); + Element name = creator.create(LayerInfo.LAYER_NAME); + Element title = creator.create(LayerInfo.LAYER_TITLE); + Element type = creator.create(LayerInfo.LAYER_TYPE); + Element status = creator.create(LayerInfo.LAYER_STATUS); + Element data = creator.create(LayerInfo.LAYER_DATA); + Element timeToLive = creator.create(NODE_TTL); + + model.setTextContent(paramType+"_isolines"); + name.setTextContent(uuid); + title.setTextContent( + (String) context.getContextValue(CONTEXT_LAYER_TITLE)); + type.setTextContent("LINE"); + status.setTextContent("OFF"); + data.setTextContent(ISOLINES_NAME); + timeToLive.setTextContent(ttl); + + layer.appendChild(model); + layer.appendChild(name); + layer.appendChild(title); + layer.appendChild(type); + layer.appendChild(status); + layer.appendChild(data); + layer.appendChild(timeToLive); + + meta.appendChild(layer); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/Pair.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/Pair.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,32 @@ +package de.intevation.gnv.utils; + +import java.io.Serializable; + +/** + * @param + * @param + * @author Sascha L. Teichmann + */ +public final class Pair +implements Serializable +{ + private A a; + private B b; + + private Pair() { + } + + public Pair(A a, B b) { + this.a = a; + this.b = b; + } + + public A getA() { + return a; + } + + public B getB() { + return b; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,487 @@ +package de.intevation.gnv.utils; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.text.NumberFormat; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.geotools.data.DataStoreFactorySpi; +import org.geotools.data.DataUtilities; +import org.geotools.data.DefaultTransaction; +import org.geotools.data.FeatureStore; +import org.geotools.data.Transaction; +import org.geotools.data.shapefile.ShapefileDataStore; +import org.geotools.data.shapefile.ShapefileDataStoreFactory; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.FeatureCollections; +import org.geotools.feature.SchemaException; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +/** + * @author Sascha L. Teichmann + */ +public final class ShapeFileWriter +{ + private static Logger log = Logger.getLogger( + ShapeFileWriter.class); + + private static NumberFormat format = NumberFormat.getInstance(); + + /** + * Precision used to format double values. + */ + public static final int DOUBLE_PRECISION = 3; + + static { + format.setMaximumFractionDigits(DOUBLE_PRECISION); + } + + private ShapeFileWriter() { + } + + + /** + * Write multilinestrings to shapefile. + * + * @param shapeFile Shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiLineStrings The multilinestring. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiLineStringsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + List> multiLineStrings + ) { + return writeMultiLineStringsToFile( + shapeFile, + parameterId, + layer, + date, + multiLineStrings, + "isolines"); + } + + + /** + * Write multilinestrings to shapefile. + * + * @param shapeFile Shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiLineStrings The multilinestring. + * @param name A name. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiLineStringsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + List> multiLineStrings, + String name + ) { + Map params = new HashMap(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType TYPE; + + try { + TYPE = DataUtilities.createType( + name, + "geom:MultiLineString:srid=4326," + + "PARAMETER:Integer," + + "LAYER:Integer," + + "DATE:Date," + + "VALUE:Double," + + "DESC:String"); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + + SimpleFeatureBuilder featureBuilder = + new SimpleFeatureBuilder(TYPE); + + FeatureCollection collection = + FeatureCollections.newCollection(); + + for (Pair pair: multiLineStrings) { + featureBuilder.add(pair.getB()); + featureBuilder.add(parameterId); + featureBuilder.add(layer); + featureBuilder.add(date); + featureBuilder.add(pair.getA()); + featureBuilder.add(value2description(asDouble(pair.getA()))); + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(TYPE); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore featureStore = + (FeatureStore) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return success; + } + + + /** + * Write multipolygon to file. + * + * @param shapeFile The shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiPolygons Multipolygons. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiPolygonsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + Map multiPolygons + ) { + return writeMultiPolygonsToFile( + shapeFile, + parameterId, + layer, + date, + multiPolygons, + "polygons"); + } + + + /** + * Write data to shapefile. + * + * @param shapeFile The shapefile. + * @param name The name. + * @param data The data. + * @param geometryType The geometry type. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeDataToFile(File shapeFile, + String name, + Collection data, + String geometryType){ + + WKTReader wktReader = new WKTReader(); + + Map params = new HashMap(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType type = null; + SimpleFeatureBuilder featureBuilder = null; + FeatureCollection collection = + FeatureCollections.newCollection(); + int j = 0; + for (Result result: data) { + j++; + try { + Geometry g = wktReader.read(result.getString(0)); + ResultDescriptor rd = result.getResultDescriptor(); + int columns = rd.getColumnCount(); + if (type == null){ + try { + String schema = "geom:"+geometryType+":srid=4326"; + for (int i = 1; i < columns; i++){ + schema+=","+rd.getColumnName(i)+ + ":"+rd.getColumnClassName(i); + } + type = DataUtilities.createType(name, schema); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + featureBuilder = new SimpleFeatureBuilder(type); + } + featureBuilder.add(g); + for (int i = 1; i < columns; i++){ + featureBuilder.add(result.getObject(i)); + } + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } catch (ParseException e) { + log.error("cannot create geometry "+j+" for "+result.getString(0)); + } catch (java.lang.IllegalArgumentException e){ + log.error("cannot create geometry for "+result.getString(0)); + } + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(type); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore featureStore = + (FeatureStore) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return true; + } + + + /** + * Write multipolygons to file. + * + * @param shapeFile The shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiPolygons Multipolygons. + * @param name A name. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiPolygonsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + Map multiPolygons, + String name + ) { + Map params = new HashMap(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType TYPE; + + try { + TYPE = DataUtilities.createType( + name, + "geom:MultiPolygon:srid=4326," + + "PARAMETER:Integer," + + "LAYER:Integer," + + "DATE:Date," + + "CLASS:Integer"); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + + SimpleFeatureBuilder featureBuilder = + new SimpleFeatureBuilder(TYPE); + + FeatureCollection collection = + FeatureCollections.newCollection(); + + for (Map.Entry entry: + multiPolygons.entrySet() + ) { + featureBuilder.add(entry.getValue()); + featureBuilder.add(parameterId); + featureBuilder.add(layer); + featureBuilder.add(date); + featureBuilder.add(entry.getKey()); + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(TYPE); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore featureStore = + (FeatureStore) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return success; + } + + /** + * Returns an object as Double. + * + * @param a An object. + * @return Object a as Double. If a is not a double and no + * number, 0d is returned. + */ + private static final Double asDouble(Object a) { + if (a instanceof Double) { + return (Double)a; + } + if (a instanceof Number) { + return Double.valueOf(((Number)a).doubleValue()); + } + return 0d; + } + + /** + * Turns a double value into a string representation taking account of the + * locale. + * + * @param value A double value. + * @return The double value formatted as string. + */ + private static final String value2description(Double value) { + return format.format(value); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/StringUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/StringUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,61 @@ +package de.intevation.gnv.utils; + +/** + * Helper class which supports some methods for working with strings. + * + * @author Sascha L. Teichmann + */ +public final class StringUtils +{ + private StringUtils() { + } + + /** + * Append a string to a string array. + * + * @param haystack String array. + * @param straw String to append. + * @return the new string array. + */ + public static final String [] append(String [] haystack, String straw) { + if (haystack == null) { + return new String [] { straw }; + } + String [] nhaystack = new String[haystack.length + 1]; + System.arraycopy(haystack, 0, nhaystack, 0, haystack.length); + nhaystack[haystack.length] = straw; + return nhaystack; + } + + /** + * Checks the existence of a string in a given string array. + * + * @param haystack String array. + * @param needle String for being checked. + * @return true, if the string is contained in haystack - else false. + */ + public static final boolean contains(String [] haystack, String needle) { + if (haystack == null) { + return false; + } + + if (needle == null) { + for (int i = haystack.length - 1; i >= 0; --i) { + if (haystack[i] == null) { + return true; + } + } + } + else { + for (int i = haystack.length - 1; i >= 0; --i) { + String straw = haystack[i]; + if (straw != null && straw.equals(needle)) { + return true; + } + } + } + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/WKTUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/WKTUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,497 @@ +package de.intevation.gnv.utils; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import de.intevation.gnv.math.LinearFunction; + +import java.text.MessageFormat; +import java.text.NumberFormat; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.math.FunctionEvaluationException; + +import org.apache.commons.math.optimization.OptimizationException; + +import org.apache.commons.math.optimization.fitting.CurveFitter; + +import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; + +import org.apache.log4j.Logger; + +/** + * A helper class which supports some useful methods to work with wkt strings. + * + * @author Ingo Weinzierl + */ +public abstract class WKTUtils { + + private static Logger log = Logger.getLogger(WKTUtils.class); + + public static final double NAUTICAL_MILE = 1852.216d; + public static final double KILOMETER = 1000d; + + public static final String I_NAME = "MEDIAN.MESHPOINT.IPOSITION"; + public static final String J_NAME = "MEDIAN.MESHPOINT.JPOSITION"; + + public static final String TRUE_EXPRESSION = "FEATUREID=FEATUREID"; + + public static final String[] COORDINATE_OUT_FORMAT = { + "coordinate.template.northeast", + "coordinate.template.southeast", + "coordinate.template.northwest", + "coordinate.template.southwest" + }; + + public static final String DEFAULT_COORDINATE_TEMPLATE = + "{0}\u00b0N {1}'' {2}\u00b0E {3}''"; + + /** + * Checks the difference of two Results. + * + * @param a A Result. + * @param b Another Result. + * @param indices Indices to be checked. + * @return true, if a and b are different - otherwise false. + */ + public static boolean different(Result a, Result b, int [] indices) { + for (int i = 0; i < indices.length; ++i) { + String oa = a.getString(indices[i]); + String ob = b.getString(indices[i]); + + if (oa == null && ob == null) { + continue; + } + + if (oa == null || ob == null) { + return true; + } + + if (!oa.equals(ob)) { + return true; + } + } + return false; + } + + /** + * Turns a wkt string into a coordinate. + * + * @param shape A wkt string. + * @return wkt string as coordinate. + */ + public static Coordinate toCoordinate(String shape) { + try { + return shape != null + ? ((Point)(new WKTReader().read(shape))).getCoordinate() + : null; + } + catch (ParseException pe) { + log.error(pe); + } + catch (ClassCastException cce) { + log.error("cannot read WKT point", cce); + } + return null; + } + + /** + * Turns a wkt string into a polygon. + * + * @param shape A wkt string. + * @return wkt string as polygon. + */ + public static Polygon toPolygon(String shape) { + try { + return (Polygon)new WKTReader().read(shape); + } + catch (ParseException pe) { + log.error(pe); + } + catch (ClassCastException cce) { + log.error("cannot read WKT polygon", cce); + } + return null; + } + + /** + * Returns a distance in km. + * + * @param distance A distance. + * @return distance in km. + */ + public static final double toKM(double distance) { + return (distance * NAUTICAL_MILE) / KILOMETER; + } + + + /** + * Turns a coordinate into a wkt string. + * + * @param coordinate A coordinate. + * @return the coordinate as wkt string. + */ + public static String toWKT(Coordinate coordinate) { + StringBuilder sb = new StringBuilder("POINT("); + sb.append(coordinate.x) + .append(' ') + .append(coordinate.y) + .append(')'); + return sb.toString(); + } + + + public static final String indexBox( + java.awt.Point a, + java.awt.Point b, + String iName, + String jName + ) { + int minI = Math.min(a.x, b.x) - 1; + int maxI = Math.max(a.x, b.x) + 1; + int minJ = Math.min(a.y, b.y) - 1; + int maxJ = Math.max(a.y, b.y) + 1; + StringBuilder sb = new StringBuilder("(") + .append(iName).append(" >= ").append(minI) + .append(" AND ").append(iName).append(" <= ").append(maxI) + .append(" AND ").append(jName).append(" >= ").append(minJ) + .append(" AND ").append(jName).append(" <= ").append(maxJ) + .append(')'); + return sb.toString(); + } + + public static final String diagonalBox(List points) { + + if (points.get(0) != null && points.get(2) != null) { + return indexBox( + points.get(0), points.get(2), + I_NAME, + J_NAME); + } + + if (points.get(1) != null && points.get(3) != null) { + return indexBox( + points.get(1), points.get(3), + I_NAME, + J_NAME); + } + + return null; + } + + public static String worldEnvelopeCoordinatesToIndex( + Coordinate [] coords, + String meshid, + String ijkQueryID + ) + throws QueryException + { + List points = + new ArrayList(coords.length); + + ArrayList missingPoints = + new ArrayList(); + + createIJKPoints(coords, meshid, ijkQueryID, points, missingPoints); + + String additionWhere = null; + + if (missingPoints.size() == coords.length) { + log.debug("cannot create index buffer"); + } + else { + additionWhere = diagonalBox(points); + + if (additionWhere == null) { + // 3 Points are missing or are on one side of the envelope + boolean remainsMissingPoints = calculateIJ4MissingPoints( + coords, points, missingPoints); + + if (!remainsMissingPoints) { + additionWhere = diagonalBox(points); + } + } + } + + return additionWhere != null + ? additionWhere + : TRUE_EXPRESSION; + } + + public static String worldCoordinatesToIndex( + Coordinate [] coords, + Collection result, + String meshid, + String ijkQueryID + ) + throws QueryException + { + List points = new ArrayList(coords.length); + + ArrayList missingPoints = new ArrayList(); + + createIJKPoints(coords, meshid, ijkQueryID, points, missingPoints); + + String additionWhere = TRUE_EXPRESSION; + + if (missingPoints.size() == coords.length) { + log.debug("cannot create index buffer"); + } + else { // generate index filter + boolean remainsMissingPoints = calculateIJ4MissingPoints( + coords, points, missingPoints); + + if (!remainsMissingPoints) { + // TODO: Make Tablenames and Columns Configurable + IndexBuffer ib = new IndexBuffer( + points, + I_NAME, + J_NAME ); + additionWhere = ib.toWhereClause(); + log.debug("Additional Where Clause = "+additionWhere); + } + } // if generate index filter + + return additionWhere; + } + + + /** + * @param coords + * @param points + * @param missingPoints + * @return + */ + private static boolean calculateIJ4MissingPoints( + Coordinate [] coords, + List points, + ArrayList missingPoints + ) { + boolean remainsMissingPoints = !missingPoints.isEmpty(); + + if (remainsMissingPoints) { + // try to guess the missing (i, j) + CurveFitter iFitter = new CurveFitter(new GaussNewtonOptimizer(true)); + CurveFitter jFitter = new CurveFitter(new GaussNewtonOptimizer(true)); + + for (int i = 0, N = points.size(); i < N; ++i) { + java.awt.Point p = (java.awt.Point)points.get(i); + if (p != null) { + Coordinate coord = coords[i]; + iFitter.addObservedPoint(coord.x, p.x); + jFitter.addObservedPoint(coord.y, p.y); + } + } + try { + // XXX: Assumption: (i, j) are created by componentwise linear function. + // This is surely not correct because (x, y) are in a ellipsoid projection. + // TODO: use ellipsoid functions and fit with Levenberg Marquardt. + double [] iParams = iFitter.fit( + LinearFunction.INSTANCE, new double [] { 1d, 1d }); + + double [] jParams = jFitter.fit( + LinearFunction.INSTANCE, new double [] { 1d, 1d }); + + for (int i = missingPoints.size()-1; i >= 0; --i) { + Object [] a = (Object [])missingPoints.get(i); + Coordinate coord = (Coordinate)a[1]; + int pi = (int)Math.round(iParams[0]*coord.x + iParams[1]); + int pj = (int)Math.round(jParams[0]*coord.y + jParams[1]); + points.set( + ((Integer)a[0]).intValue(), + new java.awt.Point(pi, pj)); + } + + remainsMissingPoints = false; // we filled the gaps + } + catch (FunctionEvaluationException fee) { + log.error(fee); + } + catch (OptimizationException oe) { + log.error(oe); + } + } + return remainsMissingPoints; + } + + + /** + * @param coords + * @param meshid + * @param ijkQueryID + * @param points + * @param missingPoints + * @throws QueryException + */ + private static void createIJKPoints( + Coordinate[] coords, + String meshid, + String ijkQueryID, + List points, + ArrayList missingPoints + ) + throws QueryException + { + boolean debug = log.isDebugEnabled(); + + QueryExecutor queryExecutor = QueryExecutorFactory + .getInstance() + .getQueryExecutor(); + + for (int i = 0; i < coords.length; i++) { + + String wkt = toWKT(coords[i]); + + Collection result = queryExecutor.executeQuery( + ijkQueryID, + new String [] {meshid, wkt}); + + if (!result.isEmpty()) { + Result resultValue = result.iterator().next(); + int iPos = resultValue.getInteger(1); + int jPos = resultValue.getInteger(0); + if (debug) { + log.debug("Found Pos "+iPos+"/"+jPos +" for "+wkt); + } + points.add(i, new java.awt.Point(iPos,jPos)); + } + else { + if (debug) { + log.debug("No i/j Pos found for "+wkt); + } + missingPoints.add(new Object [] { Integer.valueOf(i), coords[i] }); + points.add(i, null); + // Special Case no i,j found for Coordinate + } + } + } + + public static Coordinate [] toCoordinates(String wkt) { + try { + LineString ls = (LineString)new WKTReader().read(wkt); + return ls.getCoordinates(); + } + catch (ParseException pe) { + log.error("cannot read WKT line string", pe); + } + catch (ClassCastException cce) { + log.error("cannot read WKT line string", cce); + } + return null; + } + + /** + * Turns a wkt coordinate into a string format using the default locale of + * the virtual machine. + * + * @param wkt A wkt coordinate. + * @return A formatted coordinate. + */ + public static String toText(String wkt) { + return toText(Locale.getDefault(), wkt); + } + + /** + * Turns a point into a string format using the default locale of the + * virtual machine. + * + * @param p A point. + * @return A point formatted as string. + */ + public static String toText(Point p) { + return toText(Locale.getDefault(), toWKT(p.getCoordinate())); + } + + /** + * Turns a point into a string format using a given locale. + * + * @param locale A locale. + * @param p A point. + * @return a point formatted as string. + */ + public static String toText(Locale locale, Point p) { + return toText(locale, toWKT(p.getCoordinate())); + } + + /** + * Turns a wkt coordiante into a formatted text using a given locale. + * + * @param locale A locale. + * @param wkt A wkt coordinate. + * @return a formatted coordinate. + */ + public static String toText(Locale locale, String wkt) { + String formattedCoordinate = null; + try { + Point p = (Point)new WKTReader().read(wkt); + double lat = p.getY(); + double lon =p.getX(); + + int choice = 0; + + if (lat <0 ) { + choice += 1; + lat=-lat; + } + + if (lon <0 ) { + choice += 2; + lon=-lon; + } + + RessourceFactory factory = RessourceFactory.getInstance(); + String template = factory.getRessource( + locale, + COORDINATE_OUT_FORMAT[choice], + DEFAULT_COORDINATE_TEMPLATE + ); + + NumberFormat minFormatter = NumberFormat.getInstance(locale); + minFormatter.setMaximumFractionDigits(3); + minFormatter.setMinimumFractionDigits(3); + + String minLat = minFormatter.format(60.*(lat-((int)lat))); + String minLon = minFormatter.format(60.*(lon-((int)lon))); + + NumberFormat degFormatter = NumberFormat.getInstance(locale); + degFormatter.setMinimumIntegerDigits(2); + + String formLat = degFormatter.format((int)lat); + String formLon = degFormatter.format((int)lon); + + MessageFormat formatter = new MessageFormat(template); + + Object[] args = { + formLat, minLat, + formLon, minLon + }; + + return formatter.format(args); + + } + catch (ParseException e) { + log.warn(e,e); + } + + return null; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/exception/ValidationException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/exception/ValidationException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,46 @@ +package de.intevation.gnv.utils.exception; + +/** + * @author Tim Englich + * + */ +public class ValidationException extends Exception { + + /** + * The Uid of this Class + */ + private static final long serialVersionUID = -6189218101861801079L; + + /** + * Constructor + */ + public ValidationException() { + super(); + } + + /** + * Constructor + * @param arg0 + */ + public ValidationException(String arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + */ + public ValidationException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public ValidationException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Exception classes used by helper classes in the utils package. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/utils/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +This package provides some helper classes used across the whole software. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/wms/LayerInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/wms/LayerInfo.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,218 @@ +package de.intevation.gnv.wms; + +/** + * This class is used to store some meta information about a layer (e.g. a WMS + * layers). + * + * @author Ingo Weinzierl + */ +public class LayerInfo { + + /** + * Constant field LAYER + */ + public static final String LAYER = "layer"; + + /** + * Constant field LAYER_MODEL + */ + public static final String LAYER_MODEL = "model"; + + /** + * Constant field LAYER_NAME + */ + public static final String LAYER_NAME = "name"; + + /** + * Constant field LAYER_TYPE + */ + public static final String LAYER_TYPE = "type"; + + /** + * Constant field LAYER_DATA + */ + public static final String LAYER_DATA = "data"; + + /** + * Constant field LAYER_STATUS + */ + public static final String LAYER_STATUS = "status"; + + /** + * Constant field LAYER_TITLE + */ + public static final String LAYER_TITLE = "title"; + + /** + * Field storing the layer name. + */ + private String name; + + /** + * Field storing the layer title. + */ + private String title; + + /** + * Field storing the layer type. + */ + private String type; + + /** + * Field storing the layer data. + */ + private String data; + + /** + * Field storing the layer status. + */ + private String status; + + /** + * Field storing the layer model. + */ + private String model; + + + /** + * Constructs an empty object. All parameters should be set via setter + * methods. + */ + public LayerInfo() { + } + + + /** + * Set {@link #data} to data. + * + * @param data + */ + public void setData(String data) { + this.data = data; + } + + /** + * Get {@link #data} + * + * @return data + */ + public String getData() { + return data; + } + + /** + * Set {@link #name} to name. + * + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Get {@link #name} + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Set {@link #title} to title. + * + * @param title + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * Get {@link #title} + * + * @return title + */ + public String getTitle() { + return title; + } + + /** + * Set {@link #model} to model. + * + * @param model + */ + public void setModel(String model) { + this.model = model; + } + + /** + * Get {@link #model} + * + * @return model + */ + public String getModel() { + return model; + } + + /** + * Set {@link #type} to type. + * + * @param type + */ + public void setType(String type) { + this.type = type; + } + + /** + * Get {@link #type} + * + * @return type + */ + public String getType() { + return type; + } + + /** + * Set {@link #status} to status. + * + * @param status + */ + public void setStatus(String status) { + this.status = status; + } + + /** + * Get {@link #status} + * + * @return status + */ + public String getStatus() { + return status; + } + + /** + * A LayerInfo object is emtpy if name, data, type and status + * are null. + * + * @return True, if this object is empty - otherwise false. + */ + public boolean isEmpty() { + if (name == null && data == null && type == null && status == null) + return true; + + return false; + } + + /** + * A LayerInfo object is broken if name, data or type are null. + * + * @return True, if this object is broken - otherwise false. + */ + public boolean isBroken() { + if (name == null || data == null || type == null) + return true; + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/java/de/intevation/gnv/wms/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/wms/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Classes used while generating mapfiles. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/resources/lang/artifactMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/resources/lang/artifactMessages.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modeldata +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey +fis_gts = GTS +fis_bsh_ctd = CTD +fis_bsh_xbt = XBT +fis_eisklimatologie = Eisklimatologie +fis_sst = SST +fis_seastate = Sea State +fis_seacat = SeaCat +fis_currentmeter = Current Meter +fis_icestations = Ice Station Report +fis_nauthis = Nauthis +fis_contis=Contis +fis_marinefeatures = Marine Features + +meshid= Mesh +fis = Data set +product= Product +timeSeries= Timeseries +verticalProfile = Verticalprofile +horizontalProfile = Horizontalprofile +horizontalProfileCross = Horizontales Schnittprofil +horizontalCrossSection = Horizontal cross-section +verticalcrosssection = Vertical cross-section +layer = Layer +featureid = Station +mesh_coordinate = Geographic position (e.g. 56n30 6e20) +mesh_linestring = Line (WKT) +mesh_polygon = Area (WKT) +mesh_point = Mesh Point +measurementid = Measurement depth/height [m] +depthrange = Measurementarea depth/height [m] +mindepthid = Deepest Layer +maxdepthid = Highest Layer +parameterid = Parameter +yearid = Year +layerid = Layer +timeinterval = Time period +minvalue = from +maxvalue = to +dateid = Measurement date +vehicleid = Ship +cruiseid = Cruise +trackid = Track +seriesid = Series +surveyid = Survey Info +axisid = Axis +depthid = Layer and Depth range [m] +iposition = West-East-Axis +jposition = North-South-Axis +instantaneouspoint_point = Momentanmesspunkt +areaid=Area +subareaid=Subarea +depth=depth +coordinate=coordinate +coordinate.template.northeast={0}\u00b0N {1}'' {2}\u00b0E {3}'' +coordinate.template.southeast={0}\u00b0S {1}'' {2}\u00b0E {3}'' +coordinate.template.northwest={0}\u00b0N {1}'' {2}\u00b0W {3}'' +coordinate.template.southwest={0}\u00b0S {1}'' {2}\u00b0W {3}'' + +chart.timeseries.date.format=yyyy-MMM-dd +chart.timeseries.title.xaxis=Time [UTC] +chart.verticalprofile.title.xaxis=Depth [m] +chart.verticalcrosssection.title.xaxis=Distance [km] +chart.verticalcrosssection.title.yaxis=Depth [m] +chart.horizontalprofile.title.xaxis=Distance [km] +chart.horizontalcrosssection.title.xaxis=Latitude [m] + +histogram.axis.range.title=Absolute Frequency + +# error messages +no.input.data= No Entry was chosen. Please select at least one entry. +input.is.not.valid=Invalid input. Please try again. +input.is.not.valid.date.required=Invalid input. A date is required. Please try again. +start.date.after.end.date=Start date lies after end date. Please try again. +date.out.of.range=Date is out of range. +missing.data.field=Can't validate selected date. Missing date, lower or upper date bound. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/resources/lang/artifactMessages_de.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/resources/lang/artifactMessages_de.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modelldaten +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey +fis_gts = GTS +fis_bsh_ctd = CTD +fis_bsh_xbt = XBT +fis_eisklimatologie = Eisklimatologie +fis_sst = SST +fis_seastate = Seegangsarchiv +fis_seacat = SeaCat +fis_currentmeter = Strommesser +fis_icestations = Eismeldungen +fis_nauthis = Nauthis +fis_contis=Contis +fis_marinefeatures = Marine Basisdaten + +fis = Fachinformationssystem +product= Produkt +timeSeries= Zeitserie +verticalProfile = Vertikalprofil +horizontalProfile = Horizontalprofil +horizontalProfileCross = Horizontales Schnittprofil +horizontalCrossSection = Horizontalschnitt +verticalcrosssection = Profilschnitt +layer = Layer +featureid = Station +meshid= Datengitter +mesh_coordinate = Geographische Position (z.B. 56n30 6e20) +mesh_linestring = Linienzug als WKT +mesh_polygon = Fläche als WKT +mesh_point = Gitterzelle/Knotenpunkt +measurementid = Messung Tiefe/Höhe [m] +depthrange = Messbereich Tiefe/Höhe [m] +mindepthid = Untere Grenzschicht +maxdepthid = Obere Grenzschicht +parameterid = Parameter +yearid = Jahr +layerid = Layer +timeinterval = Zeitfenster +minvalue = von +maxvalue = bis +dateid = Zeitpunkt +vehicleid = Schiff +cruiseid = Reise +trackid = Track +seriesid = Mess-Serie +surveyid = Messabschnitt +axisid = Achse +depthid = Ebene und Tiefenbereich [m] +iposition = West-Ost-Achse +jposition = Nord-S\u00fcd-Achse +instantaneouspoint_point = Messpunkt +areaid=Gebiet +subareaid=Teilgebiet +depth=Tiefe +coordinate=Koordinate +coordinate.template.northeast={0}\u00b0N {1}'' {2}\u00b0O {3}'' +coordinate.template.southeast={0}\u00b0S {1}'' {2}\u00b0O {3}'' +coordinate.template.northwest={0}\u00b0N {1}'' {2}\u00b0W {3}'' +coordinate.template.southwest={0}\u00b0S {1}'' {2}\u00b0W {3}'' + +chart.timeseries.date.format=dd-MMM-yyyy +chart.timeseries.title.xaxis=Zeit [UTC] +chart.verticalprofile.title.xaxis=Tiefe [m] +chart.verticalcrosssection.title.xaxis=Distanz [km] +chart.verticalcrosssection.title.yaxis=Tiefe [m] +chart.horizontalprofile.title.xaxis=Distanz [km] +chart.horizontalcrosssection.title.xaxis=Ausdehnung [m] + +histogram.axis.range.title=Absolute H\u00e4ufigkeit + +# error messages +no.input.data=Es wurde kein Eintrag ausgew\u00e4hlt. Bitte w\u00e4hlen sie mindestens einen Eintrag aus. +input.is.not.valid=Ung\u00fcltige Eingabe. Bitte versuchen Sie es erneut. +input.is.not.valid.date.required=Ung\u00fcltige Eingabe. Ein Datum wird ben\u00f6tigt. Bitte versuchen Sie es erneut. +start.date.after.end.date=Anfangsdatum liegt hinter dem Enddatum. Bitte versuchen Sie es erneut. +date.out.of.range=Das gew\u00e4hlte Datum liegt au\u00dferhalb des gültigen Wertebereiches. +missing.data.field=Validierung der Datumseingabe nicht m\u00f6glich. Datum, obere oder untere Grenze fehlt. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/resources/lang/artifactMessages_de_DE.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/resources/lang/artifactMessages_de_DE.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modelldaten +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey +fis_gts = GTS +fis_bsh_ctd = CTD +fis_bsh_xbt = XBT +fis_eisklimatologie = Eisklimatologie +fis_sst = SST +fis_seastate = Seegangsarchiv +fis_seacat = SeaCat +fis_currentmeter = Strommesser +fis_icestations = Eismeldungen +fis_nauthis = Nauthis +fis_contis=Contis +fis_marinefeatures = Marine Basisdaten + +fis= Fachinformationssystem +product= Produkt +timeSeries= Zeitserie +verticalProfile = Vertikalprofil +horizontalProfile = Horizontalprofil +horizontalProfileCross = Horizontales Schnittprofil +horizontalCrossSection = Horizontalschnitt +verticalcrosssection = Profilschnitt +layer = Layer +featureid = Station +meshid= Datengitter +mesh_coordinate = Geographische Position (z.B. 56n30 6e20) +mesh_linestring = Linienzug als WKT +mesh_polygon = Fläche als WKT +mesh_point = Gitterzelle/Knotenpunkt +measurementid = Messung Tiefe/Höhe [m] +depthrange = Messbereich Tiefe/Höhe [m] +mindepthid = Untere Grenzschicht +maxdepthid = Obere Grenzschicht +parameterid = Parameter +yearid = Jahr +layerid = Layer +timeinterval = Zeitfenster +minvalue = von +maxvalue = bis +dateid = Zeitpunkt +vehicleid = Schiff +cruiseid = Reise +trackid = Track +seriesid = Mess-Serie +surveyid = Messabschnitt +axisid = Achse +depthid = Ebene und Tiefenbereich [m] +iposition = West-Ost-Achse +jposition = Nord-S\u00fcd-Achse +instantaneouspoint_point = Messpunkt +areaid=Gebiet +subareaid=Teilgebiet +depth=Tiefe +coordinate=Koordinate +coordinate.template.northeast={0}\u00b0N {1}'' {2}\u00b0O {3}'' +coordinate.template.southeast={0}\u00b0S {1}'' {2}\u00b0O {3}'' +coordinate.template.northwest={0}\u00b0N {1}'' {2}\u00b0W {3}'' +coordinate.template.southwest={0}\u00b0S {1}'' {2}\u00b0W {3}'' + +chart.timeseries.date.format=dd-MMM-yyyy +chart.timeseries.title.xaxis=Zeit [UTC] +chart.verticalprofile.title.xaxis=Tiefe [m] +chart.verticalcrosssection.title.xaxis=Distanz [km] +chart.verticalcrosssection.title.yaxis=Tiefe [m] +chart.horizontalprofile.title.xaxis=Distanz [km] +chart.horizontalcrosssection.title.xaxis=Ausdehnung [m] + +histogram.axis.range.title=Absolute H\u00e4ufigkeit + +# error messages +no.input.data=Es wurde kein Eintrag ausgew\u00e4hlt. Bitte w\u00e4hlen sie mindestens einen Eintrag aus. +input.is.not.valid=Ung\u00fcltige Eingabe. Bitte versuchen Sie es erneut. +input.is.not.valid.date.required=Ung\u00fcltige Eingabe. Ein Datum wird ben\u00f6tigt. Bitte versuchen Sie es erneut. +start.date.after.end.date=Anfangsdatum liegt nach dem Enddatum. Bitte versuchen Sie es erneut. +date.out.of.range=Das gew\u00e4hlte Datum liegt au\u00dferhalb des gültigen Wertebereiches. +missing.data.field=Validierung der Datumseingabe nicht m\u00f6glich. Datum, obere oder untere Grenze fehlt. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/resources/lang/artifactMessages_en.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/resources/lang/artifactMessages_en.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,83 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modeldata +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey +fis_gts = GTS +fis_bsh_ctd = CTD +fis_bsh_xbt = XBT +fis_eisklimatologie = Iceclimatology +fis_sst = SST +fis_seastate = Sea State +fis_seacat = SeaCat +fis_currentmeter = Current Meter +fis_icestations = Ice Station Report +fis_nauthis = Nauthis +fis_contis=Contis +fis_marinefeatures = Marine Features + +meshid= Mesh +fis = Data set +product= Product +timeSeries= Timeseries +verticalProfile = Verticalprofile +horizontalProfile = Horizontalprofile +horizontalProfileCross = Horizontales Schnittprofil +horizontalCrossSection = Horizontal cross-section +verticalcrosssection = Vertical cross-section +layer = Layer +featureid = Station +mesh_coordinate = Geographic position (e.g. 56n30 6e20) +mesh_linestring = Line (WKT) +mesh_polygon = Area (WKT) +mesh_point = Mesh Point +measurementid = Measurement depth/height [m] +depthrange = Measurementarea depth/height [m] +mindepthid = Deepest Layer +maxdepthid = Highest Layer +parameterid = Parameter +yearid = Year +layerid = Layer +timeinterval = Time period +minvalue = from +maxvalue = to +dateid = Measurement date +vehicleid = Ship +cruiseid = Cruise +trackid = Track +seriesid = Series +surveyid = Survey Info +axisid = Axis +depthid = Layer and Depth range [m] +iposition = West-East-Axis +jposition = North-South-Axis +instantaneouspoint_point = Instantaneouspoint +areaid=Area +subareaid=Subarea +depth=depth +coordinate=coordinate +coordinate.template.northeast={0}\u00b0N {1}'' {2}\u00b0E {3}'' +coordinate.template.southeast={0}\u00b0S {1}'' {2}\u00b0E {3}'' +coordinate.template.northwest={0}\u00b0N {1}'' {2}\u00b0W {3}'' +coordinate.template.southwest={0}\u00b0S {1}'' {2}\u00b0W {3}'' + + +chart.timeseries.date.format=yyyy-MMM-dd +chart.timeseries.title.xaxis=Time [UTC] +chart.verticalprofile.title.xaxis=Depth [m] +chart.verticalcrosssection.title.xaxis=Distance [km] +chart.verticalcrosssection.title.yaxis=Depth [m] +chart.horizontalprofile.title.xaxis=Distance [km] +chart.horizontalcrosssection.title.xaxis=Latitude [m] + +histogram.axis.range.title=Absolute Frequency + +# error messages +no.input.data= No Entry was chosen. Please select at least one entry. +input.is.not.valid=Invalid input. Please try again. +input.is.not.valid.date.required=Invalid input. A date is required. Please try again. +start.date.after.end.date=Start date lies after end date. Please try again. +date.out.of.range=Date is out of range. +missing.data.field=Can't validate selected date. Missing date, lower or upper date bound. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/main/resources/lang/lang.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/resources/lang/lang.conf Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,3 @@ +de_DE +de +en diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestCaseBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,192 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.DefaultCallMeta; +import de.intevation.artifactdatabase.DefaultPreferredLocale; +import de.intevation.artifactdatabase.FactoryBootstrap; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.artifacts.PreferredLocale; + +import de.intevation.gnv.utils.ArtifactXMLUtilities; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +import org.xml.sax.SAXException; + +/** + * @author Tim Englich + * + */ +public abstract class GNVArtifactsTestCaseBase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(GNVArtifactsTestCaseBase.class); + } + + private String configurationDir = "doc/conf"; + + protected FactoryBootstrap bootstrap = null; + + /** + * Constructor + */ + public GNVArtifactsTestCaseBase() { + } + + /** + * Constructor + * @param name + */ + public GNVArtifactsTestCaseBase(String name) { + super(name); + } + + public abstract void testArtifact(); + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + log.debug("GNVArtifactsTestCase.setUp"); + super.setUp(); + log.info(Config.CONFIG_DIR + " ==> " + configurationDir); + System.setProperty(Config.CONFIG_DIR, configurationDir); + log.info("Bootstrap wird initialisiert."); + bootstrap = new FactoryBootstrap(); + bootstrap.boot(); + } + + protected void writeDocument2Log(Document document) { + log.debug(new ArtifactXMLUtilities().writeDocument2String(document)); + } + + protected Document readDocument(String fileName) { + Document returnValue = null; + try { + DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory + .newInstance(); + docBuilderFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); + returnValue = docBuilder.parse(new File(fileName)); + } catch (ParserConfigurationException e) { + log.error(e, e); + } catch (SAXException e) { + log.error(e, e); + } catch (IOException e) { + log.error(e, e); + } + return returnValue; + } + + protected void check4ExceptionReport(Document document) throws Exception { + document = new ArtifactXMLUtilities().reInitDocument(document); + String message = Config.getStringXPath(document, + "/exceptionreport/exception"); + if (message != null) { + throw new Exception(message); + } + } + + /** + * @return + */ + protected CallContext createCallContext(ArtifactFactory artifactFactory) { + CallMeta callMeta = new DefaultCallMeta( + new PreferredLocale[] { new DefaultPreferredLocale("de_DE", + 1.0f) }); + CallContext cc = new TestCallContext(bootstrap.getContext(), callMeta,artifactFactory); + return cc; + } + + /** + * @param artifact + * @param cc + * @param describeDocument TODO + * @throws Exception + */ + protected void doNextStep(Artifact artifact, CallContext cc, + String feedDocument, String advanceDocument, Document describeDocument) + throws Exception { + Document outputData = artifact.describe(describeDocument,cc); +// this.writeDocument2Log(outputData); + outputData = artifact.feed(this.readDocument(feedDocument), cc); + this.check4ExceptionReport(outputData); + outputData = artifact.advance(this.readDocument(advanceDocument), cc); +// this.writeDocument2Log(outputData); + this.check4ExceptionReport(outputData); + + } + + protected void createFile(byte[] content, String fileName) { + try { + FileOutputStream fos = new FileOutputStream(new File(fileName)); + ByteArrayInputStream bis = new ByteArrayInputStream(content); + byte[] buf = new byte[4096]; + while (bis.read(buf) > 0) { + fos.write(buf); + } + fos.flush(); + fos.close(); + } catch (FileNotFoundException e) { + log.error(e, e); + } catch (IOException e) { + log.error(e, e); + } + } + + /** + * @param artefactName + */ + protected ArtifactFactory getArtifactFactory(String artefactName) { + log.debug("GNVArtifactsTestCase.getArtifactFactory"); + ArtifactFactory[] artifactFactories = bootstrap.getArtifactFactories(); + for (int i = 0; i < artifactFactories.length; i++) { + if (artifactFactories[i].getName().equals(artefactName)) { + log.debug("ArtifactFactory wurde gefunden."); + return artifactFactories[i]; + } + } + return null; + } + + /** + * @param artifactFactory + * @return + */ + protected Artifact createArtifact(ArtifactFactory artifactFactory) { + Document setupData = null; + Artifact artifact = artifactFactory.createArtifact( + "" + System.currentTimeMillis(), + bootstrap.getContext(), + setupData); + assertNotNull(artifact); + log.debug("Artifact is available"); + return artifact; + } + + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestSuite.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/GNVArtifactsTestSuite.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,22 @@ +package de.intevation.gnv.artifacts; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class GNVArtifactsTestSuite { + + public static Test suite() { + TestSuite suite = new TestSuite("Test for de.intevation.gnv.artifacts"); + suite.addTestSuite(TimeSeriesPointTimeSeriesTestCase.class); + suite.addTestSuite(MeshVerticalProfileTestCase.class); + suite.addTestSuite(MeshHorizontalProfileTestCase.class); + suite.addTestSuite(MeshHorizontalCrossSectionTestCase.class); + suite.addTestSuite(MeshTimeSeriesTestCase.class); + suite.addTestSuite(TimeSeriesPointVerticalProfileTestCase.class); + suite.addTestSuite(MeshVerticalCrossSectionTestCase.class); + suite.addTestSuite(InstantaneousPointHorizontalProfileTestCase.class); + suite.addTestSuite(InstantaneousPointVerticalProfileTestCase.class); + return suite; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/InstantaneousPointHorizontalProfileTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/InstantaneousPointHorizontalProfileTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,124 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class InstantaneousPointHorizontalProfileTestCase extends + GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(InstantaneousPointHorizontalProfileTestCase.class); + + /** + * Constructor + */ + public InstantaneousPointHorizontalProfileTestCase() { + } + + /** + * Constructor + * @param name + */ + public InstantaneousPointHorizontalProfileTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase." + + "testHorizontalProfileInstantaneousPointArtifact"); + String artefactName = "fis_delphin"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_describe.xml"); + + int steps = 9; + + for (int i = 0; i < steps; i++){ + + this.doNextStep( + artifact, + cc, + "src/test/ressources/horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_0"+i+"_feed.xml", + "src/test/ressources/horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_0"+i+"_advance.xml", + describeDocument); + } + + Document outputData = artifact.describe(describeDocument, cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream( + "src/test/results/horizontalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".png"); + fos2 = new FileOutputStream( + "src/test/results/horizontalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".xml"); + fos3 = new FileOutputStream( + "src/test/results/horizontalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".csv"); + fos4 = new FileOutputStream( + "src/test/results/horizontalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_08_out_statistics.xml"), + fos2,cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_08_out_chart.xml"), + fos,cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_08_out_csv.xml"), + fos3,cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_instantaneouspoint/" + + "horizontalprofile_step_08_out_odv.xml"), + fos4,cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/InstantaneousPointVerticalProfileTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/InstantaneousPointVerticalProfileTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,123 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class InstantaneousPointVerticalProfileTestCase extends + GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(InstantaneousPointVerticalProfileTestCase.class); + + /** + * Constructor + */ + public InstantaneousPointVerticalProfileTestCase() { + } + + /** + * Constructor + * @param name + */ + public InstantaneousPointVerticalProfileTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase.testVerticalProfileArtifact"); + String artefactName = "fis_bsh_ctd"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_describe.xml"); + + int steps = 5; + + for (int i = 1; i <= steps; i++){ + this.doNextStep( + artifact, + cc, + "src/test/ressources/verticalprofile_instantaneouspoint/" + + "verticalprofile_step_0"+i+"_feed.xml", + "src/test/ressources/verticalprofile_instantaneouspoint/" + + "verticalprofile_step_0"+i+"_advance.xml", + describeDocument); + } + + // Vierter Schritt + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream( + "src/test/results/verticalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".png"); + fos2 = new FileOutputStream( + "src/test/results/verticalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".xml"); + fos3 = new FileOutputStream( + "src/test/results/verticalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".csv"); + fos4 = new FileOutputStream( + "src/test/results/verticalprofile_instantaneouspoint" + + System.currentTimeMillis() + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_instantaneouspoint/" + + "verticalprofile_step_05_out_statistics.xml"), + fos2, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_instantaneouspoint/" + + "verticalprofile_step_05_out_chart.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_instantaneouspoint/" + + "verticalprofile_step_05_out_csv.xml"), + fos3, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_instantaneouspoint/" + + "verticalprofile_step_05_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshHorizontalCrossSectionTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class MeshHorizontalCrossSectionTestCase extends + GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(MeshHorizontalCrossSectionTestCase.class); + + /** + * Constructor + */ + public MeshHorizontalCrossSectionTestCase() { + } + + /** + * Constructor + * @param name + */ + public MeshHorizontalCrossSectionTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase.testHorizontalCrossSectionMeshArtifact"); + String artefactName = "fis_modeldata"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("HorizontalCrossSectionMesh-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_describe.xml"); + int steps = 8; + + for (int i = 1; i <= steps; i++){ + this.doNextStep( + artifact, + cc, + "src/test/ressources/horizontalcrosssection_mesh/" + + "horizontalcrosssection_step_0"+i+"_feed.xml", + "src/test/ressources/horizontalcrosssection_mesh/" + + "horizontalcrosssection_step_0"+i+"_advance.xml", + describeDocument); + } + + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + try { + fos = new FileOutputStream( + "src/test/results/horizontalcrosssection_mesh" + + System.currentTimeMillis() + ".zip"); + fos2 = new FileOutputStream( + "src/test/results/horizontalcrosssection_mesh" + + System.currentTimeMillis() + ".txt"); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalcrosssection_mesh/" + + "horizontalcrosssection_step_0"+steps+"_out_zip.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalcrosssection_mesh/" + + "horizontalcrosssection_step_0"+steps+"_out_wms.xml"), + fos2,cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshHorizontalProfileTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,128 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class MeshHorizontalProfileTestCase extends GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(MeshHorizontalProfileTestCase.class); + + /** + * Constructor + */ + public MeshHorizontalProfileTestCase() { + } + + /** + * Constructor + * @param name + */ + public MeshHorizontalProfileTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase." + + "testHorizontalProfileInstantaneousPointArtifact"); + String artefactName = "fis_modeldata"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/horizontalProfile_mesh/horizontalprofile_describe.xml"); + + int steps = 11; + + for (int i = 1; i <= steps; i++){ + String number = ""+i; + if (i < 10){ + number = "0"+number; + } + this.doNextStep( + artifact, + cc, + "src/test/ressources/horizontalProfile_mesh/" + + "horizontalprofile_step_"+number+"_feed.xml", + "src/test/ressources/horizontalProfile_mesh/" + + "horizontalprofile_step_"+number+"_advance.xml", + describeDocument); + } + + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream( + "src/test/results/horizontalProfile_mesh" + + System.currentTimeMillis() + ".png"); + fos2 = new FileOutputStream( + "src/test/results/horizontalProfile_mesh" + + System.currentTimeMillis() + ".xml"); + fos3 = new FileOutputStream( + "src/test/results/horizontalProfile_mesh" + + System.currentTimeMillis() + ".csv"); + fos4 = new FileOutputStream( + "src/test/results/horizontalProfile_mesh" + + System.currentTimeMillis() + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_mesh/" + + "horizontalprofile_step_"+steps+"_out_statistics.xml"), + fos2, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_mesh/" + + "horizontalprofile_step_"+steps+"_out_chart.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_mesh/" + + "horizontalprofile_step_"+steps+"_out_csv.xml"), + fos3, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "horizontalProfile_mesh/" + + "horizontalprofile_step_"+steps+"_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + fos4.flush(); + fos4.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshTimeSeriesTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshTimeSeriesTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,126 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class MeshTimeSeriesTestCase extends GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(MeshTimeSeriesTestCase.class); + + /** + * Constructor + */ + public MeshTimeSeriesTestCase() { + } + + /** + * Constructor + * @param name + */ + public MeshTimeSeriesTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase.testTimeSeriesMeshArtifact"); + String artefactName = "fis_modeldata"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("TimeSeriesMesh-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + + Document describeDocument = this.readDocument("src/test/ressources/timeseries_mesh/timeseries_describe.xml"); + + int steps = 8; + + for (int i = 1; i <= steps; i++){ + this.doNextStep( + artifact, + cc, + "src/test/ressources/timeseries_mesh/" + + "timeseries_step_0"+i+"_feed.xml", + "src/test/ressources/timeseries_mesh/" + + "timeseries_step_0"+i+"_advance.xml", + describeDocument); + } + // Achter Schritt + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream("src/test/results/timeseries_mesh" + + System.currentTimeMillis() + + ".png"); + fos2 = new FileOutputStream("src/test/results/timeseries_mesh" + + System.currentTimeMillis() + + ".xml"); + fos3 = new FileOutputStream("src/test/results/timeseries_mesh" + + System.currentTimeMillis() + + ".csv"); + fos4 = new FileOutputStream("src/test/results/timeseries_mesh" + + System.currentTimeMillis() + + ".odv"); + artifact + .out( + this + .readDocument("src/test/ressources/timeseries_mesh/timeseries_step_08_out_statistics.xml"), + fos2, cc); + artifact + .out( + this + .readDocument("src/test/ressources/timeseries_mesh/timeseries_step_08_out_chart.xml"), + fos, cc); + artifact + .out( + this + .readDocument("src/test/ressources/timeseries_mesh/timeseries_step_08_out_csv.xml"), + fos3, cc); + artifact + .out( + this + .readDocument("src/test/ressources/timeseries_mesh/timeseries_step_08_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshVerticalCrossSectionTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,118 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class MeshVerticalCrossSectionTestCase extends GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(MeshVerticalCrossSectionTestCase.class); + + /** + * Constructor + */ + public MeshVerticalCrossSectionTestCase() { + } + + /** + * Constructor + * @param name + */ + public MeshVerticalCrossSectionTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase." + + "testHVerticalCrossSectionMeshArtifact"); + String artefactName = "fis_modeldata"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_describe.xml"); + + int steps = 7; + + for (int i = 1; i <= steps; i++){ + + this.doNextStep( + artifact, + cc, + "src/test/ressources/verticalcrosssection_mesh/" + + "verticalcrosssection_step_0"+i+"_feed.xml", + "src/test/ressources/verticalcrosssection_mesh/" + + "verticalcrosssection_step_0"+i+"_advance.xml", + describeDocument); + } + + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + try { + fos = new FileOutputStream( + "src/test/results/verticalcrosssection_mesh" + + System.currentTimeMillis() + ".png"); + + fos2 = new FileOutputStream( + "src/test/results/verticalcrosssection_mesh" + + System.currentTimeMillis() + ".csv"); + fos3 = new FileOutputStream( + "src/test/results/verticalcrosssection_mesh" + + System.currentTimeMillis() + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalcrosssection_mesh/" + + "verticalcrosssection_step_0"+steps+"_out_chart.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalcrosssection_mesh/" + + "verticalcrosssection_step_0"+steps+"_out_csv.xml"), + fos2,cc); + // TODO: FIXME: ODV-Export nach Reparatur wieder Testbar machen. +// artifact.out(this.readDocument("src/test/ressources/" + +// "verticalcrosssection_mesh/" + +// "verticalcrosssection_step_0"+steps+"_out_odv.xml"), +// fos3,cc); + + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/MeshVerticalProfileTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,129 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class MeshVerticalProfileTestCase extends GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(MeshVerticalProfileTestCase.class); + + /** + * Constructor + */ + public MeshVerticalProfileTestCase() { + } + + /** + * Constructor + * @param name + */ + public MeshVerticalProfileTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase.testVerticalProfileArtifact"); + String artefactName = "fis_modeldata"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + Document describeDocument = this.readDocument("src/test/ressources/" + + "verticalprofile_mesh/" + + "verticalprofile_describe.xml"); + + int steps = 11; + + for (int i = 1; i <= steps; i++){ + String number = ""+i; + if (i < 10){ + number = "0"+number; + } + this.doNextStep( + artifact, + cc, + "src/test/ressources/verticalprofile_mesh/" + + "verticalprofile_step_"+number+"_feed.xml", + "src/test/ressources/verticalprofile_mesh/" + + "verticalprofile_step_"+number+"_advance.xml", + describeDocument); + } + // 10. Schritt + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream( + "src/test/results/verticalprofile_mesh" + + System.currentTimeMillis() + ".png"); + fos2 = new FileOutputStream( + "src/test/results/verticalprofile_mesh" + + System.currentTimeMillis() + ".xml"); + fos3 = new FileOutputStream( + "src/test/results/verticalprofile_mesh" + + System.currentTimeMillis() + ".csv"); + fos4 = new FileOutputStream( + "src/test/results/verticalprofile_mesh" + + System.currentTimeMillis() + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_mesh/" + + "verticalprofile_step_"+steps+"_out_statistics.xml"), + fos2, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_mesh/" + + "verticalprofile_step_"+steps+"_out_chart.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_mesh/" + + "verticalprofile_step_"+steps+"_out_csv.xml"), + fos3, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile_mesh/" + + "verticalprofile_step_"+steps+"_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + fos4.flush(); + fos4.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TestArtifactDatabase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.ArtifactDatabase; +import de.intevation.artifacts.ArtifactDatabaseException; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallMeta; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class TestArtifactDatabase implements ArtifactDatabase { + + private ArtifactFactory artifactFactory = null; + /** + * Constructor + */ + public TestArtifactDatabase(ArtifactFactory artifactFactory) { + this.artifactFactory = artifactFactory; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#advance(java.lang.String, org.w3c.dom.Document, de.intevation.artifacts.CallMeta) + */ + public Document advance(String artifact, Document target, CallMeta callMeta) + throws ArtifactDatabaseException { + + return null; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#artifactFactoryNamesAndDescriptions() + */ + public String[][] artifactFactoryNamesAndDescriptions() { + + return null; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#createArtifactWithFactory(java.lang.String, de.intevation.artifacts.CallMeta, org.w3c.dom.Document) + */ + public Document createArtifactWithFactory(String factory, + CallMeta callMeta, + Document data) + throws ArtifactDatabaseException { + + return null; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#describe(java.lang.String, org.w3c.dom.Document, de.intevation.artifacts.CallMeta) + */ + public Document describe(String artifact, Document data, CallMeta callMeta) + throws ArtifactDatabaseException { + + return null; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#feed(java.lang.String, org.w3c.dom.Document, de.intevation.artifacts.CallMeta) + */ + public Document feed(String artifact, Document data, CallMeta callMeta) + throws ArtifactDatabaseException { + + return null; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#getInternalArtifactFactory(java.lang.String) + */ + public ArtifactFactory getInternalArtifactFactory(String factoryName) { + return this.artifactFactory; + } + + /** + * @see de.intevation.artifacts.ArtifactDatabase#out(java.lang.String, org.w3c.dom.Document, de.intevation.artifacts.CallMeta) + */ + public DeferredOutput out(String artifact, Document format, + CallMeta callMeta) + throws ArtifactDatabaseException { + + return null; + } + + public Document process(String service, Document input, CallMeta callMeta) { + return null; + } + + public String[][] serviceNamesAndDescriptions() { + return null; + } + + public Document exportArtifact(String artifact, CallMeta callMeta) throws ArtifactDatabaseException { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Document importArtifact(Document data, CallMeta callMeta) throws ArtifactDatabaseException { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TestCallContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TestCallContext.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,69 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.ArtifactDatabase; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; + +/** + * @author Tim Englich + * + */ +public class TestCallContext implements CallContext { + + + + private Object globalContext = null; + private CallMeta callMeta = null; + private ArtifactFactory artifactFactory = null; + private ArtifactDatabase artifactDatabase = null; + /** + * Constructor + */ + public TestCallContext(Object globalContext, + CallMeta callMeta, + ArtifactFactory artifactFactory) { + this.globalContext = globalContext; + this.callMeta = callMeta; + this.artifactDatabase = new TestArtifactDatabase(artifactFactory); + } + + /** + * @see de.intevation.artifacts.CallContext#afterBackground(int) + */ + public void afterBackground(int action) { + } + + /** + * @see de.intevation.artifacts.CallContext#afterCall(int) + */ + public void afterCall(int action) { + } + + /** + * @see de.intevation.artifacts.CallContext#globalContext() + */ + public Object globalContext() { + return this.globalContext; + } + + public CallMeta getMeta() { + return this.callMeta; + } + + public Object getContextValue(Object key) { + return null; + } + + public Object putContextValue(Object key, Object value) { + return null; + } + + public ArtifactDatabase getDatabase() { + return this.artifactDatabase; + } + + public Long getTimeToLive() { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointTimeSeriesTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,122 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class TimeSeriesPointTimeSeriesTestCase extends GNVArtifactsTestCaseBase { + + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(TimeSeriesPointTimeSeriesTestCase.class); + + /** + * Constructor + */ + public TimeSeriesPointTimeSeriesTestCase() { + } + + /** + * Constructor + * @param name + */ + public TimeSeriesPointTimeSeriesTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + log.debug("GNVArtifactsTestCase.testTimeSeriesArtifact"); + try { + String artefactName = "fis_marnet"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("TimeSeries-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + + // Erster Schritt + + Document describeDocument = this.readDocument("src/test/ressources/timeseries/timeseries_describe.xml"); + + int steps = 6; + + for (int i = 1; i <= steps; i++){ + + this.doNextStep( + artifact, + cc, + "src/test/ressources/timeseries/" + + "timeseries_step_0"+i+"_feed.xml", + "src/test/ressources/timeseries/" + + "timeseries_step_0"+i+"_advance.xml", + describeDocument); + } + + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream("src/test/results/timeseries" + + System.currentTimeMillis() + + ".png"); + fos2 = new FileOutputStream("src/test/results/timeseries" + + System.currentTimeMillis() + + ".xml"); + fos3 = new FileOutputStream("src/test/results/timeseries" + + System.currentTimeMillis() + + ".csv"); + fos4 = new FileOutputStream("src/test/results/timeseries" + + System.currentTimeMillis() + + ".odv"); + + artifact.out(this + .readDocument("src/test/ressources/timeseries/timeseries_step_06_out_chart.xml"), + fos, cc); + artifact.out(this + .readDocument("src/test/ressources/timeseries/timeseries_step_06_out_statistics.xml"), + fos2, cc); + artifact.out(this + .readDocument("src/test/ressources/timeseries/timeseries_step_06_out_csv.xml"), + fos3, cc); + artifact.out(this + .readDocument("src/test/ressources/timeseries/timeseries_step_06_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/TimeSeriesPointVerticalProfileTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,125 @@ +package de.intevation.gnv.artifacts; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.CallContext; + +import java.io.FileOutputStream; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class TimeSeriesPointVerticalProfileTestCase extends + GNVArtifactsTestCaseBase { + + private static Logger log = Logger.getLogger(TimeSeriesPointVerticalProfileTestCase.class); + + /** + * Constructor + */ + public TimeSeriesPointVerticalProfileTestCase() { + } + + /** + * Constructor + * @param name + */ + public TimeSeriesPointVerticalProfileTestCase(String name) { + super(name); + } + + /** + * @see de.intevation.gnv.artifacts.GNVArtifactsTestCaseBase#testArtifact() + */ + @Override + public void testArtifact() { + try { + log.debug("GNVArtifactsTestCase.testVerticalProfileArtifact"); + String artefactName = "fis_marnet"; + ArtifactFactory artifactFactory = this + .getArtifactFactory(artefactName); + assertNotNull(artifactFactory); + log.debug("VerticalProfile-ArtifactFactory is available"); + + Artifact artifact = createArtifact(artifactFactory); + + CallContext cc = createCallContext(artifactFactory); + + Document describeDocument = this.readDocument("src/test/ressources/verticalprofile/verticalprofile_describe.xml"); + int steps = 7; + + for (int i = 1; i <= steps; i++){ + this.doNextStep( + artifact, + cc, + "src/test/ressources/verticalprofile/" + + "verticalprofile_step_0"+i+"_feed.xml", + "src/test/ressources/verticalprofile/" + + "verticalprofile_step_0"+i+"_advance.xml", + describeDocument); + } + + // Vierter Schritt + Document outputData = artifact.describe(describeDocument,cc); + FileOutputStream fos = null; + FileOutputStream fos2 = null; + FileOutputStream fos3 = null; + FileOutputStream fos4 = null; + try { + fos = new FileOutputStream("src/test/results/verticalprofile" + + System.currentTimeMillis() + + ".png"); + fos2 = new FileOutputStream("src/test/results/verticalprofile" + + System.currentTimeMillis() + + ".xml"); + fos3 = new FileOutputStream("src/test/results/verticalprofile" + + System.currentTimeMillis() + + ".csv"); + fos4 = new FileOutputStream("src/test/results/verticalprofile" + + System.currentTimeMillis() + + ".odv"); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile/" + + "verticalprofile_step_07_out_statistics.xml"), + fos2, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile/" + + "verticalprofile_step_07_out_chart.xml"), + fos, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile/" + + "verticalprofile_step_07_out_csv.xml"), + fos3, cc); + artifact.out(this.readDocument("src/test/ressources/" + + "verticalprofile/" + + "verticalprofile_step_07_out_odv.xml"), + fos4, cc); + } catch (Exception e) { + log.error(e, e); + fail(); + } finally { + try { + fos.flush(); + fos.close(); + fos2.flush(); + fos2.close(); + fos3.flush(); + fos3.close(); + fos4.flush(); + fos4.close(); + } catch (Exception e) { + log.error(e, e); + } + } + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/ressource/RessourceFactoryTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/ressource/RessourceFactoryTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,60 @@ +package de.intevation.gnv.artifacts.ressource; + +import de.intevation.artifactdatabase.DefaultPreferredLocale; + +import de.intevation.artifacts.PreferredLocale; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class RessourceFactoryTestCase extends TestCase { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(RessourceFactoryTestCase.class); + } + + /** + * Constructor + * + * @param name + */ + public RessourceFactoryTestCase(String name) { + super(name); + } + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + // System.setProperty("artifact.ressource.dir", + // "src/test/ressources/lang"); + } + + public void testRessurceFactoryTestCase() { + ; + String value = RessourceFactory.getInstance() + .getRessource( + new PreferredLocale[] { new DefaultPreferredLocale( + "de", 1.0f) }, "fis_modeldata", "N/N"); + log.debug(value); + value = RessourceFactory.getInstance() + .getRessource( + new PreferredLocale[] { new DefaultPreferredLocale( + "en", 1.0f) }, "fis_modeldata", "N/N"); + log.debug(value); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/util/DistanceCalculatorTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/util/DistanceCalculatorTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,30 @@ +package de.intevation.gnv.artifacts.util; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; + +import de.intevation.gnv.utils.DistanceCalculator; + +import junit.framework.TestCase; + +public class DistanceCalculatorTestCase extends TestCase { + + public DistanceCalculatorTestCase(String name) { + super(name); + } + + public void testDistanceCalculator(){ + + GeometryFactory gf = new GeometryFactory(); + + // Distance between Berlin and Tokio + Point p1 = gf.createPoint(new Coordinate(13.4000, 52.5167)); + Point p2 = gf.createPoint(new Coordinate(139.7667, 35.7000)); + + double s = new DistanceCalculator().calculateDistance(p1, p2); + + assertEquals(8941.201227763724, s); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/util/ShapeFileWriterTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/java/de/intevation/gnv/artifacts/util/ShapeFileWriterTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,87 @@ +package de.intevation.gnv.artifacts.util; + +import com.vividsolutions.jts.geom.MultiLineString; + +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.utils.Pair; +import de.intevation.gnv.utils.ShapeFileWriter; + +import java.io.File; +import java.io.FileReader; + +import java.util.ArrayList; +import java.util.Date; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class ShapeFileWriterTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(ShapeFileWriterTestCase.class); + } + + /** + * Constructor + * @param name + */ + public ShapeFileWriterTestCase(String name) { + super(name); + } + + + public void testMultiLineStringWriter(){ + + try { + String wkt = "MULTILINESTRING ((10 10, 20 20),(15 15, 30 15))"; + String wkt1 = "MULTILINESTRING ((10 5, 20 20),(15 15, 30 15))"; + String wkt2 = "MULTILINESTRING ((10 10, 8 20),(15 15, 30 15))"; + String wkt3 = "MULTILINESTRING ((8 10, 20 20),(15 15, 30 15))"; + File isolineFile = new File("src/test/ressources/isolines.wkt"); + MultiLineString multiLineString = (MultiLineString)new WKTReader().read(new FileReader(isolineFile)); + MultiLineString multiLineString1 = (MultiLineString)new WKTReader().read(wkt1); + MultiLineString multiLineString2 = (MultiLineString)new WKTReader().read(wkt2); + MultiLineString multiLineString3 = (MultiLineString)new WKTReader().read(wkt3); + ArrayList> multiLineStrings = + new ArrayList>(); + multiLineStrings.add( + new Pair( + 1.2, + multiLineString)); + multiLineStrings.add( + new Pair( + 1.3, + multiLineString1)); + multiLineStrings.add( + new Pair( + 1.4, + multiLineString2)); + multiLineStrings.add( + new Pair( + 1.5, + multiLineString3)); + + java.io.File shapeFile = new java.io.File("/tmp/test"+System.currentTimeMillis()+".shp"); + + ShapeFileWriter.writeMultiLineStringsToFile(shapeFile, 1, 1, new Date(), multiLineStrings); + + } catch (Exception e) { + log.error(e,e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_00_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_00_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_00_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_00_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_instantaneouspoint/horizontalprofile_step_08_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_08_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_08_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_08_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_08_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_09_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_09_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_09_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_09_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_10_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalProfile_mesh/horizontalprofile_step_11_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_wms.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_wms.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_zip.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/horizontalcrosssection_mesh/horizontalcrosssection_step_08_out_zip.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,11 @@ + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/isolines.wkt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/isolines.wkt Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +MULTILINESTRING ((4.355421574235005 -7.503513066218794, 3.1939758211056706 -7.503513066218794, 3.1939758211056706 -7.81615944397791, 0.5807228765646674 -7.81615944397791, 0.5807228765646674 -8.128805821737027, 0 -8.128805821737027), + (297.3301128011097 -67.21897121821003, 296.4590284862627 -67.21897121821003, 296.4590284862627 -67.53161759596915, 295.29758273313337 -67.53161759596915, 295.29758273313337 -67.84426397372826, 294.42649841828637 -67.84426397372826, 294.42649841828637 -68.15691035148738, 293.5554141034394 -68.15691035148738, 293.5554141034394 -68.46955672924649, 292.39396835031005 -68.46955672924649, 292.39396835031005 -68.78220310700561, 291.522884035463 -68.78220310700561, 291.522884035463 -69.09484948476472, 290.651799720616 -69.09484948476472, 290.651799720616 -69.40749586252385, 289.49035396748667 -69.40749586252385, 289.49035396748667 -69.72014224028295, 288.6192696526397 -69.72014224028295, 288.6192696526397 -70.03278861804208, 287.7481853377927 -70.03278861804208, 287.7481853377927 -70.3454349958012, 280.198787942452 -70.3454349958012, 280.198787942452 -70.65808137356031, 276.714450683064 -70.65808137356031, 276.714450683064 -70.97072775131943, 276.13372780649934 -70.97072775131943, 276.13372780649934 -70.65808137356031, 274.97228205337 -70.65808137356031, 274.97228205337 -70.3454349958012, 273.52047486195835 -70.3454349958012, 273.52047486195835 -70.03278861804208, 272.359029108829 -70.03278861804208, 272.359029108829 -69.72014224028295, 270.9072219174173 -69.72014224028295, 270.9072219174173 -69.40749586252385, 269.45541472600564 -69.40749586252385, 269.45541472600564 -69.09484948476472, 268.003607534594 -69.09484948476472, 268.003607534594 -68.78220310700561, 266.2614389049 -68.78220310700561, 266.2614389049 -68.46955672924649, 264.519270275206 -68.46955672924649, 264.519270275206 -68.15691035148738, 262.777101645512 -68.15691035148738, 262.777101645512 -67.84426397372826, 261.03493301581796 -67.84426397372826, 261.03493301581796 -67.53161759596915, 259.29276438612396 -67.53161759596915, 259.29276438612396 -67.21897121821003, 257.55059575642997 -67.21897121821003, 257.55059575642997 -66.9063248404509, 255.80842712673598 -66.9063248404509, 255.80842712673598 -66.5936784626918, 254.06625849704199 -66.5936784626918, 254.06625849704199 -66.28103208493268, 249.1301140462423 -66.28103208493268, 249.1301140462423 -65.96838570717357, 245.35541534857197 -65.96838570717357, 245.35541534857197 -65.65573932941444, 242.45180096574862 -65.65573932941444, 242.45180096574862 -65.34309295165534, 239.25782514464296 -65.34309295165534, 239.25782514464296 -65.03044657389621, 236.64457220010195 -65.03044657389621, 236.64457220010195 -64.71780019613709, 233.74095781727863 -64.71780019613709, 233.74095781727863 -64.40515381837798, 231.1277048727376 -64.40515381837798, 231.1277048727376 -64.09250744061886, 229.96625911960828 -64.09250744061886, 229.96625911960828 -63.77986106285975, 228.51445192819662 -63.77986106285975, 228.51445192819662 -63.46721468510063, 227.35300617506726 -63.46721468510063, 227.35300617506726 -63.15456830734151, 225.9011989836556 -63.15456830734151, 225.9011989836556 -62.8419219295824, 224.44939179224394 -62.8419219295824, 224.44939179224394 -62.52927555182328, 222.99758460083228 -62.52927555182328, 222.99758460083228 -62.21662917406417, 221.5457774094206 -62.21662917406417, 221.5457774094206 -61.90398279630505, 219.8036087797266 -61.90398279630505, 219.8036087797266 -61.591336418545936, 218.0614401500326 -61.591336418545936, 218.0614401500326 -61.27869004078681, 215.73854864377392 -61.27869004078681, 215.73854864377392 -60.9660436630277, 212.8349342609506 -60.9660436630277, 212.8349342609506 -60.65339728526858, 199.47830809996324 -60.65339728526858, 199.47830809996324 -60.34075090750947, 195.7036094022929 -60.34075090750947, 195.7036094022929 -60.65339728526858, 194.54216364916357 -60.65339728526858, 194.54216364916357 -60.9660436630277, 193.0903564577519 -60.9660436630277, 193.0903564577519 -61.27869004078681, 191.92891070462255 -61.27869004078681, 191.92891070462255 -61.591336418545936, 190.4771035132109 -61.591336418545936, 190.4771035132109 -61.90398279630505, 189.31565776008156 -61.90398279630505, 189.31565776008156 -62.21662917406417, 188.15421200695224 -62.21662917406417, 188.15421200695224 -62.52927555182328, 186.99276625382288 -62.52927555182328, 186.99276625382288 -62.8419219295824, 185.83132050069355 -62.8419219295824, 185.83132050069355 -63.15456830734151, 184.96023618584655 -63.15456830734151, 184.96023618584655 -63.46721468510063, 184.08915187099956 -63.46721468510063, 184.08915187099956 -63.77986106285975, 183.21806755615256 -63.77986106285975, 183.21806755615256 -64.09250744061886, 182.05662180302323 -64.09250744061886, 182.05662180302323 -64.40515381837798, 181.1855374881762 -64.40515381837798, 181.1855374881762 -64.71780019613709, 180.3144531733292 -64.71780019613709, 180.3144531733292 -65.03044657389621, 179.15300742019988 -65.03044657389621, 179.15300742019988 -65.34309295165534, 178.2819231053529 -65.34309295165534, 178.2819231053529 -65.65573932941444, 177.12047735222356 -65.65573932941444, 177.12047735222356 -65.96838570717357, 176.24939303737654 -65.96838570717357, 176.24939303737654 -66.28103208493268, 175.0879472842472 -66.28103208493268, 175.0879472842472 -66.5936784626918, 173.92650153111788 -66.5936784626918, 173.92650153111788 -66.9063248404509, 171.02288714829453 -66.9063248404509, 171.02288714829453 -67.21897121821003, 167.82891132718888 -67.21897121821003, 167.82891132718888 -67.53161759596915, 164.34457406780086 -67.53161759596915, 164.34457406780086 -67.84426397372826, 160.2795139318482 -67.84426397372826, 160.2795139318482 -68.15691035148738, 155.3433694810485 -68.15691035148738, 155.3433694810485 -68.46955672924649, 149.2457792771195 -68.46955672924649, 149.2457792771195 -68.78220310700561, 137.0505988692615 -68.78220310700561, 137.0505988692615 -68.46955672924649, 133.85662304815583 -68.46955672924649, 133.85662304815583 -68.15691035148738, 131.24337010361484 -68.15691035148738, 131.24337010361484 -67.84426397372826, 129.50120147392082 -67.84426397372826, 129.50120147392082 -67.53161759596915, 127.75903284422682 -67.53161759596915, 127.75903284422682 -67.21897121821003, 126.30722565281515 -67.21897121821003, 126.30722565281515 -66.9063248404509, 124.85541846140349 -66.9063248404509, 124.85541846140349 -66.5936784626918, 123.40361126999181 -66.5936784626918, 123.40361126999181 -66.28103208493268, 122.24216551686249 -66.28103208493268, 122.24216551686249 -65.96838570717357, 120.79035832545081 -65.96838570717357, 120.79035832545081 -65.65573932941444, 119.62891257232148 -65.65573932941444, 119.62891257232148 -65.34309295165534, 118.46746681919214 -65.34309295165534, 118.46746681919214 -65.03044657389621, 116.14457531293347 -65.03044657389621, 116.14457531293347 -64.71780019613709, 112.9505994918278 -64.71780019613709, 112.9505994918278 -64.40515381837798, 110.62770798556913 -64.40515381837798, 110.62770798556913 -64.09250744061886, 108.30481647931046 -64.09250744061886, 108.30481647931046 -63.77986106285975, 106.56264784961647 -63.77986106285975, 106.56264784961647 -63.46721468510063, 98.14216613942878 -63.46721468510063, 98.14216613942878 -63.15456830734151, 92.91566025034678 -63.15456830734151, 92.91566025034678 -63.46721468510063, 89.14096155267644 -63.46721468510063, 89.14096155267644 -63.77986106285975, 86.52770860813544 -63.77986106285975, 86.52770860813544 -64.09250744061886, 84.20481710187677 -64.09250744061886, 84.20481710187677 -64.40515381837798, 76.36505826825376 -64.40515381837798, 76.36505826825376 -64.71780019613709, 72.59035957058342 -64.71780019613709), + (72.29999813230108 -64.71780019613709, 69.68674518776008 -64.71780019613709, 69.68674518776008 -64.40515381837798, 66.78313080493675 -64.40515381837798, 66.78313080493675 -64.09250744061886, 64.16987786039574 -64.09250744061886, 64.16987786039574 -63.77986106285975, 61.55662491585474 -63.77986106285975, 61.55662491585474 -63.46721468510063, 59.81445628616074 -63.46721468510063, 59.81445628616074 -63.15456830734151, 58.653010533031406 -63.15456830734151, 58.653010533031406 -62.8419219295824, 57.49156477990207 -62.8419219295824, 57.49156477990207 -62.52927555182328, 56.330119026772735 -62.52927555182328, 56.330119026772735 -62.21662917406417, 55.45903471192573 -62.21662917406417, 55.45903471192573 -61.90398279630505, 54.297588958796396 -61.90398279630505, 54.297588958796396 -61.591336418545936, 53.4265046439494 -61.591336418545936, 53.4265046439494 -61.27869004078681, 52.5554203291024 -61.27869004078681, 52.5554203291024 -60.9660436630277, 51.68433601425539 -60.9660436630277, 51.68433601425539 -60.65339728526858, 50.8132516994084 -60.65339728526858, 50.8132516994084 -60.34075090750947, 50.232528822843726 -60.34075090750947, 50.232528822843726 -60.02810452975035, 49.36144450799673 -60.02810452975035, 49.36144450799673 -59.715458151991236, 47.909637316585055 -59.715458151991236, 47.909637316585055 -59.40281177423212, 46.74819156345572 -59.40281177423212, 46.74819156345572 -59.090165396473004, 45.29638437204405 -59.090165396473004, 45.29638437204405 -58.77751901871389, 44.13493861891472 -58.77751901871389, 44.13493861891472 -58.464872640954766, 42.97349286578539 -58.464872640954766, 42.97349286578539 -58.15222626319565, 41.81204711265605 -58.15222626319565, 41.81204711265605 -57.839579885436535, 40.65060135952672 -57.839579885436535, 40.65060135952672 -57.52693350767742, 39.48915560639738 -57.52693350767742, 39.48915560639738 -57.214287129918304, 38.32770985326805 -57.214287129918304, 38.32770985326805 -56.90164075215919, 37.16626410013871 -56.90164075215919, 37.16626410013871 -56.58899437440007, 35.714456908727044 -56.58899437440007, 35.714456908727044 -56.27634799664095, 33.972288279033044 -56.27634799664095, 33.972288279033044 -55.963701618881835, 32.23011964933904 -55.963701618881835, 32.23011964933904 -55.65105524112272, 30.48795101964504 -55.65105524112272, 30.48795101964504 -55.338408863363604, 28.165059513386367 -55.338408863363604, 28.165059513386367 -55.02576248560449, 24.971083692280697 -55.02576248560449, 24.971083692280697 -55.338408863363604, 22.93855362430436 -55.338408863363604, 22.93855362430436 -55.65105524112272, 21.777107871175026 -55.65105524112272, 21.777107871175026 -55.963701618881835, 20.61566211804569 -55.963701618881835, 20.61566211804569 -56.27634799664095, 19.74457780319869 -56.27634799664095), + (4.355421574235005 -55.02576248560449, 3.774698697670338 -55.02576248560449, 3.774698697670338 -55.338408863363604, 2.6132529445410033 -55.338408863363604, 2.6132529445410033 -55.65105524112272, 1.7421686296940022 -55.65105524112272, 1.7421686296940022 -55.963701618881835, 0.5807228765646674 -55.963701618881835, 0.5807228765646674 -56.27634799664095, 0 -56.27634799664095), + (25.551806568845365 0, 25.551806568845365 -0.3126463777591164, 25.842168007127697 -0.3126463777591164, 25.842168007127697 -0.6252927555182328, 26.132529445410032 -0.6252927555182328, 26.132529445410032 -0.9379391332773492, 26.422890883692364 -0.9379391332773492, 26.422890883692364 -1.2505855110364656, 26.7132523219747 -1.2505855110364656, 26.7132523219747 -1.563231888795582, 27.003613760257032 -1.563231888795582, 27.003613760257032 -2.8138173998320477, 26.7132523219747 -2.8138173998320477, 26.7132523219747 -3.126463777591164, 26.422890883692364 -3.126463777591164, 26.422890883692364 -3.4391101553502805, 26.132529445410032 -3.4391101553502805, 26.132529445410032 -3.751756533109397, 25.551806568845365 -3.751756533109397, 25.551806568845365 -4.064402910868513, 24.680722253998365 -4.064402910868513, 24.680722253998365 -4.37704928862763, 23.80963793915136 -4.37704928862763, 23.80963793915136 -4.689695666386746, 22.648192186022026 -4.689695666386746, 22.648192186022026 -5.002342044145863, 21.486746432892694 -5.002342044145863, 21.486746432892694 -5.314988421904979, 20.034939241481023 -5.314988421904979, 20.034939241481023 -5.627634799664095, 19.74457780319869 -5.627634799664095))MULTILINESTRING ((297.3301128011097 -61.27869004078681, 297.03975136282736 -61.27869004078681, 297.03975136282736 -61.591336418545936, 296.16866704798036 -61.591336418545936, 296.16866704798036 -61.90398279630505, 295.29758273313337 -61.90398279630505, 295.29758273313337 -62.21662917406417, 294.42649841828637 -62.21662917406417, 294.42649841828637 -62.52927555182328, 293.26505266515704 -62.52927555182328, 293.26505266515704 -62.8419219295824, 292.39396835031005 -62.8419219295824, 292.39396835031005 -63.15456830734151, 291.522884035463 -63.15456830734151, 291.522884035463 -63.46721468510063, 290.651799720616 -63.46721468510063, 290.651799720616 -63.77986106285975, 289.780715405769 -63.77986106285975, 289.780715405769 -64.09250744061886, 288.909631090922 -64.09250744061886, 288.909631090922 -64.40515381837798, 288.038546776075 -64.40515381837798, 288.038546776075 -64.71780019613709, 278.7469807510403 -64.71780019613709, 278.7469807510403 -65.03044657389621, 275.5530049299347 -65.03044657389621, 275.5530049299347 -64.71780019613709, 274.39155917680534 -64.71780019613709, 274.39155917680534 -64.40515381837798, 273.230113423676 -64.40515381837798, 273.230113423676 -64.09250744061886, 271.77830623226436 -64.09250744061886, 271.77830623226436 -63.77986106285975, 270.32649904085264 -63.77986106285975, 270.32649904085264 -63.46721468510063, 269.1650532877233 -63.46721468510063, 269.1650532877233 -63.15456830734151, 267.71324609631165 -63.15456830734151, 267.71324609631165 -62.8419219295824, 265.97107746661766 -62.8419219295824, 265.97107746661766 -62.52927555182328, 264.22890883692367 -62.52927555182328, 264.22890883692367 -62.21662917406417, 262.19637876894734 -62.21662917406417, 262.19637876894734 -61.90398279630505, 260.16384870097096 -61.90398279630505, 260.16384870097096 -61.591336418545936, 258.13131863299463 -61.591336418545936, 258.13131863299463 -61.27869004078681, 256.0987885650183 -61.27869004078681, 256.0987885650183 -60.9660436630277, 254.06625849704199 -60.9660436630277, 254.06625849704199 -60.65339728526858, 250.0011983610893 -60.65339728526858, 250.0011983610893 -60.34075090750947, 245.93613822513663 -60.34075090750947, 245.93613822513663 -60.02810452975035, 242.16143952746629 -60.02810452975035, 242.16143952746629 -59.715458151991236, 238.6771022680783 -59.715458151991236, 238.6771022680783 -59.40281177423212, 235.1927650086903 -59.40281177423212, 235.1927650086903 -59.090165396473004, 231.9987891875846 -59.090165396473004, 231.9987891875846 -58.77751901871389, 230.2566205578906 -58.77751901871389, 230.2566205578906 -58.464872640954766, 229.09517480476129 -58.464872640954766, 229.09517480476129 -58.15222626319565, 227.93372905163193 -58.15222626319565, 227.93372905163193 -57.839579885436535, 226.7722832985026 -57.839579885436535, 226.7722832985026 -57.52693350767742, 225.61083754537327 -57.52693350767742, 225.61083754537327 -57.214287129918304, 224.1590303539616 -57.214287129918304, 224.1590303539616 -56.90164075215919, 222.99758460083228 -56.90164075215919, 222.99758460083228 -56.58899437440007, 221.5457774094206 -56.58899437440007, 221.5457774094206 -56.27634799664095, 220.09397021800893 -56.27634799664095, 220.09397021800893 -55.963701618881835, 218.35180158831494 -55.963701618881835, 218.35180158831494 -55.65105524112272, 216.3192715203386 -55.65105524112272, 216.3192715203386 -55.338408863363604, 213.99638001407993 -55.338408863363604, 213.99638001407993 -55.02576248560449, 210.2216813164096 -55.02576248560449, 210.2216813164096 -54.71311610784537, 199.47830809996324 -54.71311610784537, 199.47830809996324 -54.40046973008626, 197.15541659370456 -54.40046973008626, 197.15541659370456 -54.08782335232714, 196.86505515542223 -54.08782335232714, 196.86505515542223 -54.40046973008626, 195.41324796401057 -54.40046973008626, 195.41324796401057 -54.71311610784537, 194.25180221088124 -54.71311610784537, 194.25180221088124 -55.02576248560449, 192.79999501946958 -55.02576248560449, 192.79999501946958 -55.338408863363604, 191.3481878280579 -55.338408863363604, 191.3481878280579 -55.65105524112272, 190.18674207492856 -55.65105524112272, 190.18674207492856 -55.963701618881835, 188.7349348835169 -55.963701618881835, 188.7349348835169 -56.27634799664095, 187.57348913038757 -56.27634799664095, 187.57348913038757 -56.58899437440007, 186.41204337725821 -56.58899437440007, 186.41204337725821 -56.90164075215919, 185.2505976241289 -56.90164075215919, 185.2505976241289 -57.214287129918304, 184.08915187099956 -57.214287129918304, 184.08915187099956 -57.52693350767742, 183.21806755615256 -57.52693350767742, 183.21806755615256 -57.839579885436535, 182.05662180302323 -57.839579885436535, 182.05662180302323 -58.15222626319565, 181.1855374881762 -58.15222626319565, 181.1855374881762 -58.464872640954766, 180.02409173504688 -58.464872640954766, 180.02409173504688 -58.77751901871389, 178.86264598191755 -58.77751901871389, 178.86264598191755 -59.090165396473004, 177.99156166707056 -59.090165396473004, 177.99156166707056 -59.40281177423212, 176.8301159139412 -59.40281177423212, 176.8301159139412 -59.715458151991236, 175.66867016081187 -59.715458151991236, 175.66867016081187 -60.02810452975035, 174.79758584596487 -60.02810452975035, 174.79758584596487 -60.34075090750947, 171.6036100248592 -60.34075090750947, 171.6036100248592 -60.65339728526858, 167.53854988890654 -60.65339728526858, 167.53854988890654 -60.9660436630277, 163.47348975295387 -60.9660436630277, 163.47348975295387 -61.27869004078681, 157.08553811074253 -61.27869004078681, 157.08553811074253 -61.591336418545936, 137.63132174582617 -61.591336418545936, 137.63132174582617 -61.27869004078681, 135.01806880128515 -61.27869004078681, 135.01806880128515 -60.9660436630277, 132.6951772950265 -60.9660436630277, 132.6951772950265 -60.65339728526858, 130.9530086653325 -60.65339728526858, 130.9530086653325 -60.34075090750947, 129.50120147392082 -60.34075090750947, 129.50120147392082 -60.02810452975035, 128.04939428250916 -60.02810452975035, 128.04939428250916 -59.715458151991236, 126.59758709109748 -59.715458151991236, 126.59758709109748 -59.40281177423212, 125.43614133796815 -59.40281177423212, 125.43614133796815 -59.090165396473004, 124.27469558483881 -59.090165396473004, 124.27469558483881 -58.77751901871389, 123.11324983170948 -58.77751901871389, 123.11324983170948 -58.464872640954766, 121.95180407858015 -58.464872640954766, 121.95180407858015 -58.15222626319565, 120.79035832545081 -58.15222626319565, 120.79035832545081 -57.839579885436535, 119.62891257232148 -57.839579885436535, 119.62891257232148 -57.52693350767742, 118.75782825747447 -57.52693350767742, 118.75782825747447 -57.214287129918304, 117.59638250434514 -57.214287129918304, 117.59638250434514 -56.90164075215919, 114.40240668323948 -56.90164075215919, 114.40240668323948 -56.58899437440007, 111.78915373869847 -56.58899437440007, 111.78915373869847 -56.27634799664095, 109.75662367072213 -56.27634799664095, 109.75662367072213 -55.963701618881835, 108.01445504102813 -55.963701618881835, 108.01445504102813 -55.65105524112272, 106.56264784961647 -55.65105524112272, 106.56264784961647 -55.338408863363604, 101.04578052225212 -55.338408863363604, 101.04578052225212 -55.02576248560449, 90.88313018237044 -55.02576248560449, 90.88313018237044 -55.338408863363604, 87.9795157995471 -55.338408863363604, 87.9795157995471 -55.65105524112272, 85.94698573157078 -55.65105524112272, 85.94698573157078 -55.963701618881835, 84.20481710187677 -55.963701618881835, 84.20481710187677 -56.27634799664095, 76.6554197065361 -56.27634799664095, 76.6554197065361 -56.58899437440007, 72.59035957058342 -56.58899437440007), + (72.29999813230108 -56.58899437440007, 69.39638374947775 -56.58899437440007, 69.39638374947775 -56.27634799664095, 66.78313080493675 -56.27634799664095, 66.78313080493675 -55.963701618881835, 64.46023929867808 -55.963701618881835, 64.46023929867808 -55.65105524112272, 61.84698635413707 -55.65105524112272, 61.84698635413707 -55.338408863363604, 60.395179162725405 -55.338408863363604, 60.395179162725405 -55.02576248560449, 59.23373340959607 -55.02576248560449, 59.23373340959607 -54.71311610784537, 58.072287656466735 -54.71311610784537, 58.072287656466735 -54.40046973008626, 57.20120334161974 -54.40046973008626, 57.20120334161974 -54.08782335232714, 56.0397575884904 -54.08782335232714, 56.0397575884904 -53.775176974568026, 55.1686732736434 -53.775176974568026, 55.1686732736434 -53.462530596808904, 54.297588958796396 -53.462530596808904, 54.297588958796396 -53.14988421904979, 53.71686608223173 -53.14988421904979, 53.71686608223173 -52.83723784129067, 52.84578176738473 -52.83723784129067, 52.84578176738473 -52.52459146353156, 51.97469745253773 -52.52459146353156, 51.97469745253773 -52.21194508577244, 51.39397457597306 -52.21194508577244, 51.39397457597306 -51.899298708013326, 50.52289026112606 -51.899298708013326, 50.52289026112606 -51.58665233025421, 49.942167384561394 -51.58665233025421, 49.942167384561394 -51.27400595249509, 49.07108306971439 -51.27400595249509, 49.07108306971439 -50.96135957473597, 47.909637316585055 -50.96135957473597, 47.909637316585055 -50.64871319697686, 46.74819156345572 -50.64871319697686, 46.74819156345572 -50.33606681921774, 45.58674581032639 -50.33606681921774, 45.58674581032639 -50.023420441458626, 44.71566149547939 -50.023420441458626, 44.71566149547939 -49.71077406369951, 43.55421574235005 -49.71077406369951, 43.55421574235005 -49.398127685940395, 42.39276998922072 -49.398127685940395, 42.39276998922072 -49.08548130818128, 41.23132423609138 -49.08548130818128, 41.23132423609138 -48.772834930422164, 40.36023992124438 -48.772834930422164, 40.36023992124438 -48.46018855266304, 39.19879416811505 -48.46018855266304, 39.19879416811505 -48.147542174903926, 38.32770985326805 -48.147542174903926, 38.32770985326805 -47.83489579714481, 37.16626410013871 -47.83489579714481, 37.16626410013871 -47.522249419385695, 35.714456908727044 -47.522249419385695, 35.714456908727044 -47.20960304162658, 34.26264971731538 -47.20960304162658, 34.26264971731538 -46.89695666386746, 32.81084252590371 -46.89695666386746, 32.81084252590371 -46.58431028610835, 31.359035334492038 -46.58431028610835, 31.359035334492038 -46.271663908349225, 29.616866704798035 -46.271663908349225, 29.616866704798035 -45.95901753059011, 27.5843366368217 -45.95901753059011, 27.5843366368217 -45.646371152830994, 24.39036081571603 -45.646371152830994, 24.39036081571603 -45.95901753059011, 22.06746930945736 -45.95901753059011, 22.06746930945736 -46.271663908349225, 20.906023556328027 -46.271663908349225, 20.906023556328027 -46.58431028610835, 19.74457780319869 -46.58431028610835), + (72.29999813230108 -7.81615944397791, 70.26746806432475 -7.81615944397791, 70.26746806432475 -8.128805821737027, 67.07349224321908 -8.128805821737027, 67.07349224321908 -8.441452199496144, 63.29879354554874 -8.441452199496144, 63.29879354554874 -8.75409857725526, 59.5240948478784 -8.75409857725526, 59.5240948478784 -9.066744955014375, 55.74939615020807 -9.066744955014375, 55.74939615020807 -9.379391332773492, 51.68433601425539 -9.379391332773492, 51.68433601425539 -9.69203771053261, 47.61927587830272 -9.69203771053261, 47.61927587830272 -10.004684088291725, 44.13493861891472 -10.004684088291725, 44.13493861891472 -10.31733046605084, 40.06987848296205 -10.31733046605084, 40.06987848296205 -10.629976843809958, 36.29517978529171 -10.629976843809958, 36.29517978529171 -10.942623221569075, 32.23011964933904 -10.942623221569075, 32.23011964933904 -11.25526959932819, 28.165059513386367 -11.25526959932819, 28.165059513386367 -11.567915977087306, 24.680722253998365 -11.567915977087306, 24.680722253998365 -11.880562354846424, 21.777107871175026 -11.880562354846424, 21.777107871175026 -12.193208732605541, 19.74457780319869 -12.193208732605541), + (92.62529881206444 0, 92.62529881206444 -0.3126463777591164, 92.91566025034678 -0.3126463777591164, 92.91566025034678 -0.6252927555182328, 93.20602168862911 -0.6252927555182328, 93.20602168862911 -0.9379391332773492, 93.49638312691144 -0.9379391332773492, 93.49638312691144 -1.2505855110364656, 93.78674456519379 -1.2505855110364656, 93.78674456519379 -1.563231888795582, 94.07710600347612 -1.563231888795582, 94.07710600347612 -3.126463777591164, 93.78674456519379 -3.126463777591164, 93.78674456519379 -3.4391101553502805, 93.20602168862911 -3.4391101553502805, 93.20602168862911 -3.751756533109397, 92.62529881206444 -3.751756533109397, 92.62529881206444 -4.064402910868513, 92.04457593549978 -4.064402910868513, 92.04457593549978 -4.37704928862763, 91.17349162065278 -4.37704928862763, 91.17349162065278 -4.689695666386746, 90.01204586752344 -4.689695666386746, 90.01204586752344 -5.002342044145863, 88.85060011439411 -5.002342044145863, 88.85060011439411 -5.314988421904979, 87.68915436126477 -5.314988421904979, 87.68915436126477 -5.627634799664095, 86.23734716985311 -5.627634799664095, 86.23734716985311 -5.940281177423212, 84.4951785401591 -5.940281177423212, 84.4951785401591 -6.252927555182328, 82.7530099104651 -6.252927555182328, 82.7530099104651 -6.565573932941445, 80.72047984248876 -6.565573932941445, 80.72047984248876 -6.878220310700561, 78.3975883362301 -6.878220310700561, 78.3975883362301 -7.1908666884596775, 76.07469682997143 -7.1908666884596775, 76.07469682997143 -7.503513066218794, 73.46144388543043 -7.503513066218794, 73.46144388543043 -7.81615944397791, 72.59035957058342 -7.81615944397791), + (4.355421574235005 -43.7704928862763, 3.4843372593880044 -43.7704928862763, 3.4843372593880044 -44.08313926403542, 1.4518071914116684 -44.08313926403542, 1.4518071914116684 -44.39578564179453, 0 -44.39578564179453), + (4.355421574235005 -13.13114786588289, 0.5807228765646674 -13.13114786588289, 0.5807228765646674 -13.443794243642007, 0 -13.443794243642007))MULTILINESTRING ((4.355421574235005 -33.765808797984576, 2.9036143828233367 -33.765808797984576, 2.9036143828233367 -34.07845517574369, 0 -34.07845517574369), + (72.29999813230108 -48.46018855266304, 72.00963669401875 -48.46018855266304, 72.00963669401875 -48.147542174903926, 69.39638374947775 -48.147542174903926, 69.39638374947775 -47.83489579714481, 67.07349224321908 -47.83489579714481, 67.07349224321908 -47.522249419385695, 65.04096217524274 -47.522249419385695, 65.04096217524274 -47.20960304162658, 62.718070668984076 -47.20960304162658, 62.718070668984076 -46.89695666386746, 60.97590203929008 -46.89695666386746, 60.97590203929008 -46.58431028610835, 59.81445628616074 -46.58431028610835, 59.81445628616074 -46.271663908349225, 58.94337197131374 -46.271663908349225, 58.94337197131374 -45.95901753059011, 58.072287656466735 -45.95901753059011, 58.072287656466735 -45.646371152830994, 57.20120334161974 -45.646371152830994, 57.20120334161974 -45.33372477507188, 56.330119026772735 -45.33372477507188, 56.330119026772735 -45.02107839731276, 55.74939615020807 -45.02107839731276, 55.74939615020807 -44.70843201955365, 54.87831183536107 -44.70843201955365, 54.87831183536107 -44.39578564179453, 54.297588958796396 -44.39578564179453, 54.297588958796396 -44.08313926403542, 53.4265046439494 -44.08313926403542, 53.4265046439494 -43.7704928862763, 52.84578176738473 -43.7704928862763, 52.84578176738473 -43.45784650851718, 52.265058890820065 -43.45784650851718, 52.265058890820065 -43.14520013075806, 51.68433601425539 -43.14520013075806, 51.68433601425539 -42.83255375299895, 50.8132516994084 -42.83255375299895, 50.8132516994084 -42.51990737523983, 50.232528822843726 -42.51990737523983, 50.232528822843726 -42.20726099748072, 49.65180594627906 -42.20726099748072, 49.65180594627906 -41.8946146197216, 48.78072163143206 -41.8946146197216, 48.78072163143206 -41.581968241962485, 47.61927587830272 -41.581968241962485, 47.61927587830272 -41.26932186420336, 46.74819156345572 -41.26932186420336, 46.74819156345572 -40.95667548644425, 45.58674581032639 -40.95667548644425, 45.58674581032639 -40.64402910868513, 44.71566149547939 -40.64402910868513, 44.71566149547939 -40.331382730926016, 43.55421574235005 -40.331382730926016, 43.55421574235005 -40.0187363531669, 42.68313142750305 -40.0187363531669, 42.68313142750305 -39.706089975407785, 41.81204711265605 -39.706089975407785, 41.81204711265605 -39.39344359764867, 40.65060135952672 -39.39344359764867, 40.65060135952672 -39.080797219889554, 39.779517044679714 -39.080797219889554, 39.779517044679714 -38.76815084213044, 38.61807129155038 -38.76815084213044, 38.61807129155038 -38.455504464371316, 37.746986976703376 -38.455504464371316, 37.746986976703376 -38.1428580866122, 36.29517978529171 -38.1428580866122, 36.29517978529171 -37.830211708853085, 35.13373403216237 -37.830211708853085, 35.13373403216237 -37.51756533109397, 33.681926840750705 -37.51756533109397, 33.681926840750705 -37.204918953334854, 32.23011964933904 -37.204918953334854, 32.23011964933904 -36.89227257557574, 30.48795101964504 -36.89227257557574, 30.48795101964504 -36.57962619781662, 28.745782389951035 -36.57962619781662, 28.745782389951035 -36.2669798200575, 26.132529445410032 -36.2669798200575, 26.132529445410032 -35.954333442298385, 23.51927650086903 -35.954333442298385, 23.51927650086903 -36.2669798200575, 20.61566211804569 -36.2669798200575, 20.61566211804569 -36.57962619781662, 19.74457780319869 -36.57962619781662), + (170.15180283344753 0, 170.15180283344753 -0.3126463777591164, 170.44216427172987 -0.3126463777591164, 170.44216427172987 -0.9379391332773492, 170.7325257100122 -0.9379391332773492, 170.7325257100122 -1.2505855110364656, 171.02288714829453 -1.2505855110364656, 171.02288714829453 -1.8758782665546985, 171.31324858657686 -1.8758782665546985, 171.31324858657686 -2.8138173998320477, 171.02288714829453 -2.8138173998320477, 171.02288714829453 -3.126463777591164, 170.7325257100122 -3.126463777591164, 170.7325257100122 -3.4391101553502805, 170.44216427172987 -3.4391101553502805, 170.44216427172987 -3.751756533109397, 170.15180283344753 -3.751756533109397, 170.15180283344753 -4.064402910868513, 169.57107995688287 -4.064402910868513, 169.57107995688287 -4.37704928862763, 168.69999564203587 -4.37704928862763, 168.69999564203587 -4.689695666386746, 167.82891132718888 -4.689695666386746, 167.82891132718888 -5.002342044145863, 166.95782701234188 -5.002342044145863, 166.95782701234188 -5.314988421904979, 165.79638125921252 -5.314988421904979, 165.79638125921252 -5.627634799664095, 164.6349355060832 -5.627634799664095, 164.6349355060832 -5.940281177423212, 163.18312831467154 -5.940281177423212, 163.18312831467154 -6.252927555182328, 160.86023680841285 -6.252927555182328, 160.86023680841285 -6.565573932941445, 158.24698386387186 -6.565573932941445, 158.24698386387186 -6.878220310700561, 155.63373091933084 -6.878220310700561, 155.63373091933084 -7.1908666884596775, 153.02047797478986 -7.1908666884596775, 153.02047797478986 -7.503513066218794, 150.1168635919665 -7.503513066218794, 150.1168635919665 -7.81615944397791, 147.21324920914319 -7.81615944397791, 147.21324920914319 -8.128805821737027, 144.30963482631984 -8.128805821737027, 144.30963482631984 -8.441452199496144, 141.40602044349652 -8.441452199496144, 141.40602044349652 -8.75409857725526, 137.9216831841085 -8.75409857725526, 137.9216831841085 -9.066744955014375, 134.14698448643816 -9.066744955014375, 134.14698448643816 -9.379391332773492, 130.3722857887678 -9.379391332773492, 130.3722857887678 -9.69203771053261, 126.59758709109748 -9.69203771053261, 126.59758709109748 -10.004684088291725, 122.53252695514482 -10.004684088291725, 122.53252695514482 -10.31733046605084, 118.17710538090981 -10.31733046605084, 118.17710538090981 -10.629976843809958, 114.40240668323948 -10.629976843809958, 114.40240668323948 -10.942623221569075, 110.3373465472868 -10.942623221569075, 110.3373465472868 -11.25526959932819, 106.27228641133412 -11.25526959932819, 106.27228641133412 -11.567915977087306, 102.49758771366379 -11.567915977087306, 102.49758771366379 -11.880562354846424, 98.72288901599346 -11.880562354846424, 98.72288901599346 -12.193208732605541, 94.94819031832311 -12.193208732605541, 94.94819031832311 -12.505855110364656, 91.46385305893511 -12.505855110364656, 91.46385305893511 -12.818501488123772, 87.9795157995471 -12.818501488123772, 87.9795157995471 -13.13114786588289, 84.20481710187677 -13.13114786588289, 84.20481710187677 -13.443794243642007, 80.1397569659241 -13.443794243642007, 80.1397569659241 -13.756440621401122, 75.49397395340675 -13.756440621401122, 75.49397395340675 -14.069086999160238, 72.59035957058342 -14.069086999160238), + (72.29999813230108 -14.069086999160238, 70.84819094088942 -14.069086999160238, 70.84819094088942 -14.381733376919355, 65.91204649008975 -14.381733376919355, 65.91204649008975 -14.694379754678472, 60.68554060100774 -14.694379754678472, 60.68554060100774 -15.007026132437588, 55.74939615020807 -15.007026132437588, 55.74939615020807 -15.319672510196703, 50.232528822843726 -15.319672510196703, 50.232528822843726 -15.63231888795582, 45.87710724860872 -15.63231888795582, 45.87710724860872 -15.944965265714938, 41.521685674373714 -15.944965265714938, 41.521685674373714 -16.257611643474053, 37.16626410013871 -16.257611643474053, 37.16626410013871 -16.57025802123317, 32.23011964933904 -16.57025802123317, 32.23011964933904 -16.882904398992288, 27.003613760257032 -16.882904398992288, 27.003613760257032 -17.195550776751404, 24.099999377433697 -17.195550776751404, 24.099999377433697 -17.50819715451052, 21.19638499461036 -17.50819715451052, 21.19638499461036 -17.820843532269635, 19.74457780319869 -17.820843532269635), + (4.355421574235005 -18.13348991002875, 3.4843372593880044 -18.13348991002875, 3.4843372593880044 -18.44613628778787, 0 -18.44613628778787), + (297.3301128011097 -55.65105524112272, 297.03975136282736 -55.65105524112272, 297.03975136282736 -55.963701618881835, 295.87830560969803 -55.963701618881835, 295.87830560969803 -56.27634799664095, 295.00722129485104 -56.27634799664095, 295.00722129485104 -56.58899437440007, 294.13613698000404 -56.58899437440007, 294.13613698000404 -56.90164075215919, 293.26505266515704 -56.90164075215919, 293.26505266515704 -57.214287129918304, 292.39396835031005 -57.214287129918304, 292.39396835031005 -57.52693350767742, 291.8132454737453 -57.52693350767742, 291.8132454737453 -57.839579885436535, 290.94216115889833 -57.839579885436535, 290.94216115889833 -58.15222626319565, 290.07107684405133 -58.15222626319565, 290.07107684405133 -58.464872640954766, 289.19999252920434 -58.464872640954766, 289.19999252920434 -58.77751901871389, 288.32890821435734 -58.77751901871389, 288.32890821435734 -59.090165396473004, 277.29517355962867 -59.090165396473004, 277.29517355962867 -59.40281177423212, 276.13372780649934 -59.40281177423212, 276.13372780649934 -59.090165396473004, 274.97228205337 -59.090165396473004, 274.97228205337 -58.77751901871389, 273.8108363002407 -58.77751901871389, 273.8108363002407 -58.464872640954766, 272.64939054711135 -58.464872640954766, 272.64939054711135 -58.15222626319565, 271.48794479398197 -58.15222626319565, 271.48794479398197 -57.839579885436535, 270.32649904085264 -57.839579885436535, 270.32649904085264 -57.52693350767742, 268.874691849441 -57.52693350767742, 268.874691849441 -57.214287129918304, 267.71324609631165 -57.214287129918304, 267.71324609631165 -56.90164075215919, 266.2614389049 -56.90164075215919, 266.2614389049 -56.58899437440007, 264.519270275206 -56.58899437440007, 264.519270275206 -56.27634799664095, 262.19637876894734 -56.27634799664095, 262.19637876894734 -55.963701618881835, 259.8734872626886 -55.963701618881835, 259.8734872626886 -55.65105524112272, 257.26023431814764 -55.65105524112272, 257.26023431814764 -55.338408863363604, 254.93734281188898 -55.338408863363604, 254.93734281188898 -55.02576248560449, 251.7433669907833 -55.02576248560449, 251.7433669907833 -54.71311610784537, 247.09758397826596 -54.71311610784537, 247.09758397826596 -54.40046973008626, 242.45180096574862 -54.40046973008626, 242.45180096574862 -54.08782335232714, 238.96746370636063 -54.08782335232714, 238.96746370636063 -53.775176974568026, 235.48312644697262 -53.775176974568026, 235.48312644697262 -53.462530596808904, 232.28915062586694 -53.462530596808904, 232.28915062586694 -53.14988421904979, 230.54698199617295 -53.14988421904979, 230.54698199617295 -52.83723784129067, 229.38553624304362 -52.83723784129067, 229.38553624304362 -52.52459146353156, 228.51445192819662 -52.52459146353156, 228.51445192819662 -52.21194508577244, 227.35300617506726 -52.21194508577244, 227.35300617506726 -51.899298708013326, 226.48192186022027 -51.899298708013326, 226.48192186022027 -51.58665233025421, 225.32047610709094 -51.58665233025421, 225.32047610709094 -51.27400595249509, 224.1590303539616 -51.27400595249509, 224.1590303539616 -50.96135957473597, 222.99758460083228 -50.96135957473597, 222.99758460083228 -50.64871319697686, 221.5457774094206 -50.64871319697686, 221.5457774094206 -50.33606681921774, 220.38433165629127 -50.33606681921774, 220.38433165629127 -50.023420441458626, 218.64216302659727 -50.023420441458626, 218.64216302659727 -49.71077406369951, 216.89999439690325 -49.71077406369951, 216.89999439690325 -49.398127685940395, 214.28674145236226 -49.398127685940395, 214.28674145236226 -49.08548130818128, 211.09276563125658 -49.08548130818128, 211.09276563125658 -48.772834930422164, 202.09156104450423 -48.772834930422164, 202.09156104450423 -48.46018855266304, 198.89758522339858 -48.46018855266304, 198.89758522339858 -48.147542174903926, 195.7036094022929 -48.147542174903926, 195.7036094022929 -48.46018855266304, 194.25180221088124 -48.46018855266304, 194.25180221088124 -48.772834930422164, 192.79999501946958 -48.772834930422164, 192.79999501946958 -49.08548130818128, 191.63854926634022 -49.08548130818128, 191.63854926634022 -49.398127685940395, 190.18674207492856 -49.398127685940395, 190.18674207492856 -49.71077406369951, 188.7349348835169 -49.71077406369951, 188.7349348835169 -50.023420441458626, 187.57348913038757 -50.023420441458626, 187.57348913038757 -50.33606681921774, 186.12168193897588 -50.33606681921774, 186.12168193897588 -50.64871319697686, 184.96023618584655 -50.64871319697686, 184.96023618584655 -50.96135957473597, 183.79879043271723 -50.96135957473597, 183.79879043271723 -51.27400595249509, 182.6373446795879 -51.27400595249509, 182.6373446795879 -51.58665233025421, 181.47589892645854 -51.58665233025421, 181.47589892645854 -51.899298708013326, 180.3144531733292 -51.899298708013326, 180.3144531733292 -52.21194508577244, 179.15300742019988 -52.21194508577244, 179.15300742019988 -52.52459146353156, 177.99156166707056 -52.52459146353156, 177.99156166707056 -52.83723784129067, 176.8301159139412 -52.83723784129067, 176.8301159139412 -53.14988421904979, 175.9590315990942 -53.14988421904979, 175.9590315990942 -53.462530596808904, 174.79758584596487 -53.462530596808904, 174.79758584596487 -53.775176974568026, 170.7325257100122 -53.775176974568026, 170.7325257100122 -54.08782335232714, 165.79638125921252 -54.08782335232714, 165.79638125921252 -54.40046973008626, 157.6662609873072 -54.40046973008626, 157.6662609873072 -54.71311610784537, 142.2771047583435 -54.71311610784537, 142.2771047583435 -54.40046973008626, 138.21204462239083 -54.40046973008626, 138.21204462239083 -54.08782335232714, 135.88915311613218 -54.08782335232714, 135.88915311613218 -53.775176974568026, 133.85662304815583 -53.775176974568026, 133.85662304815583 -53.462530596808904, 132.40481585674416 -53.462530596808904, 132.40481585674416 -53.14988421904979, 130.9530086653325 -53.14988421904979, 130.9530086653325 -52.83723784129067, 129.50120147392082 -52.83723784129067, 129.50120147392082 -52.52459146353156, 128.3397557207915 -52.52459146353156, 128.3397557207915 -52.21194508577244, 127.17830996766216 -52.21194508577244, 127.17830996766216 -51.899298708013326, 126.01686421453282 -51.899298708013326, 126.01686421453282 -51.58665233025421, 125.14577989968582 -51.58665233025421, 125.14577989968582 -51.27400595249509, 123.98433414655648 -51.27400595249509, 123.98433414655648 -50.96135957473597, 123.11324983170948 -50.96135957473597, 123.11324983170948 -50.64871319697686, 122.24216551686249 -50.64871319697686, 122.24216551686249 -50.33606681921774, 121.08071976373314 -50.33606681921774, 121.08071976373314 -50.023420441458626, 120.20963544888615 -50.023420441458626, 120.20963544888615 -49.71077406369951, 119.33855113403915 -49.71077406369951, 119.33855113403915 -49.398127685940395, 118.46746681919214 -49.398127685940395, 118.46746681919214 -49.08548130818128, 117.30602106606281 -49.08548130818128, 117.30602106606281 -48.772834930422164, 114.40240668323948 -48.772834930422164, 114.40240668323948 -48.46018855266304, 112.36987661526314 -48.46018855266304, 112.36987661526314 -48.147542174903926, 110.62770798556913 -48.147542174903926, 110.62770798556913 -47.83489579714481, 108.88553935587512 -47.83489579714481, 108.88553935587512 -47.522249419385695, 107.7240936027458 -47.522249419385695, 107.7240936027458 -47.20960304162658, 106.27228641133412 -47.20960304162658, 106.27228641133412 -46.89695666386746, 101.91686483709913 -46.89695666386746, 101.91686483709913 -46.58431028610835, 96.69035894801712 -46.58431028610835, 96.69035894801712 -46.271663908349225, 92.91566025034678 -46.271663908349225, 92.91566025034678 -46.58431028610835, 89.72168442924111 -46.58431028610835, 89.72168442924111 -46.89695666386746, 87.39879292298244 -46.89695666386746, 87.39879292298244 -47.20960304162658, 85.65662429328843 -47.20960304162658, 85.65662429328843 -47.522249419385695, 83.91445566359444 -47.522249419385695, 83.91445566359444 -47.83489579714481, 76.94578114481843 -47.83489579714481, 76.94578114481843 -48.147542174903926, 72.59035957058342 -48.147542174903926))MULTILINESTRING ((246.80722253998363 0, 246.80722253998363 -0.3126463777591164, 247.09758397826596 -0.3126463777591164, 247.09758397826596 -0.9379391332773492, 247.3879454165483 -0.9379391332773492, 247.3879454165483 -1.8758782665546985, 247.67830685483062 -1.8758782665546985, 247.67830685483062 -2.5011710220729313, 247.3879454165483 -2.5011710220729313, 247.3879454165483 -3.4391101553502805, 247.09758397826596 -3.4391101553502805, 247.09758397826596 -3.751756533109397, 246.80722253998363 -3.751756533109397, 246.80722253998363 -4.064402910868513, 246.5168611017013 -4.064402910868513, 246.5168611017013 -4.37704928862763, 245.93613822513663 -4.37704928862763, 245.93613822513663 -4.689695666386746, 245.6457767868543 -4.689695666386746, 245.6457767868543 -5.002342044145863, 245.06505391028963 -5.002342044145863, 245.06505391028963 -5.314988421904979, 244.48433103372497 -5.314988421904979, 244.48433103372497 -5.627634799664095, 243.61324671887797 -5.627634799664095, 243.61324671887797 -5.940281177423212, 242.74216240403095 -5.940281177423212, 242.74216240403095 -6.252927555182328, 242.16143952746629 -6.252927555182328, 242.16143952746629 -6.565573932941445, 241.2903552126193 -6.565573932941445, 241.2903552126193 -6.878220310700561, 240.4192708977723 -6.878220310700561, 240.4192708977723 -7.1908666884596775, 239.83854802120763 -7.1908666884596775, 239.83854802120763 -7.503513066218794, 238.6771022680783 -7.503513066218794, 238.6771022680783 -7.81615944397791, 237.80601795323128 -7.81615944397791, 237.80601795323128 -8.128805821737027, 236.93493363838428 -8.128805821737027, 236.93493363838428 -8.441452199496144, 235.77348788525495 -8.441452199496144, 235.77348788525495 -8.75409857725526, 234.61204213212562 -8.75409857725526, 234.61204213212562 -9.066744955014375, 233.74095781727863 -9.066744955014375, 233.74095781727863 -9.379391332773492, 232.57951206414927 -9.379391332773492, 232.57951206414927 -9.69203771053261, 231.1277048727376 -9.69203771053261, 231.1277048727376 -10.004684088291725, 229.67589768132595 -10.004684088291725, 229.67589768132595 -10.31733046605084, 228.2240904899143 -10.31733046605084, 228.2240904899143 -10.629976843809958, 226.48192186022027 -10.629976843809958, 226.48192186022027 -10.942623221569075, 224.73975323052628 -10.942623221569075, 224.73975323052628 -11.25526959932819, 222.70722316254992 -11.25526959932819, 222.70722316254992 -11.567915977087306, 220.6746930945736 -11.567915977087306, 220.6746930945736 -11.880562354846424, 218.0614401500326 -11.880562354846424, 218.0614401500326 -12.193208732605541, 214.5771028906446 -12.193208732605541, 214.5771028906446 -12.505855110364656, 210.2216813164096 -12.505855110364656, 210.2216813164096 -12.818501488123772, 200.34939241481024 -12.818501488123772, 200.34939241481024 -13.13114786588289, 192.79999501946958 -13.13114786588289, 192.79999501946958 -13.443794243642007, 187.8638505686699 -13.443794243642007, 187.8638505686699 -13.756440621401122, 183.5084289944349 -13.756440621401122, 183.5084289944349 -14.069086999160238, 180.02409173504688 -14.069086999160238, 180.02409173504688 -14.381733376919355, 176.24939303737654 -14.381733376919355, 176.24939303737654 -14.694379754678472, 171.6036100248592 -14.694379754678472, 171.6036100248592 -15.007026132437588, 166.3771041357772 -15.007026132437588, 166.3771041357772 -15.319672510196703, 157.95662242558953 -15.319672510196703, 157.95662242558953 -15.63231888795582, 148.08433352399018 -15.63231888795582, 148.08433352399018 -15.944965265714938, 139.6638518138025 -15.944965265714938, 139.6638518138025 -16.257611643474053, 132.98553873330883 -16.257611643474053, 132.98553873330883 -16.57025802123317, 127.46867140594449 -16.57025802123317, 127.46867140594449 -16.882904398992288, 123.69397270827415 -16.882904398992288, 123.69397270827415 -17.195550776751404, 119.33855113403915 -17.195550776751404, 119.33855113403915 -17.50819715451052, 115.27349099808647 -17.50819715451052, 115.27349099808647 -17.820843532269635, 111.2084308621338 -17.820843532269635, 111.2084308621338 -18.13348991002875, 107.14337072618113 -18.13348991002875, 107.14337072618113 -18.44613628778787, 102.49758771366379 -18.44613628778787, 102.49758771366379 -18.758782665546985, 98.43252757771111 -18.758782665546985, 98.43252757771111 -19.0714290433061, 94.94819031832311 -19.0714290433061, 94.94819031832311 -19.38407542106522, 90.88313018237044 -19.38407542106522, 90.88313018237044 -19.696721798824335, 86.81807004641777 -19.696721798824335, 86.81807004641777 -20.00936817658345, 82.7530099104651 -20.00936817658345, 82.7530099104651 -20.322014554342566, 78.97831121279476 -20.322014554342566, 78.97831121279476 -20.63466093210168, 74.62288963855976 -20.63466093210168, 74.62288963855976 -20.9473073098608, 72.59035957058342 -20.9473073098608), + (72.29999813230108 -20.9473073098608, 70.55782950260709 -20.9473073098608, 70.55782950260709 -21.259953687619916, 67.65421511978374 -21.259953687619916, 67.65421511978374 -21.57260006537903, 64.75060073696041 -21.57260006537903, 64.75060073696041 -21.88524644313815, 62.137347792419405 -21.88524644313815, 62.137347792419405 -22.197892820897266, 60.10481772444307 -22.197892820897266, 60.10481772444307 -22.51053919865638, 58.653010533031406 -22.51053919865638, 58.653010533031406 -22.823185576415497, 57.20120334161974 -22.823185576415497, 57.20120334161974 -23.135831954174613, 55.74939615020807 -23.135831954174613, 55.74939615020807 -23.44847833193373, 54.587950397078735 -23.44847833193373, 54.587950397078735 -23.761124709692847, 53.71686608223173 -23.761124709692847, 53.71686608223173 -24.073771087451963, 52.84578176738473 -24.073771087451963, 52.84578176738473 -24.386417465211082, 51.97469745253773 -24.386417465211082, 51.97469745253773 -24.699063842970197, 51.39397457597306 -24.699063842970197, 51.39397457597306 -25.011710220729313, 51.10361313769073 -25.011710220729313, 51.10361313769073 -25.32435659848843, 50.52289026112606 -25.32435659848843, 50.52289026112606 -25.637002976247544, 50.232528822843726 -25.637002976247544, 50.232528822843726 -26.26229573176578, 49.942167384561394 -26.26229573176578, 49.942167384561394 -27.20023486504313, 50.232528822843726 -27.20023486504313, 50.232528822843726 -27.82552762056136, 50.52289026112606 -27.82552762056136, 50.52289026112606 -28.450820376079594, 50.8132516994084 -28.450820376079594, 50.8132516994084 -28.76346675383871, 51.10361313769073 -28.76346675383871, 51.10361313769073 -29.076113131597825, 51.39397457597306 -29.076113131597825, 51.39397457597306 -29.388759509356944, 51.68433601425539 -29.388759509356944, 51.68433601425539 -29.70140588711606, 51.97469745253773 -29.70140588711606, 51.97469745253773 -30.014052264875176, 52.5554203291024 -30.014052264875176, 52.5554203291024 -30.32669864263429, 52.84578176738473 -30.32669864263429, 52.84578176738473 -30.639345020393407, 53.13614320566706 -30.639345020393407, 53.13614320566706 -30.951991398152526, 53.71686608223173 -30.951991398152526, 53.71686608223173 -31.26463777591164, 54.007227520514064 -31.26463777591164, 54.007227520514064 -31.577284153670757, 54.587950397078735 -31.577284153670757, 54.587950397078735 -31.889930531429876, 54.87831183536107 -31.889930531429876, 54.87831183536107 -32.20257690918899, 55.45903471192573 -32.20257690918899, 55.45903471192573 -32.51522328694811, 56.0397575884904 -32.51522328694811, 56.0397575884904 -32.82786966470722, 56.62048046505507 -32.82786966470722, 56.62048046505507 -33.14051604246634, 57.20120334161974 -33.14051604246634, 57.20120334161974 -33.45316242022545, 57.49156477990207 -33.45316242022545, 57.49156477990207 -33.765808797984576, 58.072287656466735 -33.765808797984576, 58.072287656466735 -34.07845517574369, 58.653010533031406 -34.07845517574369, 58.653010533031406 -34.39110155350281, 59.5240948478784 -34.39110155350281, 59.5240948478784 -34.70374793126192, 60.10481772444307 -34.70374793126192, 60.10481772444307 -35.01639430902104, 60.68554060100774 -35.01639430902104, 60.68554060100774 -35.329040686780154, 61.84698635413707 -35.329040686780154, 61.84698635413707 -35.64168706453927, 63.00843210726641 -35.64168706453927, 63.00843210726641 -35.954333442298385, 64.46023929867808 -35.954333442298385, 64.46023929867808 -36.2669798200575, 65.91204649008975 -36.2669798200575, 65.91204649008975 -36.57962619781662, 67.36385368150141 -36.57962619781662, 67.36385368150141 -36.89227257557574, 68.81566087291309 -36.89227257557574, 68.81566087291309 -37.204918953334854, 70.55782950260709 -37.204918953334854, 70.55782950260709 -37.51756533109397, 72.29999813230108 -37.51756533109397), + (297.3301128011097 -49.71077406369951, 296.4590284862627 -49.71077406369951, 296.4590284862627 -50.023420441458626, 295.5879441714157 -50.023420441458626, 295.5879441714157 -50.33606681921774, 294.7168598565687 -50.33606681921774, 294.7168598565687 -50.64871319697686, 293.8457755417217 -50.64871319697686, 293.8457755417217 -50.96135957473597, 292.9746912268747 -50.96135957473597, 292.9746912268747 -51.27400595249509, 292.39396835031005 -51.27400595249509, 292.39396835031005 -51.58665233025421, 291.522884035463 -51.58665233025421, 291.522884035463 -51.899298708013326, 290.651799720616 -51.899298708013326, 290.651799720616 -52.21194508577244, 290.07107684405133 -52.21194508577244, 290.07107684405133 -52.52459146353156, 289.19999252920434 -52.52459146353156, 289.19999252920434 -52.83723784129067, 288.6192696526397 -52.83723784129067, 288.6192696526397 -53.14988421904979, 287.7481853377927 -53.14988421904979, 287.7481853377927 -53.462530596808904, 286.58673958466335 -53.462530596808904, 286.58673958466335 -53.14988421904979, 275.843366368217 -53.14988421904979, 275.843366368217 -52.83723784129067, 274.97228205337 -52.83723784129067, 274.97228205337 -52.52459146353156, 274.101197738523 -52.52459146353156, 274.101197738523 -52.21194508577244, 272.9397519853937 -52.21194508577244, 272.9397519853937 -51.899298708013326, 272.0686676705467 -51.899298708013326, 272.0686676705467 -51.58665233025421, 270.9072219174173 -51.58665233025421, 270.9072219174173 -51.27400595249509, 269.745776164288 -51.27400595249509, 269.745776164288 -50.96135957473597, 268.874691849441 -50.96135957473597, 268.874691849441 -50.64871319697686, 267.71324609631165 -50.64871319697686, 267.71324609631165 -50.33606681921774, 266.5518003431823 -50.33606681921774, 266.5518003431823 -50.023420441458626, 265.390354590053 -50.023420441458626, 265.390354590053 -49.71077406369951, 262.777101645512 -49.71077406369951, 262.777101645512 -49.398127685940395, 260.16384870097096 -49.398127685940395, 260.16384870097096 -49.08548130818128, 257.55059575642997 -49.08548130818128, 257.55059575642997 -48.772834930422164, 254.93734281188898 -48.772834930422164, 254.93734281188898 -48.46018855266304, 250.0011983610893 -48.46018855266304, 250.0011983610893 -48.147542174903926, 243.9036081571603 -48.147542174903926, 243.9036081571603 -47.83489579714481, 240.4192708977723 -47.83489579714481, 240.4192708977723 -47.522249419385695, 237.51565651494894 -47.522249419385695, 237.51565651494894 -47.20960304162658, 234.90240357040796 -47.20960304162658, 234.90240357040796 -46.89695666386746, 232.28915062586694 -46.89695666386746, 232.28915062586694 -46.58431028610835, 230.54698199617295 -46.58431028610835, 230.54698199617295 -46.271663908349225, 229.96625911960828 -46.271663908349225, 229.96625911960828 -45.95901753059011, 229.09517480476129 -45.95901753059011, 229.09517480476129 -45.646371152830994, 228.2240904899143 -45.646371152830994, 228.2240904899143 -45.33372477507188, 227.35300617506726 -45.33372477507188, 227.35300617506726 -45.02107839731276, 226.48192186022027 -45.02107839731276, 226.48192186022027 -44.70843201955365, 225.61083754537327 -44.70843201955365, 225.61083754537327 -44.39578564179453, 224.73975323052628 -44.39578564179453, 224.73975323052628 -44.08313926403542, 223.86866891567928 -44.08313926403542, 223.86866891567928 -43.7704928862763, 222.70722316254992 -43.7704928862763, 222.70722316254992 -43.45784650851718, 221.83613884770293 -43.45784650851718, 221.83613884770293 -43.14520013075806, 220.6746930945736 -43.14520013075806, 220.6746930945736 -42.83255375299895, 219.51324734144427 -42.83255375299895, 219.51324734144427 -42.51990737523983, 217.19035583518558 -42.51990737523983, 217.19035583518558 -42.20726099748072, 214.5771028906446 -42.20726099748072, 214.5771028906446 -41.8946146197216, 211.09276563125658 -41.8946146197216, 211.09276563125658 -41.581968241962485, 203.83372967419825 -41.581968241962485, 203.83372967419825 -41.26932186420336, 200.0590309765279 -41.26932186420336, 200.0590309765279 -40.95667548644425, 197.44577803198692 -40.95667548644425, 197.44577803198692 -40.64402910868513, 196.5746937171399 -40.64402910868513, 196.5746937171399 -40.95667548644425, 195.41324796401057 -40.95667548644425, 195.41324796401057 -41.26932186420336, 193.9614407725989 -41.26932186420336, 193.9614407725989 -41.581968241962485, 192.50963358118724 -41.581968241962485, 192.50963358118724 -41.8946146197216, 191.05782638977556 -41.8946146197216, 191.05782638977556 -42.20726099748072, 189.89638063664623 -42.20726099748072, 189.89638063664623 -42.51990737523983, 188.44457344523457 -42.51990737523983, 188.44457344523457 -42.83255375299895, 186.99276625382288 -42.83255375299895, 186.99276625382288 -43.14520013075806, 185.83132050069355 -43.14520013075806, 185.83132050069355 -43.45784650851718, 184.3795133092819 -43.45784650851718, 184.3795133092819 -43.7704928862763, 182.92770611787023 -43.7704928862763, 182.92770611787023 -44.08313926403542, 181.76626036474087 -44.08313926403542, 181.76626036474087 -44.39578564179453, 180.60481461161154 -44.39578564179453, 180.60481461161154 -44.70843201955365, 179.15300742019988 -44.70843201955365, 179.15300742019988 -45.02107839731276, 177.99156166707056 -45.02107839731276, 177.99156166707056 -45.33372477507188, 177.12047735222356 -45.33372477507188, 177.12047735222356 -45.646371152830994, 175.9590315990942 -45.646371152830994, 175.9590315990942 -45.95901753059011, 174.79758584596487 -45.95901753059011, 174.79758584596487 -46.271663908349225, 169.28071851860054 -46.271663908349225, 169.28071851860054 -46.58431028610835, 161.73132112325987 -46.58431028610835, 161.73132112325987 -46.89695666386746, 149.82650215368417 -46.89695666386746, 149.82650215368417 -46.58431028610835, 141.69638188177885 -46.58431028610835, 141.69638188177885 -46.271663908349225, 138.7927674989555 -46.271663908349225, 138.7927674989555 -45.95901753059011, 137.0505988692615 -45.95901753059011, 137.0505988692615 -45.646371152830994, 135.30843023956749 -45.646371152830994, 135.30843023956749 -45.33372477507188, 133.85662304815583 -45.33372477507188, 133.85662304815583 -45.02107839731276, 132.6951772950265 -45.02107839731276, 132.6951772950265 -44.70843201955365, 131.53373154189717 -44.70843201955365, 131.53373154189717 -44.39578564179453, 130.3722857887678 -44.39578564179453, 130.3722857887678 -44.08313926403542, 129.50120147392082 -44.08313926403542, 129.50120147392082 -43.7704928862763, 128.3397557207915 -43.7704928862763, 128.3397557207915 -43.45784650851718, 127.46867140594449 -43.45784650851718, 127.46867140594449 -43.14520013075806, 126.59758709109748 -43.14520013075806, 126.59758709109748 -42.83255375299895, 125.72650277625048 -42.83255375299895, 125.72650277625048 -42.51990737523983, 125.14577989968582 -42.51990737523983, 125.14577989968582 -42.20726099748072, 124.27469558483881 -42.20726099748072, 124.27469558483881 -41.8946146197216, 123.40361126999181 -41.8946146197216, 123.40361126999181 -41.581968241962485, 122.82288839342715 -41.581968241962485, 122.82288839342715 -41.26932186420336, 121.95180407858015 -41.26932186420336, 121.95180407858015 -40.95667548644425, 121.08071976373314 -40.95667548644425, 121.08071976373314 -40.64402910868513, 120.49999688716848 -40.64402910868513, 120.49999688716848 -40.331382730926016, 119.62891257232148 -40.331382730926016, 119.62891257232148 -40.0187363531669, 119.0481896957568 -40.0187363531669, 119.0481896957568 -39.706089975407785, 118.17710538090981 -39.706089975407785, 118.17710538090981 -39.39344359764867, 117.01565962778048 -39.39344359764867, 117.01565962778048 -39.080797219889554, 114.98312955980414 -39.080797219889554, 114.98312955980414 -38.76815084213044, 113.24096093011013 -38.76815084213044, 113.24096093011013 -38.455504464371316, 111.78915373869847 -38.455504464371316, 111.78915373869847 -38.1428580866122, 110.3373465472868 -38.1428580866122, 110.3373465472868 -37.830211708853085, 109.17590079415747 -37.830211708853085, 109.17590079415747 -37.51756533109397, 108.01445504102813 -37.51756533109397, 108.01445504102813 -37.204918953334854, 106.8530092878988 -37.204918953334854, 106.8530092878988 -36.89227257557574, 104.82047921992246 -36.89227257557574, 104.82047921992246 -36.57962619781662, 101.33614196053446 -36.57962619781662, 101.33614196053446 -36.2669798200575, 97.85180470114645 -36.2669798200575, 97.85180470114645 -35.954333442298385, 90.01204586752344 -35.954333442298385, 90.01204586752344 -36.2669798200575, 87.68915436126477 -36.2669798200575, 87.68915436126477 -36.57962619781662, 85.65662429328843 -36.57962619781662, 85.65662429328843 -36.89227257557574, 84.20481710187677 -36.89227257557574, 84.20481710187677 -37.204918953334854, 76.07469682997143 -37.204918953334854, 76.07469682997143 -37.51756533109397, 72.59035957058342 -37.51756533109397))MULTILINESTRING ((179.15300742019988 -30.014052264875176, 179.15300742019988 -29.388759509356944, 179.44336885848222 -29.388759509356944, 179.44336885848222 -29.076113131597825, 179.15300742019988 -29.076113131597825, 179.15300742019988 -28.450820376079594, 178.86264598191755 -28.450820376079594, 178.86264598191755 -28.138173998320475, 178.57228454363522 -28.138173998320475, 178.57228454363522 -27.82552762056136, 177.99156166707056 -27.82552762056136, 177.99156166707056 -27.512881242802244, 177.12047735222356 -27.512881242802244, 177.12047735222356 -27.20023486504313, 175.9590315990942 -27.20023486504313, 175.9590315990942 -26.887588487284013, 172.1843329014239 -26.887588487284013, 172.1843329014239 -27.20023486504313, 170.15180283344753 -27.20023486504313, 170.15180283344753 -27.512881242802244, 168.1192727654712 -27.512881242802244, 168.1192727654712 -27.82552762056136, 166.08674269749486 -27.82552762056136, 166.08674269749486 -28.138173998320475, 164.34457406780086 -28.138173998320475, 164.34457406780086 -28.450820376079594, 162.31204399982454 -28.450820376079594, 162.31204399982454 -28.76346675383871, 159.98915249356585 -28.76346675383871, 159.98915249356585 -29.076113131597825, 158.24698386387186 -29.076113131597825, 158.24698386387186 -29.388759509356944, 157.08553811074253 -29.388759509356944, 157.08553811074253 -29.70140588711606, 155.92409235761318 -29.70140588711606, 155.92409235761318 -30.014052264875176, 155.3433694810485 -30.014052264875176, 155.3433694810485 -30.951991398152526, 155.92409235761318 -30.951991398152526, 155.92409235761318 -31.26463777591164, 156.7951766724602 -31.26463777591164, 156.7951766724602 -31.577284153670757, 158.24698386387186 -31.577284153670757, 158.24698386387186 -31.889930531429876, 159.98915249356585 -31.889930531429876, 159.98915249356585 -32.20257690918899, 162.0216825615422 -32.20257690918899, 162.0216825615422 -32.51522328694811, 166.08674269749486 -32.51522328694811, 166.08674269749486 -32.82786966470722, 171.02288714829453 -32.82786966470722, 171.02288714829453 -33.14051604246634, 174.79758584596487 -33.14051604246634, 174.79758584596487 -32.82786966470722, 175.37830872252954 -32.82786966470722, 175.37830872252954 -32.51522328694811, 175.9590315990942 -32.51522328694811, 175.9590315990942 -32.20257690918899, 176.24939303737654 -32.20257690918899, 176.24939303737654 -31.889930531429876, 176.8301159139412 -31.889930531429876, 176.8301159139412 -31.577284153670757, 177.4108387905059 -31.577284153670757, 177.4108387905059 -31.26463777591164, 177.70120022878822 -31.26463777591164, 177.70120022878822 -30.951991398152526, 178.2819231053529 -30.951991398152526, 178.2819231053529 -30.639345020393407, 178.57228454363522 -30.639345020393407, 178.57228454363522 -30.32669864263429, 178.86264598191755 -30.32669864263429, 178.86264598191755 -30.014052264875176, 179.15300742019988 -30.014052264875176), + (297.3301128011097 -9.69203771053261, 297.03975136282736 -9.69203771053261, 297.03975136282736 -10.004684088291725, 296.749389924545 -10.004684088291725, 296.749389924545 -10.31733046605084, 296.4590284862627 -10.31733046605084, 296.4590284862627 -10.629976843809958, 296.16866704798036 -10.629976843809958, 296.16866704798036 -10.942623221569075, 295.5879441714157 -10.942623221569075, 295.5879441714157 -11.25526959932819, 295.29758273313337 -11.25526959932819, 295.29758273313337 -11.567915977087306, 294.7168598565687 -11.567915977087306, 294.7168598565687 -11.880562354846424, 294.42649841828637 -11.880562354846424, 294.42649841828637 -12.193208732605541, 293.8457755417217 -12.193208732605541, 293.8457755417217 -12.505855110364656, 293.26505266515704 -12.505855110364656, 293.26505266515704 -12.818501488123772, 292.6843297885924 -12.818501488123772, 292.6843297885924 -13.13114786588289, 292.39396835031005 -13.13114786588289, 292.39396835031005 -13.443794243642007, 291.8132454737453 -13.443794243642007, 291.8132454737453 -13.756440621401122, 291.23252259718066 -13.756440621401122, 291.23252259718066 -14.069086999160238, 290.651799720616 -14.069086999160238, 290.651799720616 -14.381733376919355, 290.07107684405133 -14.381733376919355, 290.07107684405133 -14.694379754678472, 289.49035396748667 -14.694379754678472, 289.49035396748667 -15.007026132437588, 288.909631090922 -15.007026132437588, 288.909631090922 -15.319672510196703, 288.32890821435734 -15.319672510196703, 288.32890821435734 -15.63231888795582, 287.7481853377927 -15.63231888795582, 287.7481853377927 -15.944965265714938, 286.8771010229457 -15.944965265714938, 286.8771010229457 -16.257611643474053, 286.0060167080987 -16.257611643474053, 286.0060167080987 -16.57025802123317, 285.425293831534 -16.57025802123317, 285.425293831534 -16.882904398992288, 284.554209516687 -16.882904398992288, 284.554209516687 -17.195550776751404, 283.97348664012236 -17.195550776751404, 283.97348664012236 -17.50819715451052, 283.10240232527536 -17.50819715451052, 283.10240232527536 -17.820843532269635, 282.5216794487107 -17.820843532269635, 282.5216794487107 -18.13348991002875, 281.65059513386365 -18.13348991002875, 281.65059513386365 -18.44613628778787, 281.069872257299 -18.44613628778787, 281.069872257299 -18.758782665546985, 280.4891493807343 -18.758782665546985, 280.4891493807343 -19.0714290433061, 279.6180650658873 -19.0714290433061, 279.6180650658873 -19.38407542106522, 279.03734218932266 -19.38407542106522, 279.03734218932266 -19.696721798824335, 278.456619312758 -19.696721798824335, 278.456619312758 -20.00936817658345, 277.585534997911 -20.00936817658345, 277.585534997911 -20.322014554342566, 277.00481212134633 -20.322014554342566, 277.00481212134633 -20.63466093210168, 276.42408924478167 -20.63466093210168, 276.42408924478167 -20.9473073098608, 274.97228205337 -20.9473073098608, 274.97228205337 -21.259953687619916, 273.8108363002407 -21.259953687619916, 273.8108363002407 -21.57260006537903, 272.359029108829 -21.57260006537903, 272.359029108829 -21.88524644313815, 271.19758335569963 -21.88524644313815, 271.19758335569963 -22.197892820897266, 270.0361376025703 -22.197892820897266, 270.0361376025703 -22.51053919865638, 269.1650532877233 -22.51053919865638, 269.1650532877233 -22.823185576415497, 268.003607534594 -22.823185576415497, 268.003607534594 -23.135831954174613, 267.132523219747 -23.135831954174613, 267.132523219747 -23.44847833193373, 266.2614389049 -23.44847833193373, 266.2614389049 -23.761124709692847, 265.390354590053 -23.761124709692847, 265.390354590053 -24.073771087451963, 263.06746308379434 -24.073771087451963, 263.06746308379434 -24.386417465211082, 260.7445715775356 -24.386417465211082, 260.7445715775356 -24.699063842970197, 258.42168007127697 -24.699063842970197, 258.42168007127697 -25.011710220729313, 256.679511441583 -25.011710220729313, 256.679511441583 -25.32435659848843, 255.2277042501713 -25.32435659848843, 255.2277042501713 -25.637002976247544, 253.19517418219496 -25.637002976247544, 253.19517418219496 -25.949649354006663, 245.93613822513663 -25.949649354006663, 245.93613822513663 -26.26229573176578, 242.16143952746629 -26.26229573176578, 242.16143952746629 -26.574942109524894, 241.2903552126193 -26.574942109524894, 241.2903552126193 -26.887588487284013, 240.4192708977723 -26.887588487284013, 240.4192708977723 -27.20023486504313, 239.5481865829253 -27.20023486504313, 239.5481865829253 -27.512881242802244, 238.6771022680783 -27.512881242802244, 238.6771022680783 -27.82552762056136, 237.80601795323128 -27.82552762056136, 237.80601795323128 -28.138173998320475, 237.2252950766666 -28.138173998320475, 237.2252950766666 -28.450820376079594, 236.35421076181962 -28.450820376079594, 236.35421076181962 -28.76346675383871, 235.77348788525495 -28.76346675383871, 235.77348788525495 -29.076113131597825, 235.1927650086903 -29.076113131597825, 235.1927650086903 -29.388759509356944, 234.61204213212562 -29.388759509356944, 234.61204213212562 -29.70140588711606, 234.3216806938433 -29.70140588711606, 234.3216806938433 -30.014052264875176, 233.74095781727863 -30.014052264875176, 233.74095781727863 -30.32669864263429, 233.4505963789963 -30.32669864263429, 233.4505963789963 -30.639345020393407, 233.16023494071393 -30.639345020393407, 233.16023494071393 -30.951991398152526, 232.8698735024316 -30.951991398152526, 232.8698735024316 -31.26463777591164, 232.57951206414927 -31.26463777591164, 232.57951206414927 -31.577284153670757, 232.28915062586694 -31.577284153670757, 232.28915062586694 -33.14051604246634, 232.57951206414927 -33.14051604246634, 232.57951206414927 -33.765808797984576, 232.8698735024316 -33.765808797984576, 232.8698735024316 -34.07845517574369, 233.16023494071393 -34.07845517574369, 233.16023494071393 -34.39110155350281, 233.4505963789963 -34.39110155350281, 233.4505963789963 -34.70374793126192, 234.03131925556096 -34.70374793126192, 234.03131925556096 -35.01639430902104, 234.61204213212562 -35.01639430902104, 234.61204213212562 -35.329040686780154, 234.90240357040796 -35.329040686780154, 234.90240357040796 -35.64168706453927, 235.77348788525495 -35.64168706453927, 235.77348788525495 -35.954333442298385, 236.35421076181962 -35.954333442298385, 236.35421076181962 -36.2669798200575, 236.93493363838428 -36.2669798200575, 236.93493363838428 -36.57962619781662, 237.80601795323128 -36.57962619781662, 237.80601795323128 -36.89227257557574, 238.6771022680783 -36.89227257557574, 238.6771022680783 -37.204918953334854, 239.5481865829253 -37.204918953334854, 239.5481865829253 -37.51756533109397, 240.4192708977723 -37.51756533109397, 240.4192708977723 -37.830211708853085, 241.58071665090162 -37.830211708853085, 241.58071665090162 -38.1428580866122, 243.03252384231328 -38.1428580866122, 243.03252384231328 -38.455504464371316, 254.64698137360665 -38.455504464371316, 254.64698137360665 -38.76815084213044, 256.0987885650183 -38.76815084213044, 256.0987885650183 -39.080797219889554, 258.13131863299463 -39.080797219889554, 258.13131863299463 -39.39344359764867, 260.4542101392533 -39.39344359764867, 260.4542101392533 -39.706089975407785, 262.777101645512 -39.706089975407785, 262.777101645512 -40.0187363531669, 265.09999315177066 -40.0187363531669, 265.09999315177066 -40.331382730926016, 265.6807160283353 -40.331382730926016, 265.6807160283353 -40.64402910868513, 266.5518003431823 -40.64402910868513, 266.5518003431823 -40.95667548644425, 267.132523219747 -40.95667548644425, 267.132523219747 -41.26932186420336, 267.71324609631165 -41.26932186420336, 267.71324609631165 -41.581968241962485, 268.58433041115865 -41.581968241962485, 268.58433041115865 -41.8946146197216, 269.1650532877233 -41.8946146197216, 269.1650532877233 -42.20726099748072, 269.745776164288 -42.20726099748072, 269.745776164288 -42.51990737523983, 270.61686047913497 -42.51990737523983, 270.61686047913497 -42.83255375299895, 271.19758335569963 -42.83255375299895, 271.19758335569963 -43.14520013075806, 271.77830623226436 -43.14520013075806, 271.77830623226436 -43.45784650851718, 272.64939054711135 -43.45784650851718, 272.64939054711135 -43.7704928862763, 273.230113423676 -43.7704928862763, 273.230113423676 -44.08313926403542, 274.101197738523 -44.08313926403542, 274.101197738523 -44.39578564179453, 274.6819206150877 -44.39578564179453, 274.6819206150877 -44.70843201955365, 275.26264349165234 -44.70843201955365, 275.26264349165234 -45.02107839731276, 276.13372780649934 -45.02107839731276, 276.13372780649934 -45.33372477507188, 280.4891493807343 -45.33372477507188, 280.4891493807343 -45.646371152830994, 283.10240232527536 -45.646371152830994, 283.10240232527536 -45.95901753059011, 285.71565526981635 -45.95901753059011, 285.71565526981635 -46.271663908349225, 288.32890821435734 -46.271663908349225, 288.32890821435734 -45.95901753059011, 288.909631090922 -45.95901753059011, 288.909631090922 -45.646371152830994, 289.49035396748667 -45.646371152830994, 289.49035396748667 -45.33372477507188, 290.07107684405133 -45.33372477507188, 290.07107684405133 -45.02107839731276, 290.651799720616 -45.02107839731276, 290.651799720616 -44.70843201955365, 291.23252259718066 -44.70843201955365, 291.23252259718066 -44.39578564179453, 292.10360691202766 -44.39578564179453, 292.10360691202766 -44.08313926403542, 292.6843297885924 -44.08313926403542, 292.6843297885924 -43.7704928862763, 293.5554141034394 -43.7704928862763, 293.5554141034394 -43.45784650851718, 294.13613698000404 -43.45784650851718, 294.13613698000404 -43.14520013075806, 295.00722129485104 -43.14520013075806, 295.00722129485104 -42.83255375299895, 295.5879441714157 -42.83255375299895, 295.5879441714157 -42.51990737523983, 296.4590284862627 -42.51990737523983, 296.4590284862627 -42.20726099748072, 297.3301128011097 -42.20726099748072))MULTILINESTRING ((297.3301128011097 -109.73887859344985, 296.4590284862627 -109.73887859344985, 296.4590284862627 -109.42623221569075, 295.29758273313337 -109.42623221569075, 295.29758273313337 -109.11358583793162, 294.13613698000404 -109.11358583793162, 294.13613698000404 -108.80093946017251, 292.6843297885924 -108.80093946017251, 292.6843297885924 -108.48829308241339, 291.23252259718066 -108.48829308241339, 291.23252259718066 -108.17564670465428, 289.780715405769 -108.17564670465428, 289.780715405769 -107.86300032689516, 288.038546776075 -107.86300032689516, 288.038546776075 -107.55035394913605, 287.45782389951034 -107.55035394913605, 287.45782389951034 -107.86300032689516, 286.8771010229457 -107.86300032689516, 286.8771010229457 -108.17564670465428, 286.0060167080987 -108.17564670465428, 286.0060167080987 -108.48829308241339, 285.1349323932517 -108.48829308241339, 285.1349323932517 -108.80093946017251, 284.554209516687 -108.80093946017251, 284.554209516687 -109.11358583793162, 283.97348664012236 -109.11358583793162, 283.97348664012236 -109.42623221569075, 283.10240232527536 -109.42623221569075, 283.10240232527536 -109.73887859344985, 282.5216794487107 -109.73887859344985, 282.5216794487107 -110.05152497120898, 281.940956572146 -110.05152497120898, 281.940956572146 -110.3641713489681, 281.3602336955813 -110.3641713489681, 281.3602336955813 -110.67681772672721, 280.77951081901665 -110.67681772672721, 280.77951081901665 -110.98946410448633, 279.90842650416965 -110.98946410448633, 279.90842650416965 -111.30211048224544, 279.327703627605 -111.30211048224544, 279.327703627605 -111.61475686000456, 278.7469807510403 -111.61475686000456, 278.7469807510403 -111.92740323776367, 278.16625787447566 -111.92740323776367, 278.16625787447566 -112.24004961552279, 277.585534997911 -112.24004961552279, 277.585534997911 -112.5526959932819, 276.714450683064 -112.5526959932819, 276.714450683064 -112.86534237104102, 274.97228205337 -112.86534237104102, 274.97228205337 -112.5526959932819, 272.64939054711135 -112.5526959932819, 272.64939054711135 -112.24004961552279, 270.0361376025703 -112.24004961552279, 270.0361376025703 -111.92740323776367, 265.97107746661766 -111.92740323776367, 265.97107746661766 -111.61475686000456, 263.648185960359 -111.61475686000456, 263.648185960359 -111.30211048224544, 262.19637876894734 -111.30211048224544, 262.19637876894734 -110.98946410448633, 261.03493301581796 -110.98946410448633, 261.03493301581796 -110.67681772672721, 259.8734872626886 -110.67681772672721, 259.8734872626886 -110.3641713489681, 259.00240294784163 -110.3641713489681, 259.00240294784163 -110.05152497120898, 258.13131863299463 -110.05152497120898, 258.13131863299463 -109.73887859344985, 257.26023431814764 -109.73887859344985, 257.26023431814764 -109.42623221569075, 256.38915000330064 -109.42623221569075, 256.38915000330064 -109.11358583793162, 255.51806568845365 -109.11358583793162, 255.51806568845365 -108.80093946017251, 254.93734281188898 -108.80093946017251, 254.93734281188898 -108.48829308241339, 254.06625849704199 -108.48829308241339, 254.06625849704199 -108.17564670465428, 253.77589705875965 -108.17564670465428, 253.77589705875965 -108.48829308241339, 253.4855356204773 -108.48829308241339, 253.4855356204773 -109.73887859344985, 253.19517418219496 -109.73887859344985, 253.19517418219496 -111.30211048224544, 252.90481274391263 -111.30211048224544, 252.90481274391263 -112.86534237104102, 252.6144513056303 -112.86534237104102, 252.6144513056303 -115.05386701535484, 252.32408986734796 -115.05386701535484, 252.32408986734796 -117.86768441518689, 252.03372842906563 -117.86768441518689, 252.03372842906563 -122.24473370381452, 251.7433669907833 -122.24473370381452, 251.7433669907833 -131.93677141434713), + (234.61204213212562 -116.61709890415042, 234.61204213212562 -114.74122063759572, 234.3216806938433 -114.74122063759572, 234.3216806938433 -112.5526959932819, 234.03131925556096 -112.5526959932819, 234.03131925556096 -110.67681772672721, 233.74095781727863 -110.67681772672721, 233.74095781727863 -109.42623221569075, 233.4505963789963 -109.42623221569075, 233.4505963789963 -108.17564670465428, 233.16023494071393 -108.17564670465428, 233.16023494071393 -107.23770757137693, 232.8698735024316 -107.23770757137693, 232.8698735024316 -106.29976843809958, 232.57951206414927 -106.29976843809958, 232.57951206414927 -105.36182930482224, 232.28915062586694 -105.36182930482224, 232.28915062586694 -104.42389017154488, 231.9987891875846 -104.42389017154488, 231.9987891875846 -103.79859741602665, 231.70842774930227 -103.79859741602665, 231.70842774930227 -103.17330466050842, 231.41806631101994 -103.17330466050842, 231.41806631101994 -102.54801190499018, 231.1277048727376 -102.54801190499018, 231.1277048727376 -102.23536552723107, 230.54698199617295 -102.23536552723107, 230.54698199617295 -101.92271914947194, 229.96625911960828 -101.92271914947194, 229.96625911960828 -101.61007277171284, 229.09517480476129 -101.61007277171284, 229.09517480476129 -101.29742639395371, 228.51445192819662 -101.29742639395371, 228.51445192819662 -100.9847800161946, 227.93372905163193 -100.9847800161946, 227.93372905163193 -100.67213363843548, 227.06264473678493 -100.67213363843548, 227.06264473678493 -100.35948726067637, 226.48192186022027 -100.35948726067637, 226.48192186022027 -100.04684088291725, 225.61083754537327 -100.04684088291725, 225.61083754537327 -99.73419450515813, 225.0301146688086 -99.73419450515813, 225.0301146688086 -99.42154812739902, 224.1590303539616 -99.42154812739902, 224.1590303539616 -99.1089017496399, 223.28794603911462 -99.1089017496399, 223.28794603911462 -98.79625537188079, 222.4168617242676 -98.79625537188079, 222.4168617242676 -98.48360899412167, 221.83613884770293 -98.48360899412167, 221.83613884770293 -98.17096261636256, 220.96505453285593 -98.17096261636256, 220.96505453285593 -97.85831623860344, 219.8036087797266 -97.85831623860344, 219.8036087797266 -97.54566986084433, 219.51324734144427 -97.54566986084433))MULTILINESTRING ((189.6060191983639 -91.91803506118022, 185.54095906241122 -91.91803506118022, 185.54095906241122 -91.60538868342111, 183.5084289944349 -91.60538868342111, 183.5084289944349 -91.29274230566199, 182.05662180302323 -91.29274230566199, 182.05662180302323 -91.60538868342111, 180.02409173504688 -91.60538868342111, 180.02409173504688 -91.91803506118022, 178.86264598191755 -91.91803506118022, 178.86264598191755 -92.23068143893934, 177.99156166707056 -92.23068143893934, 177.99156166707056 -92.54332781669845, 177.70120022878822 -92.54332781669845, 177.70120022878822 -92.85597419445757, 177.12047735222356 -92.85597419445757, 177.12047735222356 -93.1686205722167, 176.53975447565887 -93.1686205722167, 176.53975447565887 -93.4812669499758, 175.9590315990942 -93.4812669499758, 175.9590315990942 -93.79391332773493, 175.37830872252954 -93.79391332773493, 175.37830872252954 -94.10655970549404, 175.0879472842472 -94.10655970549404, 175.0879472842472 -94.41920608325316, 174.50722440768254 -94.41920608325316, 174.50722440768254 -94.73185246101227, 173.63614009283555 -94.73185246101227, 173.63614009283555 -95.04449883877139, 172.76505577798855 -95.04449883877139, 172.76505577798855 -95.35714521653051, 171.89397146314155 -95.35714521653051, 171.89397146314155 -95.66979159428962, 171.02288714829453 -95.66979159428962, 171.02288714829453 -95.98243797204874, 169.8614413951652 -95.98243797204874, 169.8614413951652 -96.29508434980785, 168.9903570803182 -96.29508434980785, 168.9903570803182 -96.60773072756697, 168.1192727654712 -96.60773072756697, 168.1192727654712 -96.92037710532608, 167.2481884506242 -96.92037710532608, 167.2481884506242 -97.2330234830852, 166.08674269749486 -97.2330234830852, 166.08674269749486 -97.54566986084433, 165.21565838264786 -97.54566986084433, 165.21565838264786 -97.85831623860344, 164.34457406780086 -97.85831623860344, 164.34457406780086 -98.17096261636256, 163.18312831467154 -98.17096261636256, 163.18312831467154 -98.48360899412167, 162.31204399982454 -98.48360899412167, 162.31204399982454 -98.79625537188079, 161.4409596849775 -98.79625537188079, 161.4409596849775 -99.1089017496399, 160.56987537013052 -99.1089017496399, 160.56987537013052 -99.42154812739902, 159.69879105528352 -99.42154812739902, 159.69879105528352 -99.73419450515813, 158.82770674043653 -99.73419450515813, 158.82770674043653 -100.04684088291725, 157.95662242558953 -100.04684088291725, 157.95662242558953 -100.35948726067637, 157.08553811074253 -100.35948726067637, 157.08553811074253 -100.67213363843548, 156.2144537958955 -100.67213363843548, 156.2144537958955 -100.9847800161946, 155.05300804276618 -100.9847800161946, 155.05300804276618 -101.29742639395371, 154.18192372791918 -101.29742639395371, 154.18192372791918 -101.61007277171284, 153.02047797478986 -101.61007277171284, 153.02047797478986 -101.92271914947194, 152.14939365994286 -101.92271914947194, 152.14939365994286 -102.23536552723107, 151.27830934509586 -102.23536552723107, 151.27830934509586 -102.54801190499018, 150.69758646853117 -102.54801190499018, 150.69758646853117 -102.8606582827493, 150.1168635919665 -102.8606582827493, 150.1168635919665 -103.17330466050842, 149.53614071540184 -103.17330466050842, 149.53614071540184 -103.48595103826753, 148.95541783883718 -103.48595103826753, 148.95541783883718 -103.79859741602665, 148.3746949622725 -103.79859741602665, 148.3746949622725 -104.11124379378576, 147.50361064742552 -104.11124379378576, 147.50361064742552 -104.42389017154488, 146.92288777086085 -104.42389017154488, 146.92288777086085 -104.73653654930399, 146.3421648942962 -104.73653654930399, 146.3421648942962 -105.04918292706311, 145.7614420177315 -105.04918292706311, 145.7614420177315 -105.36182930482224, 145.18071914116683 -105.36182930482224, 145.18071914116683 -105.67447568258135, 144.59999626460217 -105.67447568258135, 144.59999626460217 -105.98712206034047, 144.0192733880375 -105.98712206034047, 144.0192733880375 -106.29976843809958, 143.43855051147284 -106.29976843809958, 143.43855051147284 -106.6124148158587, 142.85782763490818 -106.6124148158587, 142.85782763490818 -106.92506119361781, 142.2771047583435 -106.92506119361781, 142.2771047583435 -107.23770757137693, 141.69638188177885 -107.23770757137693, 141.69638188177885 -107.55035394913605, 141.11565900521418 -107.55035394913605, 141.11565900521418 -107.86300032689516, 140.5349361286495 -107.86300032689516, 140.5349361286495 -108.17564670465428, 139.95421325208483 -108.17564670465428, 139.95421325208483 -108.48829308241339, 139.6638518138025 -108.48829308241339, 139.6638518138025 -108.80093946017251, 139.08312893723783 -108.80093946017251, 139.08312893723783 -109.11358583793162, 138.7927674989555 -109.11358583793162, 138.7927674989555 -109.42623221569075, 138.21204462239083 -109.42623221569075, 138.21204462239083 -109.73887859344985, 137.9216831841085 -109.73887859344985, 137.9216831841085 -110.05152497120898, 137.34096030754384 -110.05152497120898, 137.34096030754384 -110.3641713489681, 137.0505988692615 -110.3641713489681, 137.0505988692615 -110.67681772672721, 136.76023743097917 -110.67681772672721, 136.76023743097917 -110.98946410448633, 136.1795145544145 -110.98946410448633, 136.1795145544145 -111.30211048224544, 135.88915311613218 -111.30211048224544, 135.88915311613218 -111.61475686000456, 135.59879167784982 -111.61475686000456, 135.59879167784982 -111.92740323776367, 135.01806880128515 -111.92740323776367, 135.01806880128515 -112.24004961552279, 134.72770736300282 -112.24004961552279, 134.72770736300282 -112.5526959932819, 134.4373459247205 -112.5526959932819, 134.4373459247205 -112.86534237104102, 134.14698448643816 -112.86534237104102, 134.14698448643816 -113.17798874880015, 133.85662304815583 -113.17798874880015, 133.85662304815583 -113.49063512655925, 133.5662616098735 -113.49063512655925, 133.5662616098735 -113.80328150431838, 133.27590017159116 -113.80328150431838, 133.27590017159116 -114.11592788207749, 132.98553873330883 -114.11592788207749, 132.98553873330883 -114.42857425983661, 132.6951772950265 -114.42857425983661, 132.6951772950265 -114.74122063759572, 132.40481585674416 -114.74122063759572, 132.40481585674416 -115.05386701535484, 132.11445441846183 -115.05386701535484, 132.11445441846183 -115.36651339311396, 131.8240929801795 -115.36651339311396, 131.8240929801795 -115.67915977087307, 131.53373154189717 -115.67915977087307, 131.53373154189717 -115.9918061486322, 131.24337010361484 -115.9918061486322, 131.24337010361484 -116.3044525263913, 130.9530086653325 -116.3044525263913, 130.9530086653325 -116.92974528190953, 130.66264722705014 -116.92974528190953, 130.66264722705014 -117.24239165966866, 130.3722857887678 -117.24239165966866, 130.3722857887678 -117.55503803742778, 130.08192435048548 -117.55503803742778, 130.08192435048548 -118.18033079294601, 129.79156291220315 -118.18033079294601, 129.79156291220315 -118.49297717070512, 129.50120147392082 -118.49297717070512, 129.50120147392082 -119.11826992622335, 129.21084003563848 -119.11826992622335, 129.21084003563848 -119.43091630398247, 128.92047859735615 -119.43091630398247, 128.92047859735615 -120.0562090595007, 128.3397557207915 -120.0562090595007, 128.3397557207915 -120.36885543725982, 128.04939428250916 -120.36885543725982, 128.04939428250916 -120.68150181501893, 127.75903284422682 -120.68150181501893, 127.75903284422682 -120.99414819277806, 127.46867140594449 -120.99414819277806, 127.46867140594449 -121.30679457053716, 127.17830996766216 -121.30679457053716, 127.17830996766216 -121.61944094829629, 126.88794852937983 -121.61944094829629, 126.88794852937983 -121.9320873260554, 126.59758709109748 -121.9320873260554, 126.59758709109748 -122.24473370381452, 126.30722565281515 -122.24473370381452, 126.30722565281515 -122.55738008157363, 126.01686421453282 -122.55738008157363, 126.01686421453282 -122.87002645933275, 125.72650277625048 -122.87002645933275, 125.72650277625048 -123.18267283709187, 125.43614133796815 -123.18267283709187, 125.43614133796815 -123.8079655926101, 125.14577989968582 -123.8079655926101, 125.14577989968582 -124.12061197036921, 124.85541846140349 -124.12061197036921, 124.85541846140349 -124.74590472588744, 124.56505702312116 -124.74590472588744, 124.56505702312116 -125.05855110364656, 124.27469558483881 -125.05855110364656, 124.27469558483881 -125.6838438591648, 123.98433414655648 -125.6838438591648, 123.98433414655648 -126.30913661468303, 123.69397270827415 -126.30913661468303, 123.69397270827415 -127.24707574796038, 123.40361126999181 -127.24707574796038, 123.40361126999181 -128.18501488123772, 123.11324983170948 -128.18501488123772, 123.11324983170948 -129.12295401451507, 122.82288839342715 -129.12295401451507, 122.82288839342715 -130.68618590331067, 122.53252695514482 -130.68618590331067, 122.53252695514482 -133.1873569253836, 122.24216551686249 -133.1873569253836, 122.24216551686249 -139.1276381028068, 122.53252695514482 -139.1276381028068, 122.53252695514482 -142.56674825815708, 122.82288839342715 -142.56674825815708, 122.82288839342715 -145.06791928023, 123.11324983170948 -145.06791928023, 123.11324983170948 -147.25644392454382, 123.40361126999181 -147.25644392454382, 123.40361126999181 -149.44496856885763, 123.69397270827415 -149.44496856885763, 123.69397270827415 -151.32084683541234, 123.98433414655648 -151.32084683541234, 123.98433414655648 -152.88407872420794, 124.27469558483881 -152.88407872420794, 124.27469558483881 -154.75995699076262, 124.56505702312116 -154.75995699076262, 124.56505702312116 -156.32318887955822, 124.85541846140349 -156.32318887955822, 124.85541846140349 -158.1990671461129, 125.14577989968582 -158.1990671461129, 125.14577989968582 -159.7622990349085, 125.43614133796815 -159.7622990349085, 125.43614133796815 -161.32553092370406, 125.72650277625048 -161.32553092370406, 125.72650277625048 -163.51405556801788, 126.01686421453282 -163.51405556801788, 126.01686421453282 -165.7025802123317, 126.30722565281515 -165.7025802123317, 126.30722565281515 -167.5784584788864, 126.59758709109748 -167.5784584788864, 126.59758709109748 -168.20375123440462), + (297.3301128011097 -90.66744955014376, 297.03975136282736 -90.66744955014376, 297.03975136282736 -90.98009592790288, 295.5879441714157 -90.98009592790288, 295.5879441714157 -91.29274230566199, 293.8457755417217 -91.29274230566199, 293.8457755417217 -91.60538868342111, 292.39396835031005 -91.60538868342111, 292.39396835031005 -91.91803506118022, 290.651799720616 -91.91803506118022, 290.651799720616 -92.23068143893934, 288.6192696526397 -92.23068143893934, 288.6192696526397 -92.54332781669845, 286.8771010229457 -92.54332781669845, 286.8771010229457 -92.85597419445757, 285.425293831534 -92.85597419445757, 285.425293831534 -93.1686205722167, 284.2638480784047 -93.1686205722167, 284.2638480784047 -93.4812669499758, 282.81204088699303 -93.4812669499758, 282.81204088699303 -93.79391332773493, 281.65059513386365 -93.79391332773493, 281.65059513386365 -94.10655970549404, 280.198787942452 -94.10655970549404, 280.198787942452 -94.41920608325316, 279.327703627605 -94.41920608325316, 279.327703627605 -94.73185246101227, 278.16625787447566 -94.73185246101227, 278.16625787447566 -95.04449883877139, 277.00481212134633 -95.04449883877139, 277.00481212134633 -95.35714521653051, 275.5530049299347 -95.35714521653051, 275.5530049299347 -95.04449883877139, 274.39155917680534 -95.04449883877139, 274.39155917680534 -94.73185246101227, 273.230113423676 -94.73185246101227, 273.230113423676 -94.41920608325316, 272.0686676705467 -94.41920608325316, 272.0686676705467 -94.10655970549404, 270.61686047913497 -94.10655970549404, 270.61686047913497 -93.79391332773493, 269.45541472600564 -93.79391332773493, 269.45541472600564 -93.4812669499758, 268.003607534594 -93.4812669499758, 268.003607534594 -93.1686205722167, 266.5518003431823 -93.1686205722167, 266.5518003431823 -92.85597419445757, 264.80963171348833 -92.85597419445757, 264.80963171348833 -92.54332781669845, 263.93854739864133 -92.54332781669845, 263.93854739864133 -92.23068143893934, 263.06746308379434 -92.23068143893934, 263.06746308379434 -91.91803506118022, 261.906017330665 -91.91803506118022, 261.906017330665 -91.60538868342111, 261.03493301581796 -91.60538868342111, 261.03493301581796 -91.29274230566199, 260.16384870097096 -91.29274230566199, 260.16384870097096 -90.98009592790288, 259.29276438612396 -90.98009592790288, 259.29276438612396 -90.66744955014376, 258.42168007127697 -90.66744955014376, 258.42168007127697 -90.35480317238465, 257.26023431814764 -90.35480317238465, 257.26023431814764 -90.04215679462553, 256.38915000330064 -90.04215679462553, 256.38915000330064 -89.7295104168664, 255.51806568845365 -89.7295104168664, 255.51806568845365 -89.4168640391073, 254.64698137360665 -89.4168640391073, 254.64698137360665 -89.10421766134817, 253.19517418219496 -89.10421766134817, 253.19517418219496 -89.4168640391073, 252.90481274391263 -89.4168640391073, 252.90481274391263 -89.7295104168664, 252.6144513056303 -89.7295104168664, 252.6144513056303 -90.04215679462553, 252.32408986734796 -90.04215679462553, 252.32408986734796 -90.35480317238465, 251.7433669907833 -90.35480317238465, 251.7433669907833 -90.66744955014376, 251.45300555250097 -90.66744955014376, 251.45300555250097 -90.98009592790288, 251.16264411421864 -90.98009592790288, 251.16264411421864 -91.29274230566199, 250.8722826759363 -91.29274230566199, 250.8722826759363 -91.60538868342111, 250.29155979937164 -91.60538868342111, 250.29155979937164 -91.91803506118022, 250.0011983610893 -91.91803506118022, 250.0011983610893 -92.23068143893934, 249.71083692280698 -92.23068143893934, 249.71083692280698 -92.54332781669845, 249.1301140462423 -92.54332781669845, 249.1301140462423 -92.85597419445757, 248.83975260795998 -92.85597419445757, 248.83975260795998 -93.1686205722167, 248.2590297313953 -93.1686205722167, 248.2590297313953 -93.4812669499758, 247.67830685483062 -93.4812669499758, 247.67830685483062 -93.79391332773493, 247.3879454165483 -93.79391332773493, 247.3879454165483 -94.10655970549404, 246.80722253998363 -94.10655970549404, 246.80722253998363 -94.41920608325316, 245.93613822513663 -94.41920608325316, 245.93613822513663 -94.73185246101227, 244.7746924720073 -94.73185246101227, 244.7746924720073 -95.04449883877139, 242.74216240403095 -95.04449883877139, 242.74216240403095 -94.73185246101227, 242.16143952746629 -94.73185246101227, 242.16143952746629 -94.41920608325316, 241.87107808918395 -94.41920608325316, 241.87107808918395 -93.79391332773493, 241.58071665090162 -93.79391332773493, 241.58071665090162 -93.4812669499758, 241.2903552126193 -93.4812669499758, 241.2903552126193 -93.1686205722167, 240.99999377433696 -93.1686205722167, 240.99999377433696 -92.85597419445757, 240.70963233605463 -92.85597419445757, 240.70963233605463 -92.54332781669845, 240.4192708977723 -92.54332781669845, 240.4192708977723 -91.91803506118022, 240.12890945948996 -91.91803506118022, 240.12890945948996 -91.60538868342111, 239.83854802120763 -91.60538868342111, 239.83854802120763 -91.29274230566199, 239.5481865829253 -91.29274230566199, 239.5481865829253 -90.98009592790288, 239.25782514464296 -90.98009592790288, 239.25782514464296 -90.66744955014376, 238.96746370636063 -90.66744955014376, 238.96746370636063 -90.35480317238465, 238.6771022680783 -90.35480317238465, 238.6771022680783 -90.04215679462553, 238.0963793915136 -90.04215679462553, 238.0963793915136 -89.7295104168664, 237.80601795323128 -89.7295104168664, 237.80601795323128 -89.4168640391073, 237.51565651494894 -89.4168640391073, 237.51565651494894 -89.10421766134817, 237.2252950766666 -89.10421766134817, 237.2252950766666 -88.79157128358906, 236.93493363838428 -88.79157128358906, 236.93493363838428 -88.47892490582994, 236.35421076181962 -88.47892490582994, 236.35421076181962 -88.16627852807083, 236.06384932353728 -88.16627852807083, 236.06384932353728 -87.85363215031171, 235.77348788525495 -87.85363215031171, 235.77348788525495 -87.5409857725526, 235.1927650086903 -87.5409857725526, 235.1927650086903 -87.22833939479348, 234.90240357040796 -87.22833939479348, 234.90240357040796 -86.91569301703436, 234.3216806938433 -86.91569301703436, 234.3216806938433 -86.60304663927525, 233.74095781727863 -86.60304663927525, 233.74095781727863 -86.29040026151613, 233.4505963789963 -86.29040026151613, 233.4505963789963 -85.97775388375702, 232.8698735024316 -85.97775388375702, 232.8698735024316 -85.6651075059979, 232.28915062586694 -85.6651075059979, 232.28915062586694 -85.35246112823879, 231.70842774930227 -85.35246112823879, 231.70842774930227 -85.03981475047966, 230.83734343445528 -85.03981475047966, 230.83734343445528 -84.72716837272054, 229.67589768132595 -84.72716837272054, 229.67589768132595 -84.41452199496143, 228.51445192819662 -84.41452199496143, 228.51445192819662 -84.10187561720231, 227.35300617506726 -84.10187561720231, 227.35300617506726 -83.7892292394432, 226.19156042193794 -83.7892292394432, 226.19156042193794 -83.47658286168408, 224.73975323052628 -83.47658286168408, 224.73975323052628 -83.16393648392497, 223.57830747739695 -83.16393648392497, 223.57830747739695 -82.85129010616585, 222.12650028598526 -82.85129010616585, 222.12650028598526 -82.53864372840673, 220.6746930945736 -82.53864372840673, 220.6746930945736 -82.22599735064762, 219.51324734144427 -82.22599735064762, 219.51324734144427 -82.53864372840673, 219.22288590316194 -82.53864372840673, 219.22288590316194 -82.85129010616585, 218.9325244648796 -82.85129010616585, 218.9325244648796 -83.16393648392497, 218.64216302659727 -83.16393648392497, 218.64216302659727 -83.47658286168408, 218.35180158831494 -83.47658286168408, 218.35180158831494 -83.7892292394432, 218.0614401500326 -83.7892292394432, 218.0614401500326 -84.10187561720231, 217.77107871175025 -84.10187561720231, 217.77107871175025 -84.41452199496143, 217.48071727346792 -84.41452199496143, 217.48071727346792 -85.03981475047966, 217.19035583518558 -85.03981475047966, 217.19035583518558 -85.35246112823879))MULTILINESTRING ((106.56264784961647 -229.16979489743233, 106.56264784961647 -224.48009923104559, 106.27228641133412 -224.48009923104559, 106.27228641133412 -224.16745285328648, 105.98192497305179 -224.16745285328648, 105.98192497305179 -230.10773403070968), + (72.29999813230108 -86.91569301703436, 69.68674518776008 -86.91569301703436, 69.68674518776008 -86.60304663927525, 67.07349224321908 -86.60304663927525, 67.07349224321908 -86.29040026151613, 64.46023929867808 -86.29040026151613, 64.46023929867808 -85.97775388375702, 62.137347792419405 -85.97775388375702, 62.137347792419405 -85.6651075059979, 60.395179162725405 -85.6651075059979, 60.395179162725405 -85.35246112823879, 58.653010533031406 -85.35246112823879, 58.653010533031406 -85.03981475047966, 57.49156477990207 -85.03981475047966, 57.49156477990207 -84.72716837272054, 56.0397575884904 -84.72716837272054, 56.0397575884904 -84.41452199496143, 54.87831183536107 -84.41452199496143, 54.87831183536107 -84.10187561720231, 53.71686608223173 -84.10187561720231, 53.71686608223173 -83.7892292394432, 52.84578176738473 -83.7892292394432, 52.84578176738473 -83.47658286168408, 51.68433601425539 -83.47658286168408, 51.68433601425539 -83.16393648392497, 50.8132516994084 -83.16393648392497, 50.8132516994084 -82.85129010616585, 49.942167384561394 -82.85129010616585, 49.942167384561394 -82.53864372840673, 48.78072163143206 -82.53864372840673, 48.78072163143206 -82.22599735064762, 47.61927587830272 -82.22599735064762, 47.61927587830272 -81.9133509728885, 46.45783012517339 -81.9133509728885, 46.45783012517339 -81.60070459512939, 45.29638437204405 -81.60070459512939, 45.29638437204405 -81.28805821737026, 44.13493861891472 -81.28805821737026, 44.13493861891472 -80.97541183961116, 42.97349286578539 -80.97541183961116, 42.97349286578539 -80.66276546185203, 42.102408550938385 -80.66276546185203, 42.102408550938385 -80.35011908409292, 40.94096279780905 -80.35011908409292, 40.94096279780905 -80.0374727063338, 40.06987848296205 -80.0374727063338, 40.06987848296205 -79.72482632857468, 38.90843272983271 -79.72482632857468, 38.90843272983271 -79.41217995081557, 37.746986976703376 -79.41217995081557, 37.746986976703376 -79.09953357305645, 35.714456908727044 -79.09953357305645, 35.714456908727044 -78.78688719529734, 33.39156540246837 -78.78688719529734, 33.39156540246837 -78.47424081753822, 30.77831245792737 -78.47424081753822, 30.77831245792737 -78.16159443977911, 25.551806568845365 -78.16159443977911, 25.551806568845365 -78.47424081753822, 24.39036081571603 -78.47424081753822, 24.39036081571603 -78.78688719529734, 23.228915062586694 -78.78688719529734, 23.228915062586694 -79.09953357305645, 22.357830747739694 -79.09953357305645, 22.357830747739694 -79.41217995081557, 21.486746432892694 -79.41217995081557, 21.486746432892694 -79.72482632857468, 20.61566211804569 -79.72482632857468, 20.61566211804569 -80.0374727063338, 19.74457780319869 -80.0374727063338), + (297.3301128011097 -80.66276546185203, 296.4590284862627 -80.66276546185203, 296.4590284862627 -80.97541183961116, 295.5879441714157 -80.97541183961116, 295.5879441714157 -81.28805821737026, 294.42649841828637 -81.28805821737026, 294.42649841828637 -81.60070459512939, 293.26505266515704 -81.60070459512939, 293.26505266515704 -81.9133509728885, 292.10360691202766 -81.9133509728885, 292.10360691202766 -82.22599735064762, 290.94216115889833 -82.22599735064762, 290.94216115889833 -82.53864372840673, 290.07107684405133 -82.53864372840673, 290.07107684405133 -82.85129010616585, 288.909631090922 -82.85129010616585, 288.909631090922 -83.16393648392497, 287.45782389951034 -83.16393648392497, 287.45782389951034 -83.47658286168408, 284.84457095496936 -83.47658286168408, 284.84457095496936 -83.7892292394432, 282.5216794487107 -83.7892292394432, 282.5216794487107 -84.10187561720231, 280.4891493807343 -84.10187561720231, 280.4891493807343 -84.41452199496143, 278.7469807510403 -84.41452199496143, 278.7469807510403 -84.72716837272054, 277.00481212134633 -84.72716837272054, 277.00481212134633 -85.03981475047966, 275.843366368217 -85.03981475047966, 275.843366368217 -84.72716837272054, 274.6819206150877 -84.72716837272054, 274.6819206150877 -84.41452199496143, 273.52047486195835 -84.41452199496143, 273.52047486195835 -84.10187561720231, 272.359029108829 -84.10187561720231, 272.359029108829 -83.7892292394432, 270.9072219174173 -83.7892292394432, 270.9072219174173 -83.47658286168408, 269.45541472600564 -83.47658286168408, 269.45541472600564 -83.16393648392497, 268.003607534594 -83.16393648392497, 268.003607534594 -82.85129010616585, 266.5518003431823 -82.85129010616585, 266.5518003431823 -82.53864372840673, 265.09999315177066 -82.53864372840673, 265.09999315177066 -82.22599735064762, 263.93854739864133 -82.22599735064762, 263.93854739864133 -81.9133509728885, 262.777101645512 -81.9133509728885, 262.777101645512 -81.60070459512939, 261.6156558923827 -81.60070459512939, 261.6156558923827 -81.28805821737026, 260.4542101392533 -81.28805821737026, 260.4542101392533 -80.97541183961116, 259.29276438612396 -80.97541183961116, 259.29276438612396 -80.66276546185203, 258.13131863299463 -80.66276546185203, 258.13131863299463 -80.35011908409292, 256.9698728798653 -80.35011908409292, 256.9698728798653 -80.0374727063338, 255.80842712673598 -80.0374727063338, 255.80842712673598 -79.72482632857468, 254.64698137360665 -79.72482632857468, 254.64698137360665 -79.41217995081557, 252.6144513056303 -79.41217995081557, 252.6144513056303 -79.72482632857468, 251.45300555250097 -79.72482632857468, 251.45300555250097 -80.0374727063338, 250.0011983610893 -80.0374727063338, 250.0011983610893 -80.35011908409292, 247.67830685483062 -80.35011908409292, 247.67830685483062 -80.66276546185203, 244.7746924720073 -80.66276546185203, 244.7746924720073 -80.35011908409292, 242.45180096574862 -80.35011908409292, 242.45180096574862 -80.0374727063338, 241.87107808918395 -80.0374727063338, 241.87107808918395 -79.72482632857468, 241.2903552126193 -79.72482632857468, 241.2903552126193 -79.41217995081557, 240.4192708977723 -79.41217995081557, 240.4192708977723 -79.09953357305645, 239.83854802120763 -79.09953357305645, 239.83854802120763 -78.78688719529734, 238.96746370636063 -78.78688719529734, 238.96746370636063 -78.47424081753822, 238.0963793915136 -78.47424081753822, 238.0963793915136 -78.16159443977911, 237.2252950766666 -78.16159443977911, 237.2252950766666 -77.84894806201999, 236.35421076181962 -77.84894806201999, 236.35421076181962 -77.53630168426088, 235.48312644697262 -77.53630168426088, 235.48312644697262 -77.22365530650175, 234.3216806938433 -77.22365530650175, 234.3216806938433 -76.91100892874263, 233.16023494071393 -76.91100892874263, 233.16023494071393 -76.59836255098352, 231.9987891875846 -76.59836255098352, 231.9987891875846 -76.2857161732244, 230.54698199617295 -76.2857161732244, 230.54698199617295 -75.97306979546529, 229.38553624304362 -75.97306979546529, 229.38553624304362 -75.66042341770617, 227.93372905163193 -75.66042341770617, 227.93372905163193 -75.34777703994706, 226.48192186022027 -75.34777703994706, 226.48192186022027 -75.03513066218794, 225.0301146688086 -75.03513066218794, 225.0301146688086 -74.72248428442882, 223.57830747739695 -74.72248428442882, 223.57830747739695 -74.40983790666971, 221.83613884770293 -74.40983790666971, 221.83613884770293 -74.09719152891059, 220.09397021800893 -74.09719152891059, 220.09397021800893 -73.78454515115148, 217.48071727346792 -73.78454515115148, 217.48071727346792 -74.09719152891059, 211.67348850782125 -74.09719152891059, 211.67348850782125 -74.40983790666971, 204.99517542732758 -74.40983790666971, 204.99517542732758 -74.72248428442882, 198.60722378511625 -74.72248428442882, 198.60722378511625 -74.40983790666971, 196.86505515542223 -74.40983790666971, 196.86505515542223 -74.72248428442882, 195.7036094022929 -74.72248428442882, 195.7036094022929 -75.03513066218794, 194.8325250874459 -75.03513066218794, 194.8325250874459 -75.34777703994706, 193.67107933431657 -75.34777703994706, 193.67107933431657 -75.66042341770617, 192.79999501946958 -75.66042341770617, 192.79999501946958 -75.97306979546529, 191.63854926634022 -75.97306979546529, 191.63854926634022 -76.2857161732244, 190.76746495149322 -76.2857161732244, 190.76746495149322 -76.59836255098352, 189.6060191983639 -76.59836255098352, 189.6060191983639 -76.91100892874263, 188.7349348835169 -76.91100892874263, 188.7349348835169 -77.22365530650175, 187.57348913038757 -77.22365530650175, 187.57348913038757 -77.53630168426088, 186.70240481554055 -77.53630168426088, 186.70240481554055 -77.84894806201999, 185.54095906241122 -77.84894806201999, 185.54095906241122 -78.16159443977911, 184.3795133092819 -78.16159443977911, 184.3795133092819 -78.47424081753822, 183.5084289944349 -78.47424081753822, 183.5084289944349 -78.78688719529734, 182.34698324130557 -78.78688719529734, 182.34698324130557 -79.09953357305645, 181.47589892645854 -79.09953357305645, 181.47589892645854 -79.41217995081557, 180.60481461161154 -79.41217995081557, 180.60481461161154 -79.72482632857468, 179.44336885848222 -79.72482632857468, 179.44336885848222 -80.0374727063338, 178.57228454363522 -80.0374727063338, 178.57228454363522 -80.35011908409292, 177.99156166707056 -80.35011908409292, 177.99156166707056 -80.66276546185203, 177.12047735222356 -80.66276546185203, 177.12047735222356 -80.97541183961116, 176.53975447565887 -80.97541183961116, 176.53975447565887 -81.28805821737026, 175.66867016081187 -81.28805821737026, 175.66867016081187 -81.60070459512939, 175.0879472842472 -81.60070459512939, 175.0879472842472 -81.9133509728885, 174.50722440768254 -81.9133509728885, 174.50722440768254 -82.22599735064762, 173.05541721627088 -82.22599735064762, 173.05541721627088 -82.53864372840673, 171.31324858657686 -82.53864372840673, 171.31324858657686 -82.85129010616585, 169.8614413951652 -82.85129010616585, 169.8614413951652 -83.16393648392497, 168.1192727654712 -83.16393648392497, 168.1192727654712 -83.47658286168408, 166.3771041357772 -83.47658286168408, 166.3771041357772 -83.7892292394432, 164.6349355060832 -83.7892292394432, 164.6349355060832 -84.10187561720231, 162.60240543810687 -84.10187561720231, 162.60240543810687 -84.41452199496143, 160.86023680841285 -84.41452199496143, 160.86023680841285 -84.72716837272054, 159.11806817871886 -84.72716837272054, 159.11806817871886 -85.03981475047966, 157.37589954902487 -85.03981475047966, 157.37589954902487 -85.35246112823879, 155.05300804276618 -85.35246112823879, 155.05300804276618 -85.6651075059979, 153.02047797478986 -85.6651075059979, 153.02047797478986 -85.97775388375702, 150.9879479068135 -85.97775388375702, 150.9879479068135 -86.29040026151613, 148.95541783883718 -86.29040026151613, 148.95541783883718 -86.60304663927525, 147.21324920914319 -86.60304663927525, 147.21324920914319 -86.91569301703436, 145.18071914116683 -86.91569301703436, 145.18071914116683 -87.22833939479348, 142.85782763490818 -87.22833939479348, 142.85782763490818 -87.5409857725526, 140.24457469036716 -87.5409857725526, 140.24457469036716 -87.85363215031171, 136.1795145544145 -87.85363215031171, 136.1795145544145 -88.16627852807083, 128.92047859735615 -88.16627852807083, 128.92047859735615 -87.85363215031171, 126.88794852937983 -87.85363215031171, 126.88794852937983 -87.5409857725526, 125.14577989968582 -87.5409857725526, 125.14577989968582 -87.22833939479348, 123.69397270827415 -87.22833939479348, 123.69397270827415 -86.91569301703436, 121.95180407858015 -86.91569301703436, 121.95180407858015 -86.60304663927525, 120.49999688716848 -86.60304663927525, 120.49999688716848 -86.29040026151613, 119.0481896957568 -86.29040026151613, 119.0481896957568 -85.97775388375702, 117.59638250434514 -85.97775388375702, 117.59638250434514 -85.6651075059979, 112.9505994918278 -85.6651075059979, 112.9505994918278 -85.35246112823879, 109.4662622324398 -85.35246112823879, 109.4662622324398 -85.03981475047966, 106.8530092878988 -85.03981475047966, 106.8530092878988 -84.72716837272054, 103.65903346679312 -84.72716837272054, 103.65903346679312 -85.03981475047966, 97.85180470114645 -85.03981475047966, 97.85180470114645 -84.72716837272054, 94.07710600347612 -84.72716837272054, 94.07710600347612 -85.03981475047966, 90.88313018237044 -85.03981475047966, 90.88313018237044 -85.35246112823879, 88.26987723782943 -85.35246112823879, 88.26987723782943 -85.6651075059979, 85.65662429328843 -85.6651075059979, 85.65662429328843 -85.97775388375702, 82.46264847218276 -85.97775388375702, 82.46264847218276 -86.29040026151613, 77.52650402138309 -86.29040026151613, 77.52650402138309 -86.60304663927525, 74.33252820027742 -86.60304663927525, 74.33252820027742 -86.91569301703436, 72.59035957058342 -86.91569301703436), + (4.355421574235005 -87.22833939479348, 4.065060135952671 -87.22833939479348, 4.065060135952671 -87.5409857725526, 3.4843372593880044 -87.5409857725526, 3.4843372593880044 -87.85363215031171, 3.1939758211056706 -87.85363215031171, 3.1939758211056706 -88.16627852807083, 2.9036143828233367 -88.16627852807083, 2.9036143828233367 -88.47892490582994, 2.6132529445410033 -88.47892490582994, 2.6132529445410033 -88.79157128358906, 2.3228915062586695 -88.79157128358906, 2.3228915062586695 -89.10421766134817, 2.0325300679763356 -89.10421766134817, 2.0325300679763356 -89.4168640391073, 1.4518071914116684 -89.4168640391073, 1.4518071914116684 -89.7295104168664, 1.1614457531293347 -89.7295104168664, 1.1614457531293347 -90.04215679462553, 0.8710843148470011 -90.04215679462553, 0.8710843148470011 -90.35480317238465, 0.5807228765646674 -90.35480317238465, 0.5807228765646674 -90.66744955014376, 0.2903614382823337 -90.66744955014376, 0.2903614382823337 -90.98009592790288, 0 -90.98009592790288))MULTILINESTRING ((297.3301128011097 -73.15925239563325, 297.03975136282736 -73.15925239563325, 297.03975136282736 -73.47189877339235, 295.87830560969803 -73.47189877339235, 295.87830560969803 -73.78454515115148, 295.00722129485104 -73.78454515115148, 295.00722129485104 -74.09719152891059, 293.8457755417217 -74.09719152891059, 293.8457755417217 -74.40983790666971, 292.9746912268747 -74.40983790666971, 292.9746912268747 -74.72248428442882, 291.8132454737453 -74.72248428442882, 291.8132454737453 -75.03513066218794, 290.94216115889833 -75.03513066218794, 290.94216115889833 -75.34777703994706, 289.780715405769 -75.34777703994706, 289.780715405769 -75.66042341770617, 288.909631090922 -75.66042341770617, 288.909631090922 -75.97306979546529, 287.7481853377927 -75.97306979546529, 287.7481853377927 -76.2857161732244, 283.97348664012236 -76.2857161732244, 283.97348664012236 -76.59836255098352, 280.198787942452 -76.59836255098352, 280.198787942452 -76.91100892874263, 277.585534997911 -76.91100892874263, 277.585534997911 -77.22365530650175, 275.5530049299347 -77.22365530650175, 275.5530049299347 -76.91100892874263, 274.39155917680534 -76.91100892874263, 274.39155917680534 -76.59836255098352, 273.230113423676 -76.59836255098352, 273.230113423676 -76.2857161732244, 271.77830623226436 -76.2857161732244, 271.77830623226436 -75.97306979546529, 270.32649904085264 -75.97306979546529, 270.32649904085264 -75.66042341770617, 268.874691849441 -75.66042341770617, 268.874691849441 -75.34777703994706, 267.4228846580293 -75.34777703994706, 267.4228846580293 -75.03513066218794, 265.6807160283353 -75.03513066218794, 265.6807160283353 -74.72248428442882, 264.22890883692367 -74.72248428442882, 264.22890883692367 -74.40983790666971, 262.777101645512 -74.40983790666971, 262.777101645512 -74.09719152891059, 261.3252944541003 -74.09719152891059, 261.3252944541003 -73.78454515115148, 259.8734872626886 -73.78454515115148, 259.8734872626886 -73.47189877339235, 258.42168007127697 -73.47189877339235, 258.42168007127697 -73.15925239563325, 256.9698728798653 -73.15925239563325, 256.9698728798653 -72.84660601787412, 255.51806568845365 -72.84660601787412, 255.51806568845365 -72.533959640115, 254.06625849704199 -72.533959640115, 254.06625849704199 -72.22131326235589, 245.35541534857197 -72.22131326235589, 245.35541534857197 -71.90866688459677, 242.74216240403095 -71.90866688459677, 242.74216240403095 -71.59602050683766, 240.99999377433696 -71.59602050683766, 240.99999377433696 -71.28337412907854, 239.25782514464296 -71.28337412907854, 239.25782514464296 -70.97072775131943, 237.2252950766666 -70.97072775131943, 237.2252950766666 -70.65808137356031, 235.1927650086903 -70.65808137356031, 235.1927650086903 -70.3454349958012, 233.4505963789963 -70.3454349958012, 233.4505963789963 -70.03278861804208, 231.41806631101994 -70.03278861804208, 231.41806631101994 -69.72014224028295, 229.96625911960828 -69.72014224028295, 229.96625911960828 -69.40749586252385, 228.51445192819662 -69.40749586252385, 228.51445192819662 -69.09484948476472, 227.06264473678493 -69.09484948476472, 227.06264473678493 -68.78220310700561, 225.61083754537327 -68.78220310700561, 225.61083754537327 -68.46955672924649, 224.1590303539616 -68.46955672924649, 224.1590303539616 -68.15691035148738, 222.70722316254992 -68.15691035148738, 222.70722316254992 -67.84426397372826, 220.96505453285593 -67.84426397372826, 220.96505453285593 -67.53161759596915, 218.9325244648796 -67.53161759596915, 218.9325244648796 -67.21897121821003, 216.02891008205626 -67.21897121821003, 216.02891008205626 -66.9063248404509, 210.2216813164096 -66.9063248404509, 210.2216813164096 -66.5936784626918, 208.18915124843326 -66.5936784626918, 208.18915124843326 -66.9063248404509, 198.89758522339858 -66.9063248404509, 198.89758522339858 -66.5936784626918, 196.28433227885756 -66.5936784626918, 196.28433227885756 -66.9063248404509, 195.12288652572823 -66.9063248404509, 195.12288652572823 -67.21897121821003, 193.67107933431657 -67.21897121821003, 193.67107933431657 -67.53161759596915, 192.50963358118724 -67.53161759596915, 192.50963358118724 -67.84426397372826, 191.3481878280579 -67.84426397372826, 191.3481878280579 -68.15691035148738, 190.18674207492856 -68.15691035148738, 190.18674207492856 -68.46955672924649, 189.31565776008156 -68.46955672924649, 189.31565776008156 -68.78220310700561, 188.15421200695224 -68.78220310700561, 188.15421200695224 -69.09484948476472, 186.99276625382288 -69.09484948476472, 186.99276625382288 -69.40749586252385, 185.83132050069355 -69.40749586252385, 185.83132050069355 -69.72014224028295, 184.96023618584655 -69.72014224028295, 184.96023618584655 -70.03278861804208, 184.08915187099956 -70.03278861804208, 184.08915187099956 -70.3454349958012, 183.21806755615256 -70.3454349958012, 183.21806755615256 -70.65808137356031, 182.34698324130557 -70.65808137356031, 182.34698324130557 -70.97072775131943, 181.47589892645854 -70.97072775131943, 181.47589892645854 -71.28337412907854, 180.60481461161154 -71.28337412907854, 180.60481461161154 -71.59602050683766, 179.44336885848222 -71.59602050683766, 179.44336885848222 -71.90866688459677, 178.57228454363522 -71.90866688459677, 178.57228454363522 -72.22131326235589, 177.70120022878822 -72.22131326235589, 177.70120022878822 -72.533959640115, 176.8301159139412 -72.533959640115, 176.8301159139412 -72.84660601787412, 175.9590315990942 -72.84660601787412, 175.9590315990942 -73.15925239563325, 175.0879472842472 -73.15925239563325, 175.0879472842472 -73.47189877339235, 174.2168629694002 -73.47189877339235, 174.2168629694002 -73.78454515115148, 171.89397146314155 -73.78454515115148, 171.89397146314155 -74.09719152891059, 169.57107995688287 -74.09719152891059, 169.57107995688287 -74.40983790666971, 166.95782701234188 -74.40983790666971, 166.95782701234188 -74.72248428442882, 164.34457406780086 -74.72248428442882, 164.34457406780086 -75.03513066218794, 161.73132112325987 -75.03513066218794, 161.73132112325987 -75.34777703994706, 158.82770674043653 -75.34777703994706, 158.82770674043653 -75.66042341770617, 155.3433694810485 -75.66042341770617, 155.3433694810485 -75.97306979546529, 151.5686707833782 -75.97306979546529, 151.5686707833782 -76.2857161732244, 147.79397208570785 -76.2857161732244, 147.79397208570785 -76.59836255098352, 142.85782763490818 -76.59836255098352, 142.85782763490818 -76.91100892874263, 135.59879167784982 -76.91100892874263, 135.59879167784982 -76.59836255098352, 131.53373154189717 -76.59836255098352, 131.53373154189717 -76.2857161732244, 129.21084003563848 -76.2857161732244, 129.21084003563848 -75.97306979546529, 127.17830996766216 -75.97306979546529, 127.17830996766216 -75.66042341770617, 125.72650277625048 -75.66042341770617, 125.72650277625048 -75.34777703994706, 124.27469558483881 -75.34777703994706, 124.27469558483881 -75.03513066218794, 122.82288839342715 -75.03513066218794, 122.82288839342715 -74.72248428442882, 121.37108120201547 -74.72248428442882, 121.37108120201547 -74.40983790666971, 119.91927401060381 -74.40983790666971, 119.91927401060381 -74.09719152891059, 118.46746681919214 -74.09719152891059, 118.46746681919214 -73.78454515115148, 116.4349367512158 -73.78454515115148, 116.4349367512158 -73.47189877339235, 112.66023805354547 -73.47189877339235, 112.66023805354547 -73.15925239563325, 110.04698510900447 -73.15925239563325, 110.04698510900447 -72.84660601787412, 107.7240936027458 -72.84660601787412, 107.7240936027458 -72.533959640115, 98.72288901599346 -72.533959640115, 98.72288901599346 -72.22131326235589, 93.20602168862911 -72.22131326235589, 93.20602168862911 -72.533959640115, 89.14096155267644 -72.533959640115, 89.14096155267644 -72.84660601787412, 86.23734716985311 -72.84660601787412, 86.23734716985311 -73.15925239563325, 83.91445566359444 -73.15925239563325, 83.91445566359444 -73.47189877339235, 74.91325107684209 -73.47189877339235, 74.91325107684209 -73.78454515115148, 72.59035957058342 -73.78454515115148), + (72.29999813230108 -73.78454515115148, 70.55782950260709 -73.78454515115148, 70.55782950260709 -73.47189877339235, 67.65421511978374 -73.47189877339235, 67.65421511978374 -73.15925239563325, 64.75060073696041 -73.15925239563325, 64.75060073696041 -72.84660601787412, 62.427709230701744 -72.84660601787412, 62.427709230701744 -72.533959640115, 60.10481772444307 -72.533959640115, 60.10481772444307 -72.22131326235589, 58.94337197131374 -72.22131326235589, 58.94337197131374 -71.90866688459677, 57.49156477990207 -71.90866688459677, 57.49156477990207 -71.59602050683766, 56.330119026772735 -71.59602050683766, 56.330119026772735 -71.28337412907854, 55.1686732736434 -71.28337412907854, 55.1686732736434 -70.97072775131943, 54.007227520514064 -70.97072775131943, 54.007227520514064 -70.65808137356031, 53.13614320566706 -70.65808137356031, 53.13614320566706 -70.3454349958012, 51.97469745253773 -70.3454349958012, 51.97469745253773 -70.03278861804208, 51.10361313769073 -70.03278861804208, 51.10361313769073 -69.72014224028295, 50.232528822843726 -69.72014224028295, 50.232528822843726 -69.40749586252385, 49.07108306971439 -69.40749586252385, 49.07108306971439 -69.09484948476472, 47.61927587830272 -69.09484948476472, 47.61927587830272 -68.78220310700561, 46.45783012517339 -68.78220310700561, 46.45783012517339 -68.46955672924649, 45.00602293376172 -68.46955672924649, 45.00602293376172 -68.15691035148738, 43.55421574235005 -68.15691035148738, 43.55421574235005 -67.84426397372826, 42.39276998922072 -67.84426397372826, 42.39276998922072 -67.53161759596915, 41.23132423609138 -67.53161759596915, 41.23132423609138 -67.21897121821003, 40.06987848296205 -67.21897121821003, 40.06987848296205 -66.9063248404509, 38.61807129155038 -66.9063248404509, 38.61807129155038 -66.5936784626918, 37.16626410013871 -66.5936784626918, 37.16626410013871 -66.28103208493268, 35.42409547044471 -66.28103208493268, 35.42409547044471 -65.96838570717357, 33.39156540246837 -65.96838570717357, 33.39156540246837 -65.65573932941444, 31.359035334492038 -65.65573932941444, 31.359035334492038 -65.34309295165534, 28.745782389951035 -65.34309295165534, 28.745782389951035 -65.03044657389621, 25.551806568845365 -65.03044657389621, 25.551806568845365 -65.34309295165534, 24.099999377433697 -65.34309295165534, 24.099999377433697 -65.65573932941444, 22.648192186022026 -65.65573932941444, 22.648192186022026 -65.96838570717357, 21.486746432892694 -65.96838570717357, 21.486746432892694 -66.28103208493268, 20.61566211804569 -66.28103208493268, 20.61566211804569 -66.5936784626918, 19.74457780319869 -66.5936784626918), + (4.355421574235005 -68.46955672924649, 4.065060135952671 -68.46955672924649, 4.065060135952671 -68.78220310700561, 3.4843372593880044 -68.78220310700561, 3.4843372593880044 -69.09484948476472, 2.9036143828233367 -69.09484948476472, 2.9036143828233367 -69.40749586252385, 2.3228915062586695 -69.40749586252385, 2.3228915062586695 -69.72014224028295, 1.7421686296940022 -69.72014224028295, 1.7421686296940022 -70.03278861804208, 0.8710843148470011 -70.03278861804208, 0.8710843148470011 -70.3454349958012, 0.2903614382823337 -70.3454349958012, 0.2903614382823337 -70.65808137356031, 0 -70.65808137356031))MULTILINESTRING ((297.3301128011097 -70.03278861804208, 297.03975136282736 -70.03278861804208, 297.03975136282736 -70.3454349958012, 295.87830560969803 -70.3454349958012, 295.87830560969803 -70.65808137356031, 295.00722129485104 -70.65808137356031, 295.00722129485104 -70.97072775131943, 293.8457755417217 -70.97072775131943, 293.8457755417217 -71.28337412907854, 292.9746912268747 -71.28337412907854, 292.9746912268747 -71.59602050683766, 291.8132454737453 -71.59602050683766, 291.8132454737453 -71.90866688459677, 290.94216115889833 -71.90866688459677, 290.94216115889833 -72.22131326235589, 289.780715405769 -72.22131326235589, 289.780715405769 -72.533959640115, 288.909631090922 -72.533959640115, 288.909631090922 -72.84660601787412, 288.038546776075 -72.84660601787412, 288.038546776075 -73.15925239563325, 283.3927637635577 -73.15925239563325, 283.3927637635577 -73.47189877339235, 279.03734218932266 -73.47189877339235, 279.03734218932266 -73.78454515115148, 275.26264349165234 -73.78454515115148, 275.26264349165234 -73.47189877339235, 273.8108363002407 -73.47189877339235, 273.8108363002407 -73.15925239563325, 272.64939054711135 -73.15925239563325, 272.64939054711135 -72.84660601787412, 271.19758335569963 -72.84660601787412, 271.19758335569963 -72.533959640115, 269.745776164288 -72.533959640115, 269.745776164288 -72.22131326235589, 268.2939689728763 -72.22131326235589, 268.2939689728763 -71.90866688459677, 266.5518003431823 -71.90866688459677, 266.5518003431823 -71.59602050683766, 264.80963171348833 -71.59602050683766, 264.80963171348833 -71.28337412907854, 263.35782452207667 -71.28337412907854, 263.35782452207667 -70.97072775131943, 261.6156558923827 -70.97072775131943, 261.6156558923827 -70.65808137356031, 260.16384870097096 -70.65808137356031, 260.16384870097096 -70.3454349958012, 258.42168007127697 -70.3454349958012, 258.42168007127697 -70.03278861804208, 256.9698728798653 -70.03278861804208, 256.9698728798653 -69.72014224028295, 255.2277042501713 -69.72014224028295, 255.2277042501713 -69.40749586252385, 252.6144513056303 -69.40749586252385, 252.6144513056303 -69.09484948476472, 246.80722253998363 -69.09484948476472, 246.80722253998363 -68.78220310700561, 243.61324671887797 -68.78220310700561, 243.61324671887797 -68.46955672924649, 240.99999377433696 -68.46955672924649, 240.99999377433696 -68.15691035148738, 238.6771022680783 -68.15691035148738, 238.6771022680783 -67.84426397372826, 236.35421076181962 -67.84426397372826, 236.35421076181962 -67.53161759596915, 234.03131925556096 -67.53161759596915, 234.03131925556096 -67.21897121821003, 231.70842774930227 -67.21897121821003, 231.70842774930227 -66.9063248404509, 229.96625911960828 -66.9063248404509, 229.96625911960828 -66.5936784626918, 228.80481336647895 -66.5936784626918, 228.80481336647895 -66.28103208493268, 227.35300617506726 -66.28103208493268, 227.35300617506726 -65.96838570717357, 225.9011989836556 -65.96838570717357, 225.9011989836556 -65.65573932941444, 224.44939179224394 -65.65573932941444, 224.44939179224394 -65.34309295165534, 222.99758460083228 -65.34309295165534, 222.99758460083228 -65.03044657389621, 221.25541597113826 -65.03044657389621, 221.25541597113826 -64.71780019613709, 219.8036087797266 -64.71780019613709, 219.8036087797266 -64.40515381837798, 217.48071727346792 -64.40515381837798, 217.48071727346792 -64.09250744061886, 214.86746432892693 -64.09250744061886, 214.86746432892693 -63.77986106285975, 210.51204275469192 -63.77986106285975, 210.51204275469192 -63.46721468510063, 207.60842837186857 -63.46721468510063, 207.60842837186857 -63.77986106285975, 200.34939241481024 -63.77986106285975, 200.34939241481024 -63.46721468510063, 197.15541659370456 -63.46721468510063, 197.15541659370456 -63.15456830734151, 196.86505515542223 -63.15456830734151, 196.86505515542223 -63.46721468510063, 195.7036094022929 -63.46721468510063, 195.7036094022929 -63.77986106285975, 194.25180221088124 -63.77986106285975, 194.25180221088124 -64.09250744061886, 193.0903564577519 -64.09250744061886, 193.0903564577519 -64.40515381837798, 191.92891070462255 -64.40515381837798, 191.92891070462255 -64.71780019613709, 190.76746495149322 -64.71780019613709, 190.76746495149322 -65.03044657389621, 189.6060191983639 -65.03044657389621, 189.6060191983639 -65.34309295165534, 188.44457344523457 -65.34309295165534, 188.44457344523457 -65.65573932941444, 187.28312769210524 -65.65573932941444, 187.28312769210524 -65.96838570717357, 186.12168193897588 -65.96838570717357, 186.12168193897588 -66.28103208493268, 185.2505976241289 -66.28103208493268, 185.2505976241289 -66.5936784626918, 184.3795133092819 -66.5936784626918, 184.3795133092819 -66.9063248404509, 183.5084289944349 -66.9063248404509, 183.5084289944349 -67.21897121821003, 182.34698324130557 -67.21897121821003, 182.34698324130557 -67.53161759596915, 181.47589892645854 -67.53161759596915, 181.47589892645854 -67.84426397372826, 180.60481461161154 -67.84426397372826, 180.60481461161154 -68.15691035148738, 179.73373029676455 -68.15691035148738, 179.73373029676455 -68.46955672924649, 178.57228454363522 -68.46955672924649, 178.57228454363522 -68.78220310700561, 177.70120022878822 -68.78220310700561, 177.70120022878822 -69.09484948476472, 176.8301159139412 -69.09484948476472, 176.8301159139412 -69.40749586252385, 175.66867016081187 -69.40749586252385, 175.66867016081187 -69.72014224028295, 174.79758584596487 -69.72014224028295, 174.79758584596487 -70.03278861804208, 173.05541721627088 -70.03278861804208, 173.05541721627088 -70.3454349958012, 170.44216427172987 -70.3454349958012, 170.44216427172987 -70.65808137356031, 167.53854988890654 -70.65808137356031, 167.53854988890654 -70.97072775131943, 164.6349355060832 -70.97072775131943, 164.6349355060832 -71.28337412907854, 161.4409596849775 -71.28337412907854, 161.4409596849775 -71.59602050683766, 157.6662609873072 -71.59602050683766, 157.6662609873072 -71.90866688459677, 153.02047797478986 -71.90866688459677, 153.02047797478986 -72.22131326235589, 148.08433352399018 -72.22131326235589, 148.08433352399018 -72.533959640115, 135.01806880128515 -72.533959640115, 135.01806880128515 -72.22131326235589, 131.8240929801795 -72.22131326235589, 131.8240929801795 -71.90866688459677, 129.79156291220315 -71.90866688459677, 129.79156291220315 -71.59602050683766, 127.75903284422682 -71.59602050683766, 127.75903284422682 -71.28337412907854, 126.30722565281515 -71.28337412907854, 126.30722565281515 -70.97072775131943, 124.85541846140349 -70.97072775131943, 124.85541846140349 -70.65808137356031, 123.40361126999181 -70.65808137356031, 123.40361126999181 -70.3454349958012, 121.95180407858015 -70.3454349958012, 121.95180407858015 -70.03278861804208, 120.49999688716848 -70.03278861804208, 120.49999688716848 -69.72014224028295, 119.33855113403915 -69.72014224028295, 119.33855113403915 -69.40749586252385, 117.88674394262748 -69.40749586252385, 117.88674394262748 -69.09484948476472, 114.98312955980414 -69.09484948476472, 114.98312955980414 -68.78220310700561, 111.78915373869847 -68.78220310700561, 111.78915373869847 -68.46955672924649, 109.4662622324398 -68.46955672924649, 109.4662622324398 -68.15691035148738, 107.14337072618113 -68.15691035148738, 107.14337072618113 -67.84426397372826, 99.30361189255812 -67.84426397372826, 99.30361189255812 -67.53161759596915, 92.62529881206444 -67.53161759596915, 92.62529881206444 -67.84426397372826, 88.85060011439411 -67.84426397372826, 88.85060011439411 -68.15691035148738, 85.94698573157078 -68.15691035148738, 85.94698573157078 -68.46955672924649, 83.6240942253121 -68.46955672924649, 83.6240942253121 -68.78220310700561, 74.62288963855976 -68.78220310700561, 74.62288963855976 -69.09484948476472, 72.59035957058342 -69.09484948476472), + (4.355421574235005 -61.27869004078681, 4.065060135952671 -61.27869004078681, 4.065060135952671 -61.591336418545936, 3.4843372593880044 -61.591336418545936, 3.4843372593880044 -61.90398279630505, 2.6132529445410033 -61.90398279630505, 2.6132529445410033 -62.21662917406417, 1.7421686296940022 -62.21662917406417, 1.7421686296940022 -62.52927555182328, 1.1614457531293347 -62.52927555182328, 1.1614457531293347 -62.8419219295824, 0.2903614382823337 -62.8419219295824, 0.2903614382823337 -63.15456830734151, 0 -63.15456830734151), + (72.29999813230108 -69.09484948476472, 70.55782950260709 -69.09484948476472, 70.55782950260709 -68.78220310700561, 67.65421511978374 -68.78220310700561, 67.65421511978374 -68.46955672924649, 65.04096217524274 -68.46955672924649, 65.04096217524274 -68.15691035148738, 62.427709230701744 -68.15691035148738, 62.427709230701744 -67.84426397372826, 60.395179162725405 -67.84426397372826, 60.395179162725405 -67.53161759596915, 58.94337197131374 -67.53161759596915, 58.94337197131374 -67.21897121821003, 57.7819262181844 -67.21897121821003, 57.7819262181844 -66.9063248404509, 56.62048046505507 -66.9063248404509, 56.62048046505507 -66.5936784626918, 55.45903471192573 -66.5936784626918, 55.45903471192573 -66.28103208493268, 54.297588958796396 -66.28103208493268, 54.297588958796396 -65.96838570717357, 53.4265046439494 -65.96838570717357, 53.4265046439494 -65.65573932941444, 52.265058890820065 -65.65573932941444, 52.265058890820065 -65.34309295165534, 51.39397457597306 -65.34309295165534, 51.39397457597306 -65.03044657389621, 50.52289026112606 -65.03044657389621, 50.52289026112606 -64.71780019613709, 49.942167384561394 -64.71780019613709, 49.942167384561394 -64.40515381837798, 48.78072163143206 -64.40515381837798, 48.78072163143206 -64.09250744061886, 47.32891444002039 -64.09250744061886, 47.32891444002039 -63.77986106285975, 45.87710724860872 -63.77986106285975, 45.87710724860872 -63.46721468510063, 44.71566149547939 -63.46721468510063, 44.71566149547939 -63.15456830734151, 43.26385430406772 -63.15456830734151, 43.26385430406772 -62.8419219295824, 42.102408550938385 -62.8419219295824, 42.102408550938385 -62.52927555182328, 40.94096279780905 -62.52927555182328, 40.94096279780905 -62.21662917406417, 39.779517044679714 -62.21662917406417, 39.779517044679714 -61.90398279630505, 38.61807129155038 -61.90398279630505, 38.61807129155038 -61.591336418545936, 37.16626410013871 -61.591336418545936, 37.16626410013871 -61.27869004078681, 35.42409547044471 -61.27869004078681, 35.42409547044471 -60.9660436630277, 33.681926840750705 -60.9660436630277, 33.681926840750705 -60.65339728526858, 31.939758211056706 -60.65339728526858, 31.939758211056706 -60.34075090750947, 29.616866704798035 -60.34075090750947, 29.616866704798035 -60.02810452975035, 27.293975198539368 -60.02810452975035, 27.293975198539368 -59.715458151991236, 26.7132523219747 -59.715458151991236, 26.7132523219747 -60.02810452975035, 24.39036081571603 -60.02810452975035, 24.39036081571603 -60.34075090750947, 22.93855362430436 -60.34075090750947, 22.93855362430436 -60.65339728526858, 21.486746432892694 -60.65339728526858, 21.486746432892694 -60.9660436630277, 20.61566211804569 -60.9660436630277, 20.61566211804569 -61.27869004078681, 19.74457780319869 -61.27869004078681))MULTILINESTRING ((4.355421574235005 -10.629976843809958, 1.1614457531293347 -10.629976843809958, 1.1614457531293347 -10.942623221569075, 0 -10.942623221569075), + (4.355421574235005 -49.08548130818128, 4.065060135952671 -49.08548130818128, 4.065060135952671 -49.398127685940395, 2.9036143828233367 -49.398127685940395, 2.9036143828233367 -49.71077406369951, 1.4518071914116684 -49.71077406369951, 1.4518071914116684 -50.023420441458626, 0 -50.023420441458626), + (72.29999813230108 -60.65339728526858, 69.68674518776008 -60.65339728526858, 69.68674518776008 -60.34075090750947, 67.07349224321908 -60.34075090750947, 67.07349224321908 -60.02810452975035, 64.46023929867808 -60.02810452975035, 64.46023929867808 -59.715458151991236, 61.84698635413707 -59.715458151991236, 61.84698635413707 -59.40281177423212, 60.10481772444307 -59.40281177423212, 60.10481772444307 -59.090165396473004, 58.94337197131374 -59.090165396473004, 58.94337197131374 -58.77751901871389, 57.7819262181844 -58.77751901871389, 57.7819262181844 -58.464872640954766, 56.9108419033374 -58.464872640954766, 56.9108419033374 -58.15222626319565, 55.74939615020807 -58.15222626319565, 55.74939615020807 -57.839579885436535, 54.87831183536107 -57.839579885436535, 54.87831183536107 -57.52693350767742, 54.007227520514064 -57.52693350767742, 54.007227520514064 -57.214287129918304, 53.13614320566706 -57.214287129918304, 53.13614320566706 -56.90164075215919, 52.265058890820065 -56.90164075215919, 52.265058890820065 -56.58899437440007, 51.68433601425539 -56.58899437440007, 51.68433601425539 -56.27634799664095, 50.8132516994084 -56.27634799664095, 50.8132516994084 -55.963701618881835, 49.942167384561394 -55.963701618881835, 49.942167384561394 -55.65105524112272, 49.36144450799673 -55.65105524112272, 49.36144450799673 -55.338408863363604, 47.909637316585055 -55.338408863363604, 47.909637316585055 -55.02576248560449, 46.74819156345572 -55.02576248560449, 46.74819156345572 -54.71311610784537, 45.58674581032639 -54.71311610784537, 45.58674581032639 -54.40046973008626, 44.425300057197056 -54.40046973008626, 44.425300057197056 -54.08782335232714, 43.26385430406772 -54.08782335232714, 43.26385430406772 -53.775176974568026, 42.102408550938385 -53.775176974568026, 42.102408550938385 -53.462530596808904, 40.94096279780905 -53.462530596808904, 40.94096279780905 -53.14988421904979, 40.06987848296205 -53.14988421904979, 40.06987848296205 -52.83723784129067, 38.90843272983271 -52.83723784129067, 38.90843272983271 -52.52459146353156, 37.746986976703376 -52.52459146353156, 37.746986976703376 -52.21194508577244, 36.29517978529171 -52.21194508577244, 36.29517978529171 -51.899298708013326, 35.13373403216237 -51.899298708013326, 35.13373403216237 -51.58665233025421, 33.39156540246837 -51.58665233025421, 33.39156540246837 -51.27400595249509, 31.939758211056706 -51.27400595249509, 31.939758211056706 -50.96135957473597, 30.197589581362703 -50.96135957473597, 30.197589581362703 -50.64871319697686, 28.165059513386367 -50.64871319697686, 28.165059513386367 -50.33606681921774, 24.39036081571603 -50.33606681921774, 24.39036081571603 -50.64871319697686, 22.648192186022026 -50.64871319697686, 22.648192186022026 -50.96135957473597, 21.19638499461036 -50.96135957473597, 21.19638499461036 -51.27400595249509, 20.034939241481023 -51.27400595249509, 20.034939241481023 -51.58665233025421, 19.74457780319869 -51.58665233025421), + (297.3301128011097 -64.09250744061886, 297.03975136282736 -64.09250744061886, 297.03975136282736 -64.40515381837798, 296.16866704798036 -64.40515381837798, 296.16866704798036 -64.71780019613709, 295.29758273313337 -64.71780019613709, 295.29758273313337 -65.03044657389621, 294.13613698000404 -65.03044657389621, 294.13613698000404 -65.34309295165534, 293.26505266515704 -65.34309295165534, 293.26505266515704 -65.65573932941444, 292.39396835031005 -65.65573932941444, 292.39396835031005 -65.96838570717357, 291.522884035463 -65.96838570717357, 291.522884035463 -66.28103208493268, 290.651799720616 -66.28103208493268, 290.651799720616 -66.5936784626918, 289.49035396748667 -66.5936784626918, 289.49035396748667 -66.9063248404509, 288.6192696526397 -66.9063248404509, 288.6192696526397 -67.21897121821003, 287.7481853377927 -67.21897121821003, 287.7481853377927 -67.53161759596915, 279.03734218932266 -67.53161759596915, 279.03734218932266 -67.84426397372826, 275.5530049299347 -67.84426397372826, 275.5530049299347 -67.53161759596915, 274.101197738523 -67.53161759596915, 274.101197738523 -67.21897121821003, 272.9397519853937 -67.21897121821003, 272.9397519853937 -66.9063248404509, 271.48794479398197 -66.9063248404509, 271.48794479398197 -66.5936784626918, 270.0361376025703 -66.5936784626918, 270.0361376025703 -66.28103208493268, 268.58433041115865 -66.28103208493268, 268.58433041115865 -65.96838570717357, 267.132523219747 -65.96838570717357, 267.132523219747 -65.65573932941444, 265.390354590053 -65.65573932941444, 265.390354590053 -65.34309295165534, 263.648185960359 -65.34309295165534, 263.648185960359 -65.03044657389621, 261.6156558923827 -65.03044657389621, 261.6156558923827 -64.71780019613709, 259.8734872626886 -64.71780019613709, 259.8734872626886 -64.40515381837798, 257.8409571947123 -64.40515381837798, 257.8409571947123 -64.09250744061886, 256.0987885650183 -64.09250744061886, 256.0987885650183 -63.77986106285975, 254.06625849704199 -63.77986106285975, 254.06625849704199 -63.46721468510063, 250.0011983610893 -63.46721468510063, 250.0011983610893 -63.15456830734151, 245.93613822513663 -63.15456830734151, 245.93613822513663 -62.8419219295824, 242.45180096574862 -62.8419219295824, 242.45180096574862 -62.52927555182328, 239.25782514464296 -62.52927555182328, 239.25782514464296 -62.21662917406417, 236.06384932353728 -62.21662917406417, 236.06384932353728 -61.90398279630505, 232.8698735024316 -61.90398279630505, 232.8698735024316 -61.591336418545936, 230.54698199617295 -61.591336418545936, 230.54698199617295 -61.27869004078681, 229.38553624304362 -61.27869004078681, 229.38553624304362 -60.9660436630277, 228.2240904899143 -60.9660436630277, 228.2240904899143 -60.65339728526858, 227.06264473678493 -60.65339728526858, 227.06264473678493 -60.34075090750947, 225.61083754537327 -60.34075090750947, 225.61083754537327 -60.02810452975035, 224.44939179224394 -60.02810452975035, 224.44939179224394 -59.715458151991236, 222.99758460083228 -59.715458151991236, 222.99758460083228 -59.40281177423212, 221.5457774094206 -59.40281177423212, 221.5457774094206 -59.090165396473004, 219.8036087797266 -59.090165396473004, 219.8036087797266 -58.77751901871389, 218.0614401500326 -58.77751901871389, 218.0614401500326 -58.464872640954766, 216.02891008205626 -58.464872640954766, 216.02891008205626 -58.15222626319565, 213.41565713751527 -58.15222626319565, 213.41565713751527 -57.839579885436535, 201.8011996062219 -57.839579885436535, 201.8011996062219 -57.52693350767742, 198.31686234683391 -57.52693350767742, 198.31686234683391 -57.214287129918304, 196.28433227885756 -57.214287129918304, 196.28433227885756 -57.52693350767742, 194.8325250874459 -57.52693350767742, 194.8325250874459 -57.839579885436535, 193.67107933431657 -57.839579885436535, 193.67107933431657 -58.15222626319565, 192.21927214290488 -58.15222626319565, 192.21927214290488 -58.464872640954766, 191.05782638977556 -58.464872640954766, 191.05782638977556 -58.77751901871389, 189.6060191983639 -58.77751901871389, 189.6060191983639 -59.090165396473004, 188.44457344523457 -59.090165396473004, 188.44457344523457 -59.40281177423212, 187.28312769210524 -59.40281177423212, 187.28312769210524 -59.715458151991236, 186.12168193897588 -59.715458151991236, 186.12168193897588 -60.02810452975035, 184.96023618584655 -60.02810452975035, 184.96023618584655 -60.34075090750947, 184.08915187099956 -60.34075090750947, 184.08915187099956 -60.65339728526858, 183.21806755615256 -60.65339728526858, 183.21806755615256 -60.9660436630277, 182.05662180302323 -60.9660436630277, 182.05662180302323 -61.27869004078681, 181.1855374881762 -61.27869004078681, 181.1855374881762 -61.591336418545936, 180.02409173504688 -61.591336418545936, 180.02409173504688 -61.90398279630505, 179.15300742019988 -61.90398279630505, 179.15300742019988 -62.21662917406417, 177.99156166707056 -62.21662917406417, 177.99156166707056 -62.52927555182328, 176.8301159139412 -62.52927555182328, 176.8301159139412 -62.8419219295824, 175.9590315990942 -62.8419219295824, 175.9590315990942 -63.15456830734151, 174.79758584596487 -63.15456830734151, 174.79758584596487 -63.46721468510063, 172.76505577798855 -63.46721468510063, 172.76505577798855 -63.77986106285975, 169.28071851860054 -63.77986106285975, 169.28071851860054 -64.09250744061886, 165.5060198209302 -64.09250744061886, 165.5060198209302 -64.40515381837798, 161.15059824669518 -64.40515381837798, 161.15059824669518 -64.71780019613709, 155.3433694810485 -64.71780019613709, 155.3433694810485 -65.03044657389621, 146.05180345601383 -65.03044657389621, 146.05180345601383 -65.34309295165534, 141.11565900521418 -65.34309295165534, 141.11565900521418 -65.03044657389621, 136.1795145544145 -65.03044657389621, 136.1795145544145 -64.71780019613709, 133.5662616098735 -64.71780019613709, 133.5662616098735 -64.40515381837798, 131.53373154189717 -64.40515381837798, 131.53373154189717 -64.09250744061886, 129.50120147392082 -64.09250744061886, 129.50120147392082 -63.77986106285975, 128.04939428250916 -63.77986106285975, 128.04939428250916 -63.46721468510063, 126.59758709109748 -63.46721468510063, 126.59758709109748 -63.15456830734151, 125.14577989968582 -63.15456830734151, 125.14577989968582 -62.8419219295824, 123.98433414655648 -62.8419219295824, 123.98433414655648 -62.52927555182328, 122.82288839342715 -62.52927555182328, 122.82288839342715 -62.21662917406417, 121.6614426402978 -62.21662917406417, 121.6614426402978 -61.90398279630505, 120.49999688716848 -61.90398279630505, 120.49999688716848 -61.591336418545936, 119.33855113403915 -61.591336418545936, 119.33855113403915 -61.27869004078681, 118.17710538090981 -61.27869004078681, 118.17710538090981 -60.9660436630277, 115.5638524363688 -60.9660436630277, 115.5638524363688 -60.65339728526858, 112.66023805354547 -60.65339728526858, 112.66023805354547 -60.34075090750947, 110.3373465472868 -60.34075090750947, 110.3373465472868 -60.02810452975035, 108.30481647931046 -60.02810452975035, 108.30481647931046 -59.715458151991236, 106.8530092878988 -59.715458151991236, 106.8530092878988 -59.40281177423212, 100.46505764568745 -59.40281177423212, 100.46505764568745 -59.090165396473004, 91.46385305893511 -59.090165396473004, 91.46385305893511 -59.40281177423212, 88.26987723782943 -59.40281177423212, 88.26987723782943 -59.715458151991236, 85.94698573157078 -59.715458151991236, 85.94698573157078 -60.02810452975035, 84.20481710187677 -60.02810452975035, 84.20481710187677 -60.34075090750947, 76.07469682997143 -60.34075090750947, 76.07469682997143 -60.65339728526858, 72.59035957058342 -60.65339728526858), + (58.362649094749074 0, 58.362649094749074 -0.3126463777591164, 58.653010533031406 -0.3126463777591164, 58.653010533031406 -0.6252927555182328, 59.23373340959607 -0.6252927555182328, 59.23373340959607 -0.9379391332773492, 59.5240948478784 -0.9379391332773492, 59.5240948478784 -1.2505855110364656, 59.81445628616074 -1.2505855110364656, 59.81445628616074 -1.563231888795582, 60.10481772444307 -1.563231888795582, 60.10481772444307 -2.8138173998320477, 59.81445628616074 -2.8138173998320477, 59.81445628616074 -3.126463777591164, 59.5240948478784 -3.126463777591164, 59.5240948478784 -3.4391101553502805, 58.94337197131374 -3.4391101553502805, 58.94337197131374 -3.751756533109397, 58.362649094749074 -3.751756533109397, 58.362649094749074 -4.064402910868513, 57.49156477990207 -4.064402910868513, 57.49156477990207 -4.37704928862763, 56.330119026772735 -4.37704928862763, 56.330119026772735 -4.689695666386746, 54.87831183536107 -4.689695666386746, 54.87831183536107 -5.002342044145863, 53.13614320566706 -5.002342044145863, 53.13614320566706 -5.314988421904979, 51.39397457597306 -5.314988421904979, 51.39397457597306 -5.627634799664095, 49.36144450799673 -5.627634799664095, 49.36144450799673 -5.940281177423212, 47.32891444002039 -5.940281177423212, 47.32891444002039 -6.252927555182328, 45.29638437204405 -6.252927555182328, 45.29638437204405 -6.565573932941445, 42.97349286578539 -6.565573932941445, 42.97349286578539 -6.878220310700561, 40.65060135952672 -6.878220310700561, 40.65060135952672 -7.1908666884596775, 38.037348414985715 -7.1908666884596775, 38.037348414985715 -7.503513066218794, 35.42409547044471 -7.503513066218794, 35.42409547044471 -7.81615944397791, 32.52048108762137 -7.81615944397791, 32.52048108762137 -8.128805821737027, 29.616866704798035 -8.128805821737027, 29.616866704798035 -8.441452199496144, 26.422890883692364 -8.441452199496144, 26.422890883692364 -8.75409857725526, 23.80963793915136 -8.75409857725526, 23.80963793915136 -9.066744955014375, 21.486746432892694 -9.066744955014375, 21.486746432892694 -9.379391332773492, 19.74457780319869 -9.379391332773492))MULTILINESTRING ((297.3301128011097 -52.83723784129067, 296.4590284862627 -52.83723784129067, 296.4590284862627 -53.14988421904979, 295.5879441714157 -53.14988421904979, 295.5879441714157 -53.462530596808904, 294.7168598565687 -53.462530596808904, 294.7168598565687 -53.775176974568026, 293.8457755417217 -53.775176974568026, 293.8457755417217 -54.08782335232714, 292.9746912268747 -54.08782335232714, 292.9746912268747 -54.40046973008626, 292.10360691202766 -54.40046973008626, 292.10360691202766 -54.71311610784537, 291.522884035463 -54.71311610784537, 291.522884035463 -55.02576248560449, 290.651799720616 -55.02576248560449, 290.651799720616 -55.338408863363604, 289.780715405769 -55.338408863363604, 289.780715405769 -55.65105524112272, 289.19999252920434 -55.65105524112272, 289.19999252920434 -55.963701618881835, 288.32890821435734 -55.963701618881835, 288.32890821435734 -56.27634799664095, 275.843366368217 -56.27634799664095, 275.843366368217 -55.963701618881835, 274.6819206150877 -55.963701618881835, 274.6819206150877 -55.65105524112272, 273.52047486195835 -55.65105524112272, 273.52047486195835 -55.338408863363604, 272.359029108829 -55.338408863363604, 272.359029108829 -55.02576248560449, 271.19758335569963 -55.02576248560449, 271.19758335569963 -54.71311610784537, 270.0361376025703 -54.71311610784537, 270.0361376025703 -54.40046973008626, 268.874691849441 -54.40046973008626, 268.874691849441 -54.08782335232714, 267.71324609631165 -54.08782335232714, 267.71324609631165 -53.775176974568026, 266.5518003431823 -53.775176974568026, 266.5518003431823 -53.462530596808904, 265.09999315177066 -53.462530596808904, 265.09999315177066 -53.14988421904979, 262.4867402072297 -53.14988421904979, 262.4867402072297 -52.83723784129067, 259.8734872626886 -52.83723784129067, 259.8734872626886 -52.52459146353156, 257.55059575642997 -52.52459146353156, 257.55059575642997 -52.21194508577244, 254.93734281188898 -52.21194508577244, 254.93734281188898 -51.899298708013326, 250.8722826759363 -51.899298708013326, 250.8722826759363 -51.58665233025421, 245.93613822513663 -51.58665233025421, 245.93613822513663 -51.27400595249509, 241.2903552126193 -51.27400595249509, 241.2903552126193 -50.96135957473597, 238.0963793915136 -50.96135957473597, 238.0963793915136 -50.64871319697686, 234.90240357040796 -50.64871319697686, 234.90240357040796 -50.33606681921774, 231.9987891875846 -50.33606681921774, 231.9987891875846 -50.023420441458626, 230.54698199617295 -50.023420441458626, 230.54698199617295 -49.71077406369951, 229.67589768132595 -49.71077406369951, 229.67589768132595 -49.398127685940395, 228.51445192819662 -49.398127685940395, 228.51445192819662 -49.08548130818128, 227.6433676133496 -49.08548130818128, 227.6433676133496 -48.772834930422164, 226.7722832985026 -48.772834930422164, 226.7722832985026 -48.46018855266304, 225.61083754537327 -48.46018855266304, 225.61083754537327 -48.147542174903926, 224.73975323052628 -48.147542174903926, 224.73975323052628 -47.83489579714481, 223.57830747739695 -47.83489579714481, 223.57830747739695 -47.522249419385695, 222.4168617242676 -47.522249419385695, 222.4168617242676 -47.20960304162658, 221.25541597113826 -47.20960304162658, 221.25541597113826 -46.89695666386746, 220.09397021800893 -46.89695666386746, 220.09397021800893 -46.58431028610835, 218.35180158831494 -46.58431028610835, 218.35180158831494 -46.271663908349225, 216.02891008205626 -46.271663908349225, 216.02891008205626 -45.95901753059011, 213.41565713751527 -45.95901753059011, 213.41565713751527 -45.646371152830994, 209.64095843984492 -45.646371152830994, 209.64095843984492 -45.33372477507188, 201.51083816793957 -45.33372477507188, 201.51083816793957 -45.02107839731276, 198.60722378511625 -45.02107839731276, 198.60722378511625 -44.70843201955365, 195.99397084057523 -44.70843201955365, 195.99397084057523 -45.02107839731276, 194.54216364916357 -45.02107839731276, 194.54216364916357 -45.33372477507188, 193.0903564577519 -45.33372477507188, 193.0903564577519 -45.646371152830994, 191.63854926634022 -45.646371152830994, 191.63854926634022 -45.95901753059011, 190.18674207492856 -45.95901753059011, 190.18674207492856 -46.271663908349225, 189.02529632179923 -46.271663908349225, 189.02529632179923 -46.58431028610835, 187.57348913038757 -46.58431028610835, 187.57348913038757 -46.89695666386746, 186.12168193897588 -46.89695666386746, 186.12168193897588 -47.20960304162658, 184.96023618584655 -47.20960304162658, 184.96023618584655 -47.522249419385695, 183.79879043271723 -47.522249419385695, 183.79879043271723 -47.83489579714481, 182.34698324130557 -47.83489579714481, 182.34698324130557 -48.147542174903926, 181.1855374881762 -48.147542174903926, 181.1855374881762 -48.46018855266304, 180.02409173504688 -48.46018855266304, 180.02409173504688 -48.772834930422164, 178.86264598191755 -48.772834930422164, 178.86264598191755 -49.08548130818128, 177.70120022878822 -49.08548130818128, 177.70120022878822 -49.398127685940395, 176.53975447565887 -49.398127685940395, 176.53975447565887 -49.71077406369951, 175.37830872252954 -49.71077406369951, 175.37830872252954 -50.023420441458626, 174.2168629694002 -50.023420441458626, 174.2168629694002 -50.33606681921774, 168.1192727654712 -50.33606681921774, 168.1192727654712 -50.64871319697686, 161.4409596849775 -50.64871319697686, 161.4409596849775 -50.96135957473597, 144.0192733880375 -50.96135957473597, 144.0192733880375 -50.64871319697686, 139.37349037552016 -50.64871319697686, 139.37349037552016 -50.33606681921774, 137.0505988692615 -50.33606681921774, 137.0505988692615 -50.023420441458626, 135.30843023956749 -50.023420441458626, 135.30843023956749 -49.71077406369951, 133.5662616098735 -49.71077406369951, 133.5662616098735 -49.398127685940395, 132.11445441846183 -49.398127685940395, 132.11445441846183 -49.08548130818128, 130.9530086653325 -49.08548130818128, 130.9530086653325 -48.772834930422164, 129.79156291220315 -48.772834930422164, 129.79156291220315 -48.46018855266304, 128.63011715907382 -48.46018855266304, 128.63011715907382 -48.147542174903926, 127.46867140594449 -48.147542174903926, 127.46867140594449 -47.83489579714481, 126.59758709109748 -47.83489579714481, 126.59758709109748 -47.522249419385695, 125.72650277625048 -47.522249419385695, 125.72650277625048 -47.20960304162658, 124.56505702312116 -47.20960304162658, 124.56505702312116 -46.89695666386746, 123.69397270827415 -46.89695666386746, 123.69397270827415 -46.58431028610835, 122.82288839342715 -46.58431028610835, 122.82288839342715 -46.271663908349225, 121.95180407858015 -46.271663908349225, 121.95180407858015 -45.95901753059011, 121.08071976373314 -45.95901753059011, 121.08071976373314 -45.646371152830994, 120.20963544888615 -45.646371152830994, 120.20963544888615 -45.33372477507188, 119.33855113403915 -45.33372477507188, 119.33855113403915 -45.02107839731276, 118.75782825747447 -45.02107839731276, 118.75782825747447 -44.70843201955365, 117.88674394262748 -44.70843201955365, 117.88674394262748 -44.39578564179453, 115.5638524363688 -44.39578564179453, 115.5638524363688 -44.08313926403542, 113.24096093011013 -44.08313926403542, 113.24096093011013 -43.7704928862763, 111.49879230041614 -43.7704928862763, 111.49879230041614 -43.45784650851718, 110.04698510900447 -43.45784650851718, 110.04698510900447 -43.14520013075806, 108.59517791759279 -43.14520013075806, 108.59517791759279 -42.83255375299895, 107.43373216446346 -42.83255375299895, 107.43373216446346 -42.51990737523983, 106.27228641133412 -42.51990737523983, 106.27228641133412 -42.20726099748072, 102.20722627538146 -42.20726099748072, 102.20722627538146 -41.8946146197216, 97.85180470114645 -41.8946146197216, 97.85180470114645 -41.581968241962485, 91.46385305893511 -41.581968241962485, 91.46385305893511 -41.8946146197216, 88.56023867611178 -41.8946146197216, 88.56023867611178 -42.20726099748072, 86.52770860813544 -42.20726099748072, 86.52770860813544 -42.51990737523983, 85.07590141672377 -42.51990737523983, 85.07590141672377 -42.83255375299895, 83.6240942253121 -42.83255375299895, 83.6240942253121 -43.14520013075806, 75.20361251512442 -43.14520013075806, 75.20361251512442 -43.45784650851718, 72.59035957058342 -43.45784650851718), + (204.99517542732758 0, 204.99517542732758 -0.6252927555182328, 205.2855368656099 -0.6252927555182328, 205.2855368656099 -0.9379391332773492, 205.57589830389225 -0.9379391332773492, 205.57589830389225 -1.2505855110364656, 205.86625974217458 -1.2505855110364656, 205.86625974217458 -2.188524644313815, 206.1566211804569 -2.188524644313815, 206.1566211804569 -2.5011710220729313, 205.86625974217458 -2.5011710220729313, 205.86625974217458 -3.126463777591164, 205.57589830389225 -3.126463777591164, 205.57589830389225 -3.4391101553502805, 205.2855368656099 -3.4391101553502805, 205.2855368656099 -3.751756533109397, 204.99517542732758 -3.751756533109397, 204.99517542732758 -4.064402910868513, 204.41445255076292 -4.064402910868513, 204.41445255076292 -4.37704928862763, 203.54336823591592 -4.37704928862763, 203.54336823591592 -4.689695666386746, 202.67228392106892 -4.689695666386746, 202.67228392106892 -5.002342044145863, 201.8011996062219 -5.002342044145863, 201.8011996062219 -5.314988421904979, 200.63975385309257 -5.314988421904979, 200.63975385309257 -5.627634799664095, 199.47830809996324 -5.627634799664095, 199.47830809996324 -5.940281177423212, 197.73613947026925 -5.940281177423212, 197.73613947026925 -6.252927555182328, 196.5746937171399 -6.252927555182328, 196.5746937171399 -6.565573932941445, 195.12288652572823 -6.565573932941445, 195.12288652572823 -6.878220310700561, 193.9614407725989 -6.878220310700561, 193.9614407725989 -7.1908666884596775, 192.21927214290488 -7.1908666884596775, 192.21927214290488 -7.503513066218794, 190.76746495149322 -7.503513066218794, 190.76746495149322 -7.81615944397791, 189.02529632179923 -7.81615944397791, 189.02529632179923 -8.128805821737027, 186.99276625382288 -8.128805821737027, 186.99276625382288 -8.441452199496144, 185.2505976241289 -8.441452199496144, 185.2505976241289 -8.75409857725526, 183.5084289944349 -8.75409857725526, 183.5084289944349 -9.066744955014375, 181.76626036474087 -9.066744955014375, 181.76626036474087 -9.379391332773492, 180.02409173504688 -9.379391332773492, 180.02409173504688 -9.69203771053261, 177.99156166707056 -9.69203771053261, 177.99156166707056 -10.004684088291725, 175.66867016081187 -10.004684088291725, 175.66867016081187 -10.31733046605084, 172.76505577798855 -10.31733046605084, 172.76505577798855 -10.629976843809958, 169.28071851860054 -10.629976843809958, 169.28071851860054 -10.942623221569075, 165.5060198209302 -10.942623221569075, 165.5060198209302 -11.25526959932819, 160.2795139318482 -11.25526959932819, 160.2795139318482 -11.567915977087306, 153.60120085135452 -11.567915977087306, 153.60120085135452 -11.880562354846424, 148.08433352399018 -11.880562354846424, 148.08433352399018 -12.193208732605541, 142.85782763490818 -12.193208732605541, 142.85782763490818 -12.505855110364656, 137.63132174582617 -12.505855110364656, 137.63132174582617 -12.818501488123772, 132.11445441846183 -12.818501488123772, 132.11445441846183 -13.13114786588289, 127.17830996766216 -13.13114786588289, 127.17830996766216 -13.443794243642007, 122.24216551686249 -13.443794243642007, 122.24216551686249 -13.756440621401122, 117.30602106606281 -13.756440621401122, 117.30602106606281 -14.069086999160238, 113.24096093011013 -14.069086999160238, 113.24096093011013 -14.381733376919355, 108.59517791759279 -14.381733376919355, 108.59517791759279 -14.694379754678472, 104.2397563433578 -14.694379754678472, 104.2397563433578 -15.007026132437588, 99.88433476912279 -15.007026132437588, 99.88433476912279 -15.319672510196703, 95.81927463317011 -15.319672510196703, 95.81927463317011 -15.63231888795582, 91.75421449721745 -15.63231888795582, 91.75421449721745 -15.944965265714938, 87.68915436126477 -15.944965265714938, 87.68915436126477 -16.257611643474053, 83.6240942253121 -16.257611643474053, 83.6240942253121 -16.57025802123317, 78.97831121279476 -16.57025802123317, 78.97831121279476 -16.882904398992288, 74.04216676199509 -16.882904398992288, 74.04216676199509 -17.195550776751404, 72.59035957058342 -17.195550776751404), + (4.355421574235005 -23.44847833193373, 3.774698697670338 -23.44847833193373, 3.774698697670338 -23.761124709692847, 2.9036143828233367 -23.761124709692847, 2.9036143828233367 -24.073771087451963, 2.0325300679763356 -24.073771087451963, 2.0325300679763356 -24.386417465211082, 1.4518071914116684 -24.386417465211082, 1.4518071914116684 -24.699063842970197, 1.1614457531293347 -24.699063842970197, 1.1614457531293347 -25.011710220729313, 0.8710843148470011 -25.011710220729313, 0.8710843148470011 -25.637002976247544, 1.1614457531293347 -25.637002976247544, 1.1614457531293347 -25.949649354006663, 1.7421686296940022 -25.949649354006663, 1.7421686296940022 -26.26229573176578, 2.3228915062586695 -26.26229573176578, 2.3228915062586695 -26.574942109524894, 3.774698697670338 -26.574942109524894, 3.774698697670338 -26.887588487284013, 4.355421574235005 -26.887588487284013), + (72.29999813230108 -17.195550776751404, 69.10602231119542 -17.195550776751404, 69.10602231119542 -17.50819715451052, 64.46023929867808 -17.50819715451052, 64.46023929867808 -17.820843532269635, 60.10481772444307 -17.820843532269635, 60.10481772444307 -18.13348991002875, 56.330119026772735 -18.13348991002875, 56.330119026772735 -18.44613628778787, 52.265058890820065 -18.44613628778787, 52.265058890820065 -18.758782665546985, 48.199998754867394 -18.758782665546985, 48.199998754867394 -19.0714290433061, 45.29638437204405 -19.0714290433061, 45.29638437204405 -19.38407542106522, 42.102408550938385 -19.38407542106522, 42.102408550938385 -19.696721798824335, 39.19879416811505 -19.696721798824335, 39.19879416811505 -20.00936817658345, 36.004818347009376 -20.00936817658345, 36.004818347009376 -20.322014554342566, 32.81084252590371 -20.322014554342566, 32.81084252590371 -20.63466093210168, 29.616866704798035 -20.63466093210168, 29.616866704798035 -20.9473073098608, 26.7132523219747 -20.9473073098608, 26.7132523219747 -21.259953687619916, 24.680722253998365 -21.259953687619916, 24.680722253998365 -21.57260006537903, 22.93855362430436 -21.57260006537903, 22.93855362430436 -21.88524644313815, 21.486746432892694 -21.88524644313815, 21.486746432892694 -22.197892820897266, 19.74457780319869 -22.197892820897266), + (72.29999813230108 -43.45784650851718, 70.26746806432475 -43.45784650851718, 70.26746806432475 -43.14520013075806, 68.23493799634842 -43.14520013075806, 68.23493799634842 -42.83255375299895, 66.20240792837208 -42.83255375299895, 66.20240792837208 -42.51990737523983, 64.46023929867808 -42.51990737523983, 64.46023929867808 -42.20726099748072, 62.718070668984076 -42.20726099748072, 62.718070668984076 -41.8946146197216, 60.97590203929008 -41.8946146197216, 60.97590203929008 -41.581968241962485, 60.10481772444307 -41.581968241962485, 60.10481772444307 -41.26932186420336, 59.23373340959607 -41.26932186420336, 59.23373340959607 -40.95667548644425, 58.362649094749074 -40.95667548644425, 58.362649094749074 -40.64402910868513, 57.7819262181844 -40.64402910868513, 57.7819262181844 -40.331382730926016, 56.9108419033374 -40.331382730926016, 56.9108419033374 -40.0187363531669, 56.330119026772735 -40.0187363531669, 56.330119026772735 -39.706089975407785, 55.45903471192573 -39.706089975407785, 55.45903471192573 -39.39344359764867, 54.87831183536107 -39.39344359764867, 54.87831183536107 -39.080797219889554, 54.297588958796396 -39.080797219889554, 54.297588958796396 -38.76815084213044, 53.4265046439494 -38.76815084213044, 53.4265046439494 -38.455504464371316, 52.84578176738473 -38.455504464371316, 52.84578176738473 -38.1428580866122, 52.265058890820065 -38.1428580866122, 52.265058890820065 -37.830211708853085, 51.68433601425539 -37.830211708853085, 51.68433601425539 -37.51756533109397, 51.10361313769073 -37.51756533109397, 51.10361313769073 -37.204918953334854, 50.52289026112606 -37.204918953334854, 50.52289026112606 -36.89227257557574, 49.942167384561394 -36.89227257557574, 49.942167384561394 -36.57962619781662, 49.07108306971439 -36.57962619781662, 49.07108306971439 -36.2669798200575, 48.199998754867394 -36.2669798200575, 48.199998754867394 -35.954333442298385, 47.32891444002039 -35.954333442298385, 47.32891444002039 -35.64168706453927, 46.167468686891056 -35.64168706453927, 46.167468686891056 -35.329040686780154, 45.29638437204405 -35.329040686780154, 45.29638437204405 -35.01639430902104, 44.425300057197056 -35.01639430902104, 44.425300057197056 -34.70374793126192, 43.26385430406772 -34.70374793126192, 43.26385430406772 -34.39110155350281, 42.39276998922072 -34.39110155350281, 42.39276998922072 -34.07845517574369, 41.521685674373714 -34.07845517574369, 41.521685674373714 -33.765808797984576, 40.65060135952672 -33.765808797984576, 40.65060135952672 -33.45316242022545, 39.48915560639738 -33.45316242022545, 39.48915560639738 -33.14051604246634, 38.61807129155038 -33.14051604246634, 38.61807129155038 -32.82786966470722, 37.746986976703376 -32.82786966470722, 37.746986976703376 -32.51522328694811, 36.58554122357405 -32.51522328694811, 36.58554122357405 -32.20257690918899, 35.13373403216237 -32.20257690918899, 35.13373403216237 -31.889930531429876, 33.972288279033044 -31.889930531429876, 33.972288279033044 -31.577284153670757, 32.52048108762137 -31.577284153670757, 32.52048108762137 -31.26463777591164, 31.068673896209702 -31.26463777591164, 31.068673896209702 -30.951991398152526, 29.616866704798035 -30.951991398152526, 29.616866704798035 -30.639345020393407, 27.874698075104035 -30.639345020393407, 27.874698075104035 -30.32669864263429, 25.842168007127697 -30.32669864263429, 25.842168007127697 -30.014052264875176, 19.74457780319869 -30.014052264875176))MULTILINESTRING ((297.3301128011097 -18.758782665546985, 296.749389924545 -18.758782665546985, 296.749389924545 -19.0714290433061, 296.16866704798036 -19.0714290433061, 296.16866704798036 -19.38407542106522, 295.5879441714157 -19.38407542106522, 295.5879441714157 -19.696721798824335, 295.00722129485104 -19.696721798824335, 295.00722129485104 -20.00936817658345, 294.42649841828637 -20.00936817658345, 294.42649841828637 -20.322014554342566, 293.8457755417217 -20.322014554342566, 293.8457755417217 -20.63466093210168, 293.26505266515704 -20.63466093210168, 293.26505266515704 -20.9473073098608, 292.6843297885924 -20.9473073098608, 292.6843297885924 -21.259953687619916, 292.10360691202766 -21.259953687619916, 292.10360691202766 -21.57260006537903, 291.522884035463 -21.57260006537903, 291.522884035463 -21.88524644313815, 290.94216115889833 -21.88524644313815, 290.94216115889833 -22.197892820897266, 290.07107684405133 -22.197892820897266, 290.07107684405133 -22.51053919865638, 289.49035396748667 -22.51053919865638, 289.49035396748667 -22.823185576415497, 288.6192696526397 -22.823185576415497, 288.6192696526397 -23.135831954174613, 287.7481853377927 -23.135831954174613, 287.7481853377927 -23.44847833193373, 287.167462461228 -23.44847833193373, 287.167462461228 -23.761124709692847, 286.58673958466335 -23.761124709692847, 286.58673958466335 -24.073771087451963, 286.0060167080987 -24.073771087451963, 286.0060167080987 -24.386417465211082, 285.425293831534 -24.386417465211082, 285.425293831534 -24.699063842970197, 284.84457095496936 -24.699063842970197, 284.84457095496936 -25.011710220729313, 284.2638480784047 -25.011710220729313, 284.2638480784047 -25.32435659848843, 283.68312520184 -25.32435659848843, 283.68312520184 -25.637002976247544, 283.3927637635577 -25.637002976247544, 283.3927637635577 -25.949649354006663, 282.81204088699303 -25.949649354006663, 282.81204088699303 -26.26229573176578, 282.23131801042837 -26.26229573176578, 282.23131801042837 -26.574942109524894, 281.65059513386365 -26.574942109524894, 281.65059513386365 -26.887588487284013, 281.3602336955813 -26.887588487284013, 281.3602336955813 -27.20023486504313, 280.77951081901665 -27.20023486504313, 280.77951081901665 -27.512881242802244, 280.198787942452 -27.512881242802244, 280.198787942452 -27.82552762056136, 279.90842650416965 -27.82552762056136, 279.90842650416965 -28.138173998320475, 279.327703627605 -28.138173998320475, 279.327703627605 -28.450820376079594, 278.7469807510403 -28.450820376079594, 278.7469807510403 -28.76346675383871, 278.456619312758 -28.76346675383871, 278.456619312758 -29.076113131597825, 277.87589643619333 -29.076113131597825, 277.87589643619333 -29.388759509356944, 277.29517355962867 -29.388759509356944, 277.29517355962867 -29.70140588711606, 277.00481212134633 -29.70140588711606, 277.00481212134633 -30.014052264875176, 276.42408924478167 -30.014052264875176, 276.42408924478167 -30.32669864263429, 276.13372780649934 -30.32669864263429, 276.13372780649934 -30.639345020393407, 275.843366368217 -30.639345020393407, 275.843366368217 -30.951991398152526, 275.5530049299347 -30.951991398152526, 275.5530049299347 -31.26463777591164, 275.26264349165234 -31.26463777591164, 275.26264349165234 -31.577284153670757, 274.97228205337 -31.577284153670757, 274.97228205337 -31.889930531429876, 274.6819206150877 -31.889930531429876, 274.6819206150877 -32.20257690918899, 274.39155917680534 -32.20257690918899, 274.39155917680534 -32.82786966470722, 274.101197738523 -32.82786966470722, 274.101197738523 -35.329040686780154, 274.39155917680534 -35.329040686780154, 274.39155917680534 -36.2669798200575, 274.6819206150877 -36.2669798200575, 274.6819206150877 -36.57962619781662, 274.97228205337 -36.57962619781662, 274.97228205337 -37.204918953334854, 275.26264349165234 -37.204918953334854, 275.26264349165234 -37.51756533109397, 275.5530049299347 -37.51756533109397, 275.5530049299347 -37.830211708853085, 275.843366368217 -37.830211708853085, 275.843366368217 -38.1428580866122, 276.13372780649934 -38.1428580866122, 276.13372780649934 -38.455504464371316, 277.00481212134633 -38.455504464371316, 277.00481212134633 -38.76815084213044, 278.16625787447566 -38.76815084213044, 278.16625787447566 -39.080797219889554, 279.6180650658873 -39.080797219889554, 279.6180650658873 -39.39344359764867, 280.4891493807343 -39.39344359764867, 280.4891493807343 -39.706089975407785, 281.65059513386365 -39.706089975407785, 281.65059513386365 -40.0187363531669, 282.81204088699303 -40.0187363531669, 282.81204088699303 -40.331382730926016, 283.68312520184 -40.331382730926016, 283.68312520184 -40.64402910868513, 284.84457095496936 -40.64402910868513, 284.84457095496936 -40.95667548644425, 286.296378146381 -40.95667548644425, 286.296378146381 -41.26932186420336, 287.45782389951034 -41.26932186420336, 287.45782389951034 -41.581968241962485, 287.7481853377927 -41.581968241962485, 287.7481853377927 -41.26932186420336, 288.32890821435734 -41.26932186420336, 288.32890821435734 -40.95667548644425, 288.909631090922 -40.95667548644425, 288.909631090922 -40.64402910868513, 289.19999252920434 -40.64402910868513, 289.19999252920434 -40.331382730926016, 289.780715405769 -40.331382730926016, 289.780715405769 -40.0187363531669, 290.36143828233367 -40.0187363531669, 290.36143828233367 -39.706089975407785, 290.94216115889833 -39.706089975407785, 290.94216115889833 -39.39344359764867, 291.522884035463 -39.39344359764867, 291.522884035463 -39.080797219889554, 292.10360691202766 -39.080797219889554, 292.10360691202766 -38.76815084213044, 292.6843297885924 -38.76815084213044, 292.6843297885924 -38.455504464371316, 293.26505266515704 -38.455504464371316, 293.26505266515704 -38.1428580866122, 293.8457755417217 -38.1428580866122, 293.8457755417217 -37.830211708853085, 294.42649841828637 -37.830211708853085, 294.42649841828637 -37.51756533109397, 295.29758273313337 -37.51756533109397, 295.29758273313337 -37.204918953334854, 295.87830560969803 -37.204918953334854, 295.87830560969803 -36.89227257557574, 296.749389924545 -36.89227257557574, 296.749389924545 -36.57962619781662, 297.3301128011097 -36.57962619781662))MULTILINESTRING ((72.29999813230108 -100.67213363843548, 68.81566087291309 -100.67213363843548, 68.81566087291309 -100.35948726067637, 64.16987786039574 -100.35948726067637, 64.16987786039574 -100.04684088291725, 60.97590203929008 -100.04684088291725, 60.97590203929008 -99.73419450515813, 58.653010533031406 -99.73419450515813, 58.653010533031406 -99.42154812739902, 56.9108419033374 -99.42154812739902, 56.9108419033374 -99.1089017496399, 55.45903471192573 -99.1089017496399, 55.45903471192573 -98.79625537188079, 54.007227520514064 -98.79625537188079, 54.007227520514064 -98.48360899412167, 52.84578176738473 -98.48360899412167, 52.84578176738473 -98.17096261636256, 51.68433601425539 -98.17096261636256, 51.68433601425539 -97.85831623860344, 50.52289026112606 -97.85831623860344, 50.52289026112606 -97.54566986084433, 49.65180594627906 -97.54566986084433, 49.65180594627906 -97.2330234830852, 49.07108306971439 -97.2330234830852, 49.07108306971439 -96.92037710532608, 48.490360193149726 -96.92037710532608, 48.490360193149726 -96.60773072756697, 47.61927587830272 -96.60773072756697, 47.61927587830272 -96.29508434980785, 47.03855300173806 -96.29508434980785, 47.03855300173806 -95.98243797204874, 46.45783012517339 -95.98243797204874, 46.45783012517339 -95.66979159428962, 45.87710724860872 -95.66979159428962, 45.87710724860872 -95.35714521653051, 45.29638437204405 -95.35714521653051, 45.29638437204405 -95.04449883877139, 45.00602293376172 -95.04449883877139, 45.00602293376172 -94.73185246101227, 44.425300057197056 -94.73185246101227, 44.425300057197056 -94.41920608325316, 43.844577180632385 -94.41920608325316, 43.844577180632385 -94.10655970549404, 43.26385430406772 -94.10655970549404, 43.26385430406772 -93.79391332773493, 42.68313142750305 -93.79391332773493, 42.68313142750305 -93.4812669499758, 42.102408550938385 -93.4812669499758, 42.102408550938385 -93.1686205722167, 41.521685674373714 -93.1686205722167, 41.521685674373714 -92.85597419445757, 40.94096279780905 -92.85597419445757, 40.94096279780905 -92.54332781669845, 40.36023992124438 -92.54332781669845, 40.36023992124438 -92.23068143893934, 40.06987848296205 -92.23068143893934, 40.06987848296205 -91.91803506118022, 39.48915560639738 -91.91803506118022, 39.48915560639738 -91.60538868342111, 38.90843272983271 -91.60538868342111, 38.90843272983271 -91.29274230566199, 38.32770985326805 -91.29274230566199, 38.32770985326805 -90.98009592790288, 37.16626410013871 -90.98009592790288, 37.16626410013871 -90.66744955014376, 35.714456908727044 -90.66744955014376, 35.714456908727044 -90.35480317238465, 34.26264971731538 -90.35480317238465, 34.26264971731538 -90.04215679462553, 32.52048108762137 -90.04215679462553, 32.52048108762137 -89.7295104168664, 30.48795101964504 -89.7295104168664, 30.48795101964504 -89.4168640391073, 28.165059513386367 -89.4168640391073, 28.165059513386367 -89.10421766134817, 26.422890883692364 -89.10421766134817, 26.422890883692364 -89.4168640391073, 25.26144513056303 -89.4168640391073, 25.26144513056303 -89.7295104168664, 24.39036081571603 -89.7295104168664, 24.39036081571603 -90.04215679462553, 23.228915062586694 -90.04215679462553, 23.228915062586694 -90.35480317238465, 22.357830747739694 -90.35480317238465, 22.357830747739694 -90.66744955014376, 21.19638499461036 -90.66744955014376, 21.19638499461036 -90.98009592790288, 20.32530067976336 -90.98009592790288, 20.32530067976336 -91.29274230566199, 19.74457780319869 -91.29274230566199), + (47.61927587830272 -150.69555407989412, 47.61927587830272 -150.382907702135, 47.32891444002039 -150.382907702135, 47.32891444002039 -149.75761494661677, 47.03855300173806 -149.75761494661677, 47.03855300173806 -149.13232219109852, 46.74819156345572 -149.13232219109852, 46.74819156345572 -148.5070294355803, 46.45783012517339 -148.5070294355803, 46.45783012517339 -147.88173668006206, 46.167468686891056 -147.88173668006206, 46.167468686891056 -147.56909030230295, 45.87710724860872 -147.56909030230295, 45.87710724860872 -146.9437975467847, 45.58674581032639 -146.9437975467847, 45.58674581032639 -146.6311511690256, 45.29638437204405 -146.6311511690256, 45.29638437204405 -146.3185047912665, 45.00602293376172 -146.3185047912665, 45.00602293376172 -145.69321203574825, 44.71566149547939 -145.69321203574825, 44.71566149547939 -145.38056565798914, 44.425300057197056 -145.38056565798914, 44.425300057197056 -145.06791928023, 44.13493861891472 -145.06791928023, 44.13493861891472 -144.7552729024709, 43.844577180632385 -144.7552729024709, 43.844577180632385 -144.44262652471178, 43.55421574235005 -144.44262652471178, 43.55421574235005 -144.12998014695268, 43.26385430406772 -144.12998014695268, 43.26385430406772 -143.81733376919354, 42.68313142750305 -143.81733376919354, 42.68313142750305 -143.50468739143443, 42.39276998922072 -143.50468739143443, 42.39276998922072 -143.19204101367532, 41.81204711265605 -143.19204101367532, 41.81204711265605 -142.8793946359162, 41.521685674373714 -142.8793946359162, 41.521685674373714 -142.56674825815708, 40.94096279780905 -142.56674825815708, 40.94096279780905 -142.25410188039797, 40.06987848296205 -142.25410188039797, 40.06987848296205 -141.94145550263886, 39.48915560639738 -141.94145550263886, 39.48915560639738 -141.62880912487972, 38.61807129155038 -141.62880912487972, 38.61807129155038 -141.31616274712061, 38.32770985326805 -141.31616274712061, 38.32770985326805 -141.62880912487972, 38.037348414985715 -141.62880912487972, 38.037348414985715 -142.56674825815708, 37.746986976703376 -142.56674825815708, 37.746986976703376 -143.81733376919354, 37.456625538421044 -143.81733376919354, 37.456625538421044 -145.06791928023, 37.16626410013871 -145.06791928023, 37.16626410013871 -146.6311511690256, 36.87590266185638 -146.6311511690256, 36.87590266185638 -147.88173668006206, 36.58554122357405 -147.88173668006206, 36.58554122357405 -149.75761494661677, 36.29517978529171 -149.75761494661677, 36.29517978529171 -151.32084683541234, 36.004818347009376 -151.32084683541234, 36.004818347009376 -152.88407872420794), + (297.3301128011097 -85.35246112823879, 296.16866704798036 -85.35246112823879, 296.16866704798036 -85.6651075059979, 295.00722129485104 -85.6651075059979, 295.00722129485104 -85.97775388375702, 293.5554141034394 -85.97775388375702, 293.5554141034394 -86.29040026151613, 292.39396835031005 -86.29040026151613, 292.39396835031005 -86.60304663927525, 291.23252259718066 -86.60304663927525, 291.23252259718066 -86.91569301703436, 289.780715405769 -86.91569301703436, 289.780715405769 -87.22833939479348, 288.32890821435734 -87.22833939479348, 288.32890821435734 -87.5409857725526, 286.8771010229457 -87.5409857725526, 286.8771010229457 -87.85363215031171, 284.84457095496936 -87.85363215031171, 284.84457095496936 -88.16627852807083, 283.10240232527536 -88.16627852807083, 283.10240232527536 -88.47892490582994, 281.3602336955813 -88.47892490582994, 281.3602336955813 -88.79157128358906, 279.90842650416965 -88.79157128358906, 279.90842650416965 -89.10421766134817, 278.456619312758 -89.10421766134817, 278.456619312758 -89.4168640391073, 277.29517355962867 -89.4168640391073, 277.29517355962867 -89.7295104168664, 275.5530049299347 -89.7295104168664, 275.5530049299347 -89.4168640391073, 274.39155917680534 -89.4168640391073, 274.39155917680534 -89.10421766134817, 273.230113423676 -89.10421766134817, 273.230113423676 -88.79157128358906, 272.0686676705467 -88.79157128358906, 272.0686676705467 -88.47892490582994, 270.9072219174173 -88.47892490582994, 270.9072219174173 -88.16627852807083, 269.45541472600564 -88.16627852807083, 269.45541472600564 -87.85363215031171, 268.003607534594 -87.85363215031171, 268.003607534594 -87.5409857725526, 266.5518003431823 -87.5409857725526, 266.5518003431823 -87.22833939479348, 265.09999315177066 -87.22833939479348, 265.09999315177066 -86.91569301703436, 263.93854739864133 -86.91569301703436, 263.93854739864133 -86.60304663927525, 262.777101645512 -86.60304663927525, 262.777101645512 -86.29040026151613, 261.906017330665 -86.29040026151613, 261.906017330665 -85.97775388375702, 260.7445715775356 -85.97775388375702, 260.7445715775356 -85.6651075059979, 259.8734872626886 -85.6651075059979, 259.8734872626886 -85.35246112823879, 258.7120415095593 -85.35246112823879, 258.7120415095593 -85.03981475047966, 257.8409571947123 -85.03981475047966, 257.8409571947123 -84.72716837272054, 256.679511441583 -84.72716837272054, 256.679511441583 -84.41452199496143, 255.80842712673598 -84.41452199496143, 255.80842712673598 -84.10187561720231, 254.64698137360665 -84.10187561720231, 254.64698137360665 -83.7892292394432, 253.19517418219496 -83.7892292394432, 253.19517418219496 -84.10187561720231, 252.32408986734796 -84.10187561720231, 252.32408986734796 -84.41452199496143, 251.7433669907833 -84.41452199496143, 251.7433669907833 -84.72716837272054, 251.16264411421864 -84.72716837272054, 251.16264411421864 -85.03981475047966, 250.29155979937164 -85.03981475047966, 250.29155979937164 -85.35246112823879, 249.71083692280698 -85.35246112823879, 249.71083692280698 -85.6651075059979, 248.83975260795998 -85.6651075059979, 248.83975260795998 -85.97775388375702, 247.67830685483062 -85.97775388375702, 247.67830685483062 -86.29040026151613, 246.22649966341896 -86.29040026151613, 246.22649966341896 -86.60304663927525, 243.3228852805956 -86.60304663927525, 243.3228852805956 -86.29040026151613, 242.16143952746629 -86.29040026151613, 242.16143952746629 -85.97775388375702, 241.87107808918395 -85.97775388375702, 241.87107808918395 -85.6651075059979, 241.58071665090162 -85.6651075059979, 241.58071665090162 -85.35246112823879, 240.99999377433696 -85.35246112823879, 240.99999377433696 -85.03981475047966, 240.70963233605463 -85.03981475047966, 240.70963233605463 -84.72716837272054, 240.12890945948996 -84.72716837272054, 240.12890945948996 -84.41452199496143, 239.83854802120763 -84.41452199496143, 239.83854802120763 -84.10187561720231, 239.25782514464296 -84.10187561720231, 239.25782514464296 -83.7892292394432, 238.6771022680783 -83.7892292394432, 238.6771022680783 -83.47658286168408, 238.38674082979597 -83.47658286168408, 238.38674082979597 -83.16393648392497, 237.80601795323128 -83.16393648392497, 237.80601795323128 -82.85129010616585, 237.2252950766666 -82.85129010616585, 237.2252950766666 -82.53864372840673, 236.64457220010195 -82.53864372840673, 236.64457220010195 -82.22599735064762, 236.06384932353728 -82.22599735064762, 236.06384932353728 -81.9133509728885, 235.1927650086903 -81.9133509728885, 235.1927650086903 -81.60070459512939, 234.61204213212562 -81.60070459512939, 234.61204213212562 -81.28805821737026, 233.74095781727863 -81.28805821737026, 233.74095781727863 -80.97541183961116, 232.8698735024316 -80.97541183961116, 232.8698735024316 -80.66276546185203, 231.9987891875846 -80.66276546185203, 231.9987891875846 -80.35011908409292, 231.1277048727376 -80.35011908409292, 231.1277048727376 -80.0374727063338, 229.96625911960828 -80.0374727063338, 229.96625911960828 -79.72482632857468, 228.80481336647895 -79.72482632857468, 228.80481336647895 -79.41217995081557, 227.35300617506726 -79.41217995081557, 227.35300617506726 -79.09953357305645, 226.19156042193794 -79.09953357305645, 226.19156042193794 -78.78688719529734, 224.73975323052628 -78.78688719529734, 224.73975323052628 -78.47424081753822, 223.28794603911462 -78.47424081753822, 223.28794603911462 -78.16159443977911, 221.5457774094206 -78.16159443977911, 221.5457774094206 -77.84894806201999, 220.09397021800893 -77.84894806201999, 220.09397021800893 -77.53630168426088, 219.51324734144427 -77.53630168426088, 219.51324734144427 -77.84894806201999, 218.64216302659727 -77.84894806201999, 218.64216302659727 -78.16159443977911, 217.77107871175025 -78.16159443977911, 217.77107871175025 -78.47424081753822, 217.19035583518558 -78.47424081753822, 217.19035583518558 -78.78688719529734, 216.89999439690325 -78.78688719529734, 216.89999439690325 -79.09953357305645, 216.3192715203386 -79.09953357305645, 216.3192715203386 -79.41217995081557, 216.02891008205626 -79.41217995081557, 216.02891008205626 -79.72482632857468, 215.4481872054916 -79.72482632857468, 215.4481872054916 -80.0374727063338, 215.15782576720926 -80.0374727063338), + (4.355421574235005 -101.92271914947194, 4.065060135952671 -101.92271914947194, 4.065060135952671 -102.23536552723107, 3.774698697670338 -102.23536552723107, 3.774698697670338 -102.8606582827493, 3.4843372593880044 -102.8606582827493, 3.4843372593880044 -103.17330466050842, 3.1939758211056706 -103.17330466050842, 3.1939758211056706 -103.48595103826753, 2.9036143828233367 -103.48595103826753, 2.9036143828233367 -104.11124379378576, 2.6132529445410033 -104.11124379378576, 2.6132529445410033 -104.42389017154488, 2.3228915062586695 -104.42389017154488, 2.3228915062586695 -104.73653654930399, 2.0325300679763356 -104.73653654930399, 2.0325300679763356 -105.36182930482224, 1.7421686296940022 -105.36182930482224, 1.7421686296940022 -105.67447568258135, 1.4518071914116684 -105.67447568258135, 1.4518071914116684 -105.98712206034047, 1.1614457531293347 -105.98712206034047, 1.1614457531293347 -106.6124148158587, 0.8710843148470011 -106.6124148158587, 0.8710843148470011 -106.92506119361781, 0.5807228765646674 -106.92506119361781, 0.5807228765646674 -107.55035394913605, 0.2903614382823337 -107.55035394913605, 0.2903614382823337 -107.86300032689516, 0 -107.86300032689516), + (193.38071789603424 -82.22599735064762, 192.21927214290488 -82.22599735064762, 192.21927214290488 -82.53864372840673, 191.05782638977556 -82.53864372840673, 191.05782638977556 -82.85129010616585, 189.6060191983639 -82.85129010616585, 189.6060191983639 -83.16393648392497, 188.15421200695224 -83.16393648392497, 188.15421200695224 -83.47658286168408, 186.70240481554055 -83.47658286168408, 186.70240481554055 -83.7892292394432, 184.96023618584655 -83.7892292394432, 184.96023618584655 -84.10187561720231, 182.92770611787023 -84.10187561720231, 182.92770611787023 -84.41452199496143, 181.47589892645854 -84.41452199496143, 181.47589892645854 -84.72716837272054, 180.3144531733292 -84.72716837272054, 180.3144531733292 -85.03981475047966, 179.15300742019988 -85.03981475047966, 179.15300742019988 -85.35246112823879, 178.2819231053529 -85.35246112823879, 178.2819231053529 -85.6651075059979, 177.70120022878822 -85.6651075059979, 177.70120022878822 -85.97775388375702, 177.12047735222356 -85.97775388375702, 177.12047735222356 -86.29040026151613, 176.53975447565887 -86.29040026151613, 176.53975447565887 -86.60304663927525, 175.9590315990942 -86.60304663927525, 175.9590315990942 -86.91569301703436, 175.37830872252954 -86.91569301703436, 175.37830872252954 -87.22833939479348, 174.79758584596487 -87.22833939479348, 174.79758584596487 -87.5409857725526, 173.92650153111788 -87.5409857725526, 173.92650153111788 -87.85363215031171, 172.47469433970622 -87.85363215031171, 172.47469433970622 -88.16627852807083, 171.31324858657686 -88.16627852807083, 171.31324858657686 -88.47892490582994, 170.15180283344753 -88.47892490582994, 170.15180283344753 -88.79157128358906, 168.69999564203587 -88.79157128358906, 168.69999564203587 -89.10421766134817, 167.53854988890654 -89.10421766134817, 167.53854988890654 -89.4168640391073, 166.08674269749486 -89.4168640391073, 166.08674269749486 -89.7295104168664, 164.6349355060832 -89.7295104168664, 164.6349355060832 -90.04215679462553, 163.18312831467154 -90.04215679462553, 163.18312831467154 -90.35480317238465, 162.0216825615422 -90.35480317238465, 162.0216825615422 -90.66744955014376, 160.56987537013052 -90.66744955014376, 160.56987537013052 -90.98009592790288, 159.4084296170012 -90.98009592790288, 159.4084296170012 -91.29274230566199, 157.95662242558953 -91.29274230566199, 157.95662242558953 -91.60538868342111, 156.50481523417787 -91.60538868342111, 156.50481523417787 -91.91803506118022, 155.05300804276618 -91.91803506118022, 155.05300804276618 -92.23068143893934, 153.3108394130722 -92.23068143893934, 153.3108394130722 -92.54332781669845, 151.5686707833782 -92.54332781669845, 151.5686707833782 -92.85597419445757, 150.40722503024884 -92.85597419445757, 150.40722503024884 -93.1686205722167, 149.2457792771195 -93.1686205722167, 149.2457792771195 -93.4812669499758, 148.08433352399018 -93.4812669499758, 148.08433352399018 -93.79391332773493, 146.92288777086085 -93.79391332773493, 146.92288777086085 -94.10655970549404, 145.7614420177315 -94.10655970549404, 145.7614420177315 -94.41920608325316, 144.30963482631984 -94.41920608325316, 144.30963482631984 -94.73185246101227, 143.1481890731905 -94.73185246101227, 143.1481890731905 -95.04449883877139, 141.69638188177885 -95.04449883877139, 141.69638188177885 -95.35714521653051, 140.24457469036716 -95.35714521653051, 140.24457469036716 -95.66979159428962, 138.7927674989555 -95.66979159428962, 138.7927674989555 -95.98243797204874, 137.34096030754384 -95.98243797204874, 137.34096030754384 -96.29508434980785, 135.59879167784982 -96.29508434980785, 135.59879167784982 -96.60773072756697, 133.85662304815583 -96.60773072756697, 133.85662304815583 -96.92037710532608, 132.11445441846183 -96.92037710532608, 132.11445441846183 -97.2330234830852, 129.50120147392082 -97.2330234830852, 129.50120147392082 -97.54566986084433, 128.04939428250916 -97.54566986084433, 128.04939428250916 -97.2330234830852, 125.72650277625048 -97.2330234830852, 125.72650277625048 -96.92037710532608, 123.69397270827415 -96.92037710532608, 123.69397270827415 -96.60773072756697, 121.95180407858015 -96.60773072756697, 121.95180407858015 -96.29508434980785, 120.20963544888615 -96.29508434980785, 120.20963544888615 -95.98243797204874, 118.46746681919214 -95.98243797204874, 118.46746681919214 -95.66979159428962, 110.62770798556913 -95.66979159428962, 110.62770798556913 -95.35714521653051, 106.56264784961647 -95.35714521653051, 106.56264784961647 -95.04449883877139, 105.98192497305179 -95.04449883877139, 105.98192497305179 -95.35714521653051, 101.6265033988168 -95.35714521653051, 101.6265033988168 -95.66979159428962, 95.81927463317011 -95.66979159428962, 95.81927463317011 -95.35714521653051, 94.65782888004078 -95.35714521653051, 94.65782888004078 -95.66979159428962, 93.20602168862911 -95.66979159428962, 93.20602168862911 -95.98243797204874, 91.46385305893511 -95.98243797204874, 91.46385305893511 -96.29508434980785, 90.01204586752344 -96.29508434980785, 90.01204586752344 -96.60773072756697, 88.26987723782943 -96.60773072756697, 88.26987723782943 -96.92037710532608, 86.52770860813544 -96.92037710532608, 86.52770860813544 -97.2330234830852, 85.07590141672377 -97.2330234830852, 85.07590141672377 -97.54566986084433, 83.33373278702977 -97.54566986084433, 83.33373278702977 -97.85831623860344, 81.59156415733577 -97.85831623860344, 81.59156415733577 -98.17096261636256, 79.84939552764176 -98.17096261636256, 79.84939552764176 -98.48360899412167, 78.68794977451243 -98.48360899412167, 78.68794977451243 -98.79625537188079, 77.23614258310076 -98.79625537188079, 77.23614258310076 -99.1089017496399, 76.07469682997143 -99.1089017496399, 76.07469682997143 -99.42154812739902, 75.20361251512442 -99.42154812739902, 75.20361251512442 -99.73419450515813, 74.33252820027742 -99.73419450515813, 74.33252820027742 -100.04684088291725, 73.46144388543043 -100.04684088291725, 73.46144388543043 -100.35948726067637, 72.59035957058342 -100.35948726067637), + (112.0795151769808 -211.3489513651627, 112.0795151769808 -209.16042672084887, 111.78915373869847 -209.16042672084887, 111.78915373869847 -206.34660932101684, 111.49879230041614 -206.34660932101684, 111.49879230041614 -203.8454382989439, 111.2084308621338 -203.8454382989439, 111.2084308621338 -201.65691365463007, 110.91806942385146 -201.65691365463007, 110.91806942385146 -199.7810353880754, 110.62770798556913 -199.7810353880754, 110.62770798556913 -197.9051571215207, 110.3373465472868 -197.9051571215207, 110.3373465472868 -196.34192523272512, 110.04698510900447 -196.34192523272512, 110.04698510900447 -194.77869334392952, 109.75662367072213 -194.77869334392952, 109.75662367072213 -193.21546145513395, 109.4662622324398 -193.21546145513395, 109.4662622324398 -191.96487594409749, 109.17590079415747 -191.96487594409749, 109.17590079415747 -190.71429043306102, 108.88553935587512 -190.71429043306102, 108.88553935587512 -189.46370492202453, 108.59517791759279 -189.46370492202453, 108.59517791759279 -188.5257657887472, 108.30481647931046 -188.5257657887472, 108.30481647931046 -187.27518027771072, 108.01445504102813 -187.27518027771072, 108.01445504102813 -186.3372411444334, 107.7240936027458 -186.3372411444334, 107.7240936027458 -185.39930201115604, 107.43373216446346 -185.39930201115604, 107.43373216446346 -184.46136287787868, 107.14337072618113 -184.46136287787868, 107.14337072618113 -183.52342374460133, 106.8530092878988 -183.52342374460133, 106.8530092878988 -182.8981309890831, 106.56264784961647 -182.8981309890831, 106.56264784961647 -181.96019185580576, 106.27228641133412 -181.96019185580576, 106.27228641133412 -181.64754547804662, 101.33614196053446 -181.64754547804662, 101.33614196053446 -181.33489910028752, 99.59397333084046 -181.33489910028752, 99.59397333084046 -181.0222527225284, 98.72288901599346 -181.0222527225284, 98.72288901599346 -180.7096063447693, 98.14216613942878 -180.7096063447693, 98.14216613942878 -180.39695996701016, 97.56144326286412 -180.39695996701016, 97.56144326286412 -180.08431358925105, 97.27108182458178 -180.08431358925105, 97.27108182458178 -179.77166721149194, 96.69035894801712 -179.77166721149194, 96.69035894801712 -179.4590208337328, 96.39999750973479 -179.4590208337328, 96.39999750973479 -179.1463744559737, 96.10963607145244 -179.1463744559737, 96.10963607145244 -178.8337280782146, 95.81927463317011 -178.8337280782146, 95.81927463317011 -178.20843532269635, 95.52891319488778 -178.20843532269635, 95.52891319488778 -177.89578894493724, 95.23855175660545 -177.89578894493724, 95.23855175660545 -177.58314256717813, 94.94819031832311 -177.58314256717813, 94.94819031832311 -176.95784981165988, 94.65782888004078 -176.95784981165988, 94.65782888004078 -176.33255705614167, 94.36746744175845 -176.33255705614167, 94.36746744175845 -175.70726430062342, 94.07710600347612 -175.70726430062342, 94.07710600347612 -175.0819715451052, 93.78674456519379 -175.0819715451052, 93.78674456519379 -174.76932516734607, 93.49638312691144 -174.76932516734607, 93.49638312691144 -174.14403241182785, 93.20602168862911 -174.14403241182785, 93.20602168862911 -173.5187396563096, 92.91566025034678 -173.5187396563096, 92.91566025034678 -172.8934469007914, 92.62529881206444 -172.8934469007914, 92.62529881206444 -172.26815414527314, 92.33493737378211 -172.26815414527314, 92.33493737378211 -171.6428613897549, 92.04457593549978 -171.6428613897549, 92.04457593549978 -171.3302150119958, 91.75421449721745 -171.3302150119958, 91.75421449721745 -170.70492225647757, 91.46385305893511 -170.70492225647757, 91.46385305893511 -170.07962950095933, 91.17349162065278 -170.07962950095933, 91.17349162065278 -169.45433674544108, 90.88313018237044 -169.45433674544108, 90.88313018237044 -169.14169036768197, 90.5927687440881 -169.14169036768197, 90.5927687440881 -168.51639761216376, 90.30240730580577 -168.51639761216376, 90.30240730580577 -167.8911048566455, 90.01204586752344 -167.8911048566455, 90.01204586752344 -167.26581210112727, 89.72168442924111 -167.26581210112727, 89.72168442924111 -166.95316572336816, 89.43132299095878 -166.95316572336816, 89.43132299095878 -166.32787296784994, 89.14096155267644 -166.32787296784994, 89.14096155267644 -165.7025802123317, 88.85060011439411 -165.7025802123317, 88.85060011439411 -165.07728745681345, 88.56023867611178 -165.07728745681345, 88.56023867611178 -164.76464107905434, 88.26987723782943 -164.76464107905434, 88.26987723782943 -164.13934832353613, 87.9795157995471 -164.13934832353613, 87.9795157995471 -163.51405556801788, 87.68915436126477 -163.51405556801788, 87.68915436126477 -163.20140919025877, 87.39879292298244 -163.20140919025877, 87.39879292298244 -162.57611643474053, 87.1084314847001 -162.57611643474053, 87.1084314847001 -161.9508236792223, 86.81807004641777 -161.9508236792223, 86.81807004641777 -161.63817730146317, 86.52770860813544 -161.63817730146317, 86.52770860813544 -161.01288454594496, 86.23734716985311 -161.01288454594496, 86.23734716985311 -160.70023816818585, 85.94698573157078 -160.70023816818585, 85.94698573157078 -160.0749454126676, 85.65662429328843 -160.0749454126676, 85.65662429328843 -159.44965265714936, 85.3662628550061 -159.44965265714936, 85.3662628550061 -159.13700627939025, 85.07590141672377 -159.13700627939025, 85.07590141672377 -158.51171352387203, 84.78553997844143 -158.51171352387203, 84.78553997844143 -158.1990671461129, 84.4951785401591 -158.1990671461129, 84.4951785401591 -157.57377439059468, 84.20481710187677 -157.57377439059468, 84.20481710187677 -157.26112801283554, 83.91445566359444 -157.26112801283554, 83.91445566359444 -156.63583525731732, 83.6240942253121 -156.63583525731732, 83.6240942253121 -156.32318887955822, 83.33373278702977 -156.32318887955822, 83.33373278702977 -156.01054250179908, 83.04337134874743 -156.01054250179908, 83.04337134874743 -155.69789612403997, 82.46264847218276 -155.69789612403997, 82.46264847218276 -155.38524974628086, 82.17228703390043 -155.38524974628086, 82.17228703390043 -155.07260336852175, 81.59156415733577 -155.07260336852175, 81.59156415733577 -154.75995699076262, 81.30120271905344 -154.75995699076262, 81.30120271905344 -154.4473106130035, 81.0108412807711 -154.4473106130035, 81.0108412807711 -154.1346642352444, 80.43011840420642 -154.1346642352444, 80.43011840420642 -153.82201785748526, 80.1397569659241 -153.82201785748526, 80.1397569659241 -153.50937147972616, 79.55903408935943 -153.50937147972616, 79.55903408935943 -153.19672510196705, 79.2686726510771 -153.19672510196705, 79.2686726510771 -152.88407872420794, 78.68794977451243 -152.88407872420794, 78.68794977451243 -152.5714323464488, 78.10722689794775 -152.5714323464488, 78.10722689794775 -152.2587859686897, 77.81686545966542 -152.2587859686897, 77.81686545966542 -151.94613959093058, 77.23614258310076 -151.94613959093058, 77.23614258310076 -151.63349321317145, 76.94578114481843 -151.63349321317145, 76.94578114481843 -151.32084683541234, 76.36505826825376 -151.32084683541234, 76.36505826825376 -151.00820045765323, 75.7843353916891 -151.00820045765323, 75.7843353916891 -150.69555407989412, 75.49397395340675 -150.69555407989412, 75.49397395340675 -150.382907702135, 74.91325107684209 -150.382907702135, 74.91325107684209 -150.07026132437588, 74.62288963855976 -150.07026132437588, 74.62288963855976 -149.75761494661677, 74.04216676199509 -149.75761494661677, 74.04216676199509 -149.44496856885763, 73.46144388543043 -149.44496856885763, 73.46144388543043 -149.13232219109852, 73.1710824471481 -149.13232219109852, 73.1710824471481 -148.81967581333942, 72.59035957058342 -148.81967581333942), + (198.02650090855158 -81.9133509728885, 197.73613947026925 -81.9133509728885, 197.73613947026925 -81.60070459512939, 197.44577803198692 -81.60070459512939, 197.44577803198692 -81.28805821737026, 197.15541659370456 -81.28805821737026, 197.15541659370456 -80.97541183961116, 196.28433227885756 -80.97541183961116, 196.28433227885756 -81.28805821737026, 195.41324796401057 -81.28805821737026, 195.41324796401057 -81.60070459512939), + (72.29999813230108 -148.19438305782117, 72.00963669401875 -148.19438305782117, 72.00963669401875 -147.88173668006206, 71.71927525573642 -147.88173668006206, 71.71927525573642 -147.56909030230295, 71.42891381745409 -147.56909030230295, 71.42891381745409 -147.25644392454382, 71.13855237917176 -147.25644392454382, 71.13855237917176 -146.9437975467847, 70.84819094088942 -146.9437975467847, 70.84819094088942 -146.6311511690256, 70.55782950260709 -146.6311511690256, 70.55782950260709 -146.3185047912665, 70.26746806432475 -146.3185047912665, 70.26746806432475 -146.00585841350735, 69.97710662604241 -146.00585841350735, 69.97710662604241 -145.69321203574825, 69.68674518776008 -145.69321203574825, 69.68674518776008 -145.38056565798914, 69.39638374947775 -145.38056565798914, 69.39638374947775 -145.06791928023, 69.10602231119542 -145.06791928023, 69.10602231119542 -144.7552729024709, 68.81566087291309 -144.7552729024709, 68.81566087291309 -144.12998014695268, 68.52529943463075 -144.12998014695268, 68.52529943463075 -143.81733376919354, 68.23493799634842 -143.81733376919354, 68.23493799634842 -143.50468739143443, 67.94457655806609 -143.50468739143443, 67.94457655806609 -143.19204101367532, 67.65421511978374 -143.19204101367532, 67.65421511978374 -142.8793946359162, 67.36385368150141 -142.8793946359162, 67.36385368150141 -142.56674825815708, 67.07349224321908 -142.56674825815708, 67.07349224321908 -142.25410188039797, 66.78313080493675 -142.25410188039797, 66.78313080493675 -141.94145550263886, 66.49276936665441 -141.94145550263886, 66.49276936665441 -141.31616274712061, 66.20240792837208 -141.31616274712061, 66.20240792837208 -141.0035163693615, 65.91204649008975 -141.0035163693615, 65.91204649008975 -140.6908699916024, 65.62168505180742 -140.6908699916024, 65.62168505180742 -140.37822361384326, 65.33132361352507 -140.37822361384326, 65.33132361352507 -140.06557723608415, 65.04096217524274 -140.06557723608415, 65.04096217524274 -139.75293085832504, 64.75060073696041 -139.75293085832504, 64.75060073696041 -139.4402844805659, 64.46023929867808 -139.4402844805659, 64.46023929867808 -138.8149917250477, 64.16987786039574 -138.8149917250477, 64.16987786039574 -138.50234534728858, 63.87951642211341 -138.50234534728858, 63.87951642211341 -138.18969896952945, 63.58915498383108 -138.18969896952945, 63.58915498383108 -137.87705259177034, 63.29879354554874 -137.87705259177034, 63.29879354554874 -137.56440621401123, 63.00843210726641 -137.56440621401123, 63.00843210726641 -137.2517598362521, 62.718070668984076 -137.2517598362521, 62.718070668984076 -136.93911345849298, 62.427709230701744 -136.93911345849298, 62.427709230701744 -136.62646708073387, 62.137347792419405 -136.62646708073387, 62.137347792419405 -136.00117432521563, 61.84698635413707 -136.00117432521563, 61.84698635413707 -135.68852794745652, 61.55662491585474 -135.68852794745652, 61.55662491585474 -135.3758815696974, 61.26626347757241 -135.3758815696974, 61.26626347757241 -135.0632351919383, 60.97590203929008 -135.0632351919383, 60.97590203929008 -134.75058881417917, 60.10481772444307 -134.75058881417917, 60.10481772444307 -134.43794243642006, 58.653010533031406 -134.43794243642006, 58.653010533031406 -134.12529605866095, 57.20120334161974 -134.12529605866095, 57.20120334161974 -134.43794243642006, 55.74939615020807 -134.43794243642006, 55.74939615020807 -134.75058881417917, 55.1686732736434 -134.75058881417917, 55.1686732736434 -135.0632351919383, 54.587950397078735 -135.0632351919383, 54.587950397078735 -135.3758815696974, 54.297588958796396 -135.3758815696974, 54.297588958796396 -135.68852794745652, 54.007227520514064 -135.68852794745652, 54.007227520514064 -136.00117432521563, 53.71686608223173 -136.00117432521563, 53.71686608223173 -136.31382070297477, 53.4265046439494 -136.31382070297477, 53.4265046439494 -136.62646708073387, 53.13614320566706 -136.62646708073387, 53.13614320566706 -136.93911345849298, 52.84578176738473 -136.93911345849298, 52.84578176738473 -137.56440621401123, 52.5554203291024 -137.56440621401123, 52.5554203291024 -138.18969896952945, 52.265058890820065 -138.18969896952945, 52.265058890820065 -138.8149917250477, 51.97469745253773 -138.8149917250477, 51.97469745253773 -139.4402844805659, 51.68433601425539 -139.4402844805659, 51.68433601425539 -140.37822361384326, 51.39397457597306 -140.37822361384326, 51.39397457597306 -141.31616274712061, 51.10361313769073 -141.31616274712061, 51.10361313769073 -142.56674825815708, 50.8132516994084 -142.56674825815708, 50.8132516994084 -144.12998014695268, 50.52289026112606 -144.12998014695268, 50.52289026112606 -146.3185047912665, 50.232528822843726 -146.3185047912665, 50.232528822843726 -148.81967581333942, 49.942167384561394 -148.81967581333942, 49.942167384561394 -151.00820045765323), + (95.23855175660545 -236.04801520813288, 95.23855175660545 -227.29391663087762, 94.94819031832311 -227.29391663087762, 94.94819031832311 -215.1007078982721, 94.65782888004078 -215.1007078982721, 94.65782888004078 -220.10304994241795, 94.36746744175845 -220.10304994241795, 94.36746744175845 -225.1053919865638, 94.07710600347612 -225.1053919865638, 94.07710600347612 -229.79508765295057, 93.78674456519379 -229.79508765295057, 93.78674456519379 -231.67096591950525))MULTILINESTRING ((4.355421574235005 -38.76815084213044, 2.3228915062586695 -38.76815084213044, 2.3228915062586695 -39.080797219889554, 0 -39.080797219889554), + (130.08192435048548 0, 130.08192435048548 -0.3126463777591164, 130.66264722705014 -0.3126463777591164, 130.66264722705014 -0.6252927555182328, 130.9530086653325 -0.6252927555182328, 130.9530086653325 -0.9379391332773492, 131.24337010361484 -0.9379391332773492, 131.24337010361484 -1.2505855110364656, 131.53373154189717 -1.2505855110364656, 131.53373154189717 -1.563231888795582, 131.8240929801795 -1.563231888795582, 131.8240929801795 -2.8138173998320477, 131.53373154189717 -2.8138173998320477, 131.53373154189717 -3.126463777591164, 131.24337010361484 -3.126463777591164, 131.24337010361484 -3.4391101553502805, 130.9530086653325 -3.4391101553502805, 130.9530086653325 -3.751756533109397, 130.08192435048548 -3.751756533109397, 130.08192435048548 -4.064402910868513, 129.21084003563848 -4.064402910868513, 129.21084003563848 -4.37704928862763, 128.3397557207915 -4.37704928862763, 128.3397557207915 -4.689695666386746, 127.17830996766216 -4.689695666386746, 127.17830996766216 -5.002342044145863, 125.72650277625048 -5.002342044145863, 125.72650277625048 -5.314988421904979, 123.98433414655648 -5.314988421904979, 123.98433414655648 -5.627634799664095, 121.95180407858015 -5.627634799664095, 121.95180407858015 -5.940281177423212, 119.62891257232148 -5.940281177423212, 119.62891257232148 -6.252927555182328, 117.30602106606281 -6.252927555182328, 117.30602106606281 -6.565573932941445, 114.98312955980414 -6.565573932941445, 114.98312955980414 -6.878220310700561, 112.66023805354547 -6.878220310700561, 112.66023805354547 -7.1908666884596775, 109.75662367072213 -7.1908666884596775, 109.75662367072213 -7.503513066218794, 106.8530092878988 -7.503513066218794, 106.8530092878988 -7.81615944397791, 104.2397563433578 -7.81615944397791, 104.2397563433578 -8.128805821737027, 101.6265033988168 -8.128805821737027, 101.6265033988168 -8.441452199496144, 98.72288901599346 -8.441452199496144, 98.72288901599346 -8.75409857725526, 95.81927463317011 -8.75409857725526, 95.81927463317011 -9.066744955014375, 93.20602168862911 -9.066744955014375, 93.20602168862911 -9.379391332773492, 90.30240730580577 -9.379391332773492, 90.30240730580577 -9.69203771053261, 87.39879292298244 -9.69203771053261, 87.39879292298244 -10.004684088291725, 84.4951785401591 -10.004684088291725, 84.4951785401591 -10.31733046605084, 81.0108412807711 -10.31733046605084, 81.0108412807711 -10.629976843809958, 77.23614258310076 -10.629976843809958, 77.23614258310076 -10.942623221569075, 73.46144388543043 -10.942623221569075, 73.46144388543043 -11.25526959932819, 72.59035957058342 -11.25526959932819), + (72.29999813230108 -11.25526959932819, 69.10602231119542 -11.25526959932819, 69.10602231119542 -11.567915977087306, 64.46023929867808 -11.567915977087306, 64.46023929867808 -11.880562354846424, 59.5240948478784 -11.880562354846424, 59.5240948478784 -12.193208732605541, 54.87831183536107 -12.193208732605541, 54.87831183536107 -12.505855110364656, 49.36144450799673 -12.505855110364656, 49.36144450799673 -12.818501488123772, 45.00602293376172 -12.818501488123772, 45.00602293376172 -13.13114786588289, 40.65060135952672 -13.13114786588289, 40.65060135952672 -13.443794243642007, 36.004818347009376 -13.443794243642007, 36.004818347009376 -13.756440621401122, 31.359035334492038 -13.756440621401122, 31.359035334492038 -14.069086999160238, 26.422890883692364 -14.069086999160238, 26.422890883692364 -14.381733376919355, 23.228915062586694 -14.381733376919355, 23.228915062586694 -14.694379754678472, 20.32530067976336 -14.694379754678472, 20.32530067976336 -15.007026132437588, 19.74457780319869 -15.007026132437588), + (4.355421574235005 -15.319672510196703, 4.065060135952671 -15.319672510196703, 4.065060135952671 -15.63231888795582, 0 -15.63231888795582), + (297.3301128011097 -58.464872640954766, 297.03975136282736 -58.464872640954766, 297.03975136282736 -58.77751901871389, 296.16866704798036 -58.77751901871389, 296.16866704798036 -59.090165396473004, 295.29758273313337 -59.090165396473004, 295.29758273313337 -59.40281177423212, 294.42649841828637 -59.40281177423212, 294.42649841828637 -59.715458151991236, 293.5554141034394 -59.715458151991236, 293.5554141034394 -60.02810452975035, 292.6843297885924 -60.02810452975035, 292.6843297885924 -60.34075090750947, 291.8132454737453 -60.34075090750947, 291.8132454737453 -60.65339728526858, 290.94216115889833 -60.65339728526858, 290.94216115889833 -60.9660436630277, 290.07107684405133 -60.9660436630277, 290.07107684405133 -61.27869004078681, 289.19999252920434 -61.27869004078681, 289.19999252920434 -61.591336418545936, 288.32890821435734 -61.591336418545936, 288.32890821435734 -61.90398279630505, 278.456619312758 -61.90398279630505, 278.456619312758 -62.21662917406417, 275.843366368217 -62.21662917406417, 275.843366368217 -61.90398279630505, 274.6819206150877 -61.90398279630505, 274.6819206150877 -61.591336418545936, 273.52047486195835 -61.591336418545936, 273.52047486195835 -61.27869004078681, 272.0686676705467 -61.27869004078681, 272.0686676705467 -60.9660436630277, 270.9072219174173 -60.9660436630277, 270.9072219174173 -60.65339728526858, 269.45541472600564 -60.65339728526858, 269.45541472600564 -60.34075090750947, 268.003607534594 -60.34075090750947, 268.003607534594 -60.02810452975035, 266.5518003431823 -60.02810452975035, 266.5518003431823 -59.715458151991236, 265.09999315177066 -59.715458151991236, 265.09999315177066 -59.40281177423212, 263.06746308379434 -59.40281177423212, 263.06746308379434 -59.090165396473004, 260.7445715775356 -59.090165396473004, 260.7445715775356 -58.77751901871389, 258.42168007127697 -58.77751901871389, 258.42168007127697 -58.464872640954766, 256.38915000330064 -58.464872640954766, 256.38915000330064 -58.15222626319565, 254.06625849704199 -58.15222626319565, 254.06625849704199 -57.839579885436535, 250.29155979937164 -57.839579885436535, 250.29155979937164 -57.52693350767742, 245.93613822513663 -57.52693350767742, 245.93613822513663 -57.214287129918304, 241.87107808918395 -57.214287129918304, 241.87107808918395 -56.90164075215919, 238.0963793915136 -56.90164075215919, 238.0963793915136 -56.58899437440007, 234.90240357040796 -56.58899437440007, 234.90240357040796 -56.27634799664095, 231.70842774930227 -56.27634799664095, 231.70842774930227 -55.963701618881835, 230.2566205578906 -55.963701618881835, 230.2566205578906 -55.65105524112272, 229.09517480476129 -55.65105524112272, 229.09517480476129 -55.338408863363604, 227.93372905163193 -55.338408863363604, 227.93372905163193 -55.02576248560449, 226.7722832985026 -55.02576248560449, 226.7722832985026 -54.71311610784537, 225.61083754537327 -54.71311610784537, 225.61083754537327 -54.40046973008626, 224.44939179224394 -54.40046973008626, 224.44939179224394 -54.08782335232714, 223.28794603911462 -54.08782335232714, 223.28794603911462 -53.775176974568026, 221.83613884770293 -53.775176974568026, 221.83613884770293 -53.462530596808904, 220.38433165629127 -53.462530596808904, 220.38433165629127 -53.14988421904979, 218.9325244648796 -53.14988421904979, 218.9325244648796 -52.83723784129067, 217.19035583518558 -52.83723784129067, 217.19035583518558 -52.52459146353156, 214.86746432892693 -52.52459146353156, 214.86746432892693 -52.21194508577244, 211.67348850782125 -52.21194508577244, 211.67348850782125 -51.899298708013326, 201.8011996062219 -51.899298708013326, 201.8011996062219 -51.58665233025421, 198.60722378511625 -51.58665233025421, 198.60722378511625 -51.27400595249509, 195.99397084057523 -51.27400595249509, 195.99397084057523 -51.58665233025421, 194.54216364916357 -51.58665233025421, 194.54216364916357 -51.899298708013326, 193.0903564577519 -51.899298708013326, 193.0903564577519 -52.21194508577244, 191.63854926634022 -52.21194508577244, 191.63854926634022 -52.52459146353156, 190.4771035132109 -52.52459146353156, 190.4771035132109 -52.83723784129067, 189.02529632179923 -52.83723784129067, 189.02529632179923 -53.14988421904979, 187.8638505686699 -53.14988421904979, 187.8638505686699 -53.462530596808904, 186.41204337725821 -53.462530596808904, 186.41204337725821 -53.775176974568026, 185.2505976241289 -53.775176974568026, 185.2505976241289 -54.08782335232714, 184.3795133092819 -54.08782335232714, 184.3795133092819 -54.40046973008626, 183.21806755615256 -54.40046973008626, 183.21806755615256 -54.71311610784537, 182.05662180302323 -54.71311610784537, 182.05662180302323 -55.02576248560449, 180.89517604989388 -55.02576248560449, 180.89517604989388 -55.338408863363604, 179.73373029676455 -55.338408863363604, 179.73373029676455 -55.65105524112272, 178.86264598191755 -55.65105524112272, 178.86264598191755 -55.963701618881835, 177.70120022878822 -55.963701618881835, 177.70120022878822 -56.27634799664095, 176.53975447565887 -56.27634799664095, 176.53975447565887 -56.58899437440007, 175.37830872252954 -56.58899437440007, 175.37830872252954 -56.90164075215919, 174.2168629694002 -56.90164075215919, 174.2168629694002 -57.214287129918304, 169.8614413951652 -57.214287129918304, 169.8614413951652 -57.52693350767742, 165.21565838264786 -57.52693350767742, 165.21565838264786 -57.839579885436535, 158.82770674043653 -57.839579885436535, 158.82770674043653 -58.15222626319565, 139.08312893723783 -58.15222626319565, 139.08312893723783 -57.839579885436535, 136.1795145544145 -57.839579885436535, 136.1795145544145 -57.52693350767742, 134.14698448643816 -57.52693350767742, 134.14698448643816 -57.214287129918304, 132.11445441846183 -57.214287129918304, 132.11445441846183 -56.90164075215919, 130.66264722705014 -56.90164075215919, 130.66264722705014 -56.58899437440007, 129.21084003563848 -56.58899437440007, 129.21084003563848 -56.27634799664095, 128.04939428250916 -56.27634799664095, 128.04939428250916 -55.963701618881835, 126.59758709109748 -55.963701618881835, 126.59758709109748 -55.65105524112272, 125.43614133796815 -55.65105524112272, 125.43614133796815 -55.338408863363604, 124.56505702312116 -55.338408863363604, 124.56505702312116 -55.02576248560449, 123.40361126999181 -55.02576248560449, 123.40361126999181 -54.71311610784537, 122.24216551686249 -54.71311610784537, 122.24216551686249 -54.40046973008626, 121.37108120201547 -54.40046973008626, 121.37108120201547 -54.08782335232714, 120.20963544888615 -54.08782335232714, 120.20963544888615 -53.775176974568026, 119.33855113403915 -53.775176974568026, 119.33855113403915 -53.462530596808904, 118.17710538090981 -53.462530596808904, 118.17710538090981 -53.14988421904979, 116.4349367512158 -53.14988421904979, 116.4349367512158 -52.83723784129067, 113.8216838066748 -52.83723784129067, 113.8216838066748 -52.52459146353156, 111.49879230041614 -52.52459146353156, 111.49879230041614 -52.21194508577244, 109.75662367072213 -52.21194508577244, 109.75662367072213 -51.899298708013326, 108.01445504102813 -51.899298708013326, 108.01445504102813 -51.58665233025421, 106.8530092878988 -51.58665233025421, 106.8530092878988 -51.27400595249509, 102.78794915194612 -51.27400595249509, 102.78794915194612 -50.96135957473597, 96.69035894801712 -50.96135957473597, 96.69035894801712 -50.64871319697686, 93.20602168862911 -50.64871319697686, 93.20602168862911 -50.96135957473597, 89.72168442924111 -50.96135957473597, 89.72168442924111 -51.27400595249509, 87.39879292298244 -51.27400595249509, 87.39879292298244 -51.58665233025421, 85.3662628550061 -51.58665233025421, 85.3662628550061 -51.899298708013326, 83.91445566359444 -51.899298708013326, 83.91445566359444 -52.21194508577244, 76.07469682997143 -52.21194508577244, 76.07469682997143 -52.52459146353156, 72.59035957058342 -52.52459146353156), + (72.29999813230108 -52.52459146353156, 69.68674518776008 -52.52459146353156, 69.68674518776008 -52.21194508577244, 67.36385368150141 -52.21194508577244, 67.36385368150141 -51.899298708013326, 65.04096217524274 -51.899298708013326, 65.04096217524274 -51.58665233025421, 62.718070668984076 -51.58665233025421, 62.718070668984076 -51.27400595249509, 60.68554060100774 -51.27400595249509, 60.68554060100774 -50.96135957473597, 59.5240948478784 -50.96135957473597, 59.5240948478784 -50.64871319697686, 58.653010533031406 -50.64871319697686, 58.653010533031406 -50.33606681921774, 57.7819262181844 -50.33606681921774, 57.7819262181844 -50.023420441458626, 56.9108419033374 -50.023420441458626, 56.9108419033374 -49.71077406369951, 56.0397575884904 -49.71077406369951, 56.0397575884904 -49.398127685940395, 55.1686732736434 -49.398127685940395, 55.1686732736434 -49.08548130818128, 54.297588958796396 -49.08548130818128, 54.297588958796396 -48.772834930422164, 53.71686608223173 -48.772834930422164, 53.71686608223173 -48.46018855266304, 52.84578176738473 -48.46018855266304, 52.84578176738473 -48.147542174903926, 52.265058890820065 -48.147542174903926, 52.265058890820065 -47.83489579714481, 51.39397457597306 -47.83489579714481, 51.39397457597306 -47.522249419385695, 50.8132516994084 -47.522249419385695, 50.8132516994084 -47.20960304162658, 50.232528822843726 -47.20960304162658, 50.232528822843726 -46.89695666386746, 49.36144450799673 -46.89695666386746, 49.36144450799673 -46.58431028610835, 48.490360193149726 -46.58431028610835, 48.490360193149726 -46.271663908349225, 47.32891444002039 -46.271663908349225, 47.32891444002039 -45.95901753059011, 46.167468686891056 -45.95901753059011, 46.167468686891056 -45.646371152830994, 45.00602293376172 -45.646371152830994, 45.00602293376172 -45.33372477507188, 44.13493861891472 -45.33372477507188, 44.13493861891472 -45.02107839731276, 42.97349286578539 -45.02107839731276, 42.97349286578539 -44.70843201955365, 42.102408550938385 -44.70843201955365, 42.102408550938385 -44.39578564179453, 40.94096279780905 -44.39578564179453, 40.94096279780905 -44.08313926403542, 40.06987848296205 -44.08313926403542, 40.06987848296205 -43.7704928862763, 38.90843272983271 -43.7704928862763, 38.90843272983271 -43.45784650851718, 38.037348414985715 -43.45784650851718, 38.037348414985715 -43.14520013075806, 36.87590266185638 -43.14520013075806, 36.87590266185638 -42.83255375299895, 35.42409547044471 -42.83255375299895, 35.42409547044471 -42.51990737523983, 34.26264971731538 -42.51990737523983, 34.26264971731538 -42.20726099748072, 32.81084252590371 -42.20726099748072, 32.81084252590371 -41.8946146197216, 31.068673896209702 -41.8946146197216, 31.068673896209702 -41.581968241962485, 29.616866704798035 -41.581968241962485, 29.616866704798035 -41.26932186420336, 27.5843366368217 -41.26932186420336, 27.5843366368217 -40.95667548644425, 23.51927650086903 -40.95667548644425, 23.51927650086903 -41.26932186420336, 21.19638499461036 -41.26932186420336, 21.19638499461036 -41.581968241962485, 20.034939241481023 -41.581968241962485, 20.034939241481023 -41.8946146197216, 19.74457780319869 -41.8946146197216))MULTILINESTRING ((297.3301128011097 -76.59836255098352, 297.03975136282736 -76.59836255098352, 297.03975136282736 -76.91100892874263, 295.87830560969803 -76.91100892874263, 295.87830560969803 -77.22365530650175, 295.00722129485104 -77.22365530650175, 295.00722129485104 -77.53630168426088, 293.8457755417217 -77.53630168426088, 293.8457755417217 -77.84894806201999, 292.9746912268747 -77.84894806201999, 292.9746912268747 -78.16159443977911, 291.8132454737453 -78.16159443977911, 291.8132454737453 -78.47424081753822, 290.94216115889833 -78.47424081753822, 290.94216115889833 -78.78688719529734, 289.780715405769 -78.78688719529734, 289.780715405769 -79.09953357305645, 288.6192696526397 -79.09953357305645, 288.6192696526397 -79.41217995081557, 287.45782389951034 -79.41217995081557, 287.45782389951034 -79.72482632857468, 284.2638480784047 -79.72482632857468, 284.2638480784047 -80.0374727063338, 281.069872257299 -80.0374727063338, 281.069872257299 -80.35011908409292, 278.7469807510403 -80.35011908409292, 278.7469807510403 -80.66276546185203, 277.00481212134633 -80.66276546185203, 277.00481212134633 -80.97541183961116, 276.13372780649934 -80.97541183961116, 276.13372780649934 -80.66276546185203, 274.6819206150877 -80.66276546185203, 274.6819206150877 -80.35011908409292, 273.52047486195835 -80.35011908409292, 273.52047486195835 -80.0374727063338, 272.359029108829 -80.0374727063338, 272.359029108829 -79.72482632857468, 270.9072219174173 -79.72482632857468, 270.9072219174173 -79.41217995081557, 269.45541472600564 -79.41217995081557, 269.45541472600564 -79.09953357305645, 268.003607534594 -79.09953357305645, 268.003607534594 -78.78688719529734, 266.5518003431823 -78.78688719529734, 266.5518003431823 -78.47424081753822, 264.80963171348833 -78.47424081753822, 264.80963171348833 -78.16159443977911, 263.648185960359 -78.16159443977911, 263.648185960359 -77.84894806201999, 262.4867402072297 -77.84894806201999, 262.4867402072297 -77.53630168426088, 261.03493301581796 -77.53630168426088, 261.03493301581796 -77.22365530650175, 259.8734872626886 -77.22365530650175, 259.8734872626886 -76.91100892874263, 258.7120415095593 -76.91100892874263, 258.7120415095593 -76.59836255098352, 257.26023431814764 -76.59836255098352, 257.26023431814764 -76.2857161732244, 256.0987885650183 -76.2857161732244, 256.0987885650183 -75.97306979546529, 254.64698137360665 -75.97306979546529, 254.64698137360665 -75.66042341770617, 251.45300555250097 -75.66042341770617, 251.45300555250097 -75.97306979546529, 245.35541534857197 -75.97306979546529, 245.35541534857197 -75.66042341770617, 242.74216240403095 -75.66042341770617, 242.74216240403095 -75.34777703994706, 241.58071665090162 -75.34777703994706, 241.58071665090162 -75.03513066218794, 240.4192708977723 -75.03513066218794, 240.4192708977723 -74.72248428442882, 239.25782514464296 -74.72248428442882, 239.25782514464296 -74.40983790666971, 237.80601795323128 -74.40983790666971, 237.80601795323128 -74.09719152891059, 236.35421076181962 -74.09719152891059, 236.35421076181962 -73.78454515115148, 234.90240357040796 -73.78454515115148, 234.90240357040796 -73.47189877339235, 233.4505963789963 -73.47189877339235, 233.4505963789963 -73.15925239563325, 231.70842774930227 -73.15925239563325, 231.70842774930227 -72.84660601787412, 230.2566205578906 -72.84660601787412, 230.2566205578906 -72.533959640115, 228.80481336647895 -72.533959640115, 228.80481336647895 -72.22131326235589, 227.6433676133496 -72.22131326235589, 227.6433676133496 -71.90866688459677, 226.19156042193794 -71.90866688459677, 226.19156042193794 -71.59602050683766, 224.44939179224394 -71.59602050683766, 224.44939179224394 -71.28337412907854, 222.99758460083228 -71.28337412907854, 222.99758460083228 -70.97072775131943, 221.25541597113826 -70.97072775131943, 221.25541597113826 -70.65808137356031, 219.22288590316194 -70.65808137356031, 219.22288590316194 -70.3454349958012, 197.15541659370456 -70.3454349958012, 197.15541659370456 -70.03278861804208, 196.86505515542223 -70.03278861804208, 196.86505515542223 -70.3454349958012, 195.7036094022929 -70.3454349958012, 195.7036094022929 -70.65808137356031, 194.54216364916357 -70.65808137356031, 194.54216364916357 -70.97072775131943, 193.38071789603424 -70.97072775131943, 193.38071789603424 -71.28337412907854, 192.21927214290488 -71.28337412907854, 192.21927214290488 -71.59602050683766, 191.3481878280579 -71.59602050683766, 191.3481878280579 -71.90866688459677, 190.18674207492856 -71.90866688459677, 190.18674207492856 -72.22131326235589, 189.02529632179923 -72.22131326235589, 189.02529632179923 -72.533959640115, 188.15421200695224 -72.533959640115, 188.15421200695224 -72.84660601787412, 186.99276625382288 -72.84660601787412, 186.99276625382288 -73.15925239563325, 186.12168193897588 -73.15925239563325, 186.12168193897588 -73.47189877339235, 184.96023618584655 -73.47189877339235, 184.96023618584655 -73.78454515115148, 184.08915187099956 -73.78454515115148, 184.08915187099956 -74.09719152891059, 183.21806755615256 -74.09719152891059, 183.21806755615256 -74.40983790666971, 182.34698324130557 -74.40983790666971, 182.34698324130557 -74.72248428442882, 181.47589892645854 -74.72248428442882, 181.47589892645854 -75.03513066218794, 180.60481461161154 -75.03513066218794, 180.60481461161154 -75.34777703994706, 179.73373029676455 -75.34777703994706, 179.73373029676455 -75.66042341770617, 178.86264598191755 -75.66042341770617, 178.86264598191755 -75.97306979546529, 177.99156166707056 -75.97306979546529, 177.99156166707056 -76.2857161732244, 177.12047735222356 -76.2857161732244, 177.12047735222356 -76.59836255098352, 176.24939303737654 -76.59836255098352, 176.24939303737654 -76.91100892874263, 175.66867016081187 -76.91100892874263, 175.66867016081187 -77.22365530650175, 174.79758584596487 -77.22365530650175, 174.79758584596487 -77.53630168426088, 173.34577865455321 -77.53630168426088, 173.34577865455321 -77.84894806201999, 171.6036100248592 -77.84894806201999, 171.6036100248592 -78.16159443977911, 169.57107995688287 -78.16159443977911, 169.57107995688287 -78.47424081753822, 167.53854988890654 -78.47424081753822, 167.53854988890654 -78.78688719529734, 165.5060198209302 -78.78688719529734, 165.5060198209302 -79.09953357305645, 163.18312831467154 -79.09953357305645, 163.18312831467154 -79.41217995081557, 160.86023680841285 -79.41217995081557, 160.86023680841285 -79.72482632857468, 158.5373453021542 -79.72482632857468, 158.5373453021542 -80.0374727063338, 155.92409235761318 -80.0374727063338, 155.92409235761318 -80.35011908409292, 153.02047797478986 -80.35011908409292, 153.02047797478986 -80.66276546185203, 150.1168635919665 -80.66276546185203, 150.1168635919665 -80.97541183961116, 147.50361064742552 -80.97541183961116, 147.50361064742552 -81.28805821737026, 144.30963482631984 -81.28805821737026, 144.30963482631984 -81.60070459512939, 140.24457469036716 -81.60070459512939, 140.24457469036716 -81.9133509728885, 133.5662616098735 -81.9133509728885, 133.5662616098735 -81.60070459512939, 129.50120147392082 -81.60070459512939, 129.50120147392082 -81.28805821737026, 127.46867140594449 -81.28805821737026, 127.46867140594449 -80.97541183961116, 125.72650277625048 -80.97541183961116, 125.72650277625048 -80.66276546185203, 124.27469558483881 -80.66276546185203, 124.27469558483881 -80.35011908409292, 122.82288839342715 -80.35011908409292, 122.82288839342715 -80.0374727063338, 121.37108120201547 -80.0374727063338, 121.37108120201547 -79.72482632857468, 119.91927401060381 -79.72482632857468, 119.91927401060381 -79.41217995081557, 118.46746681919214 -79.41217995081557, 118.46746681919214 -79.09953357305645, 116.14457531293347 -79.09953357305645, 116.14457531293347 -78.78688719529734, 112.36987661526314 -78.78688719529734, 112.36987661526314 -78.47424081753822, 109.4662622324398 -78.47424081753822, 109.4662622324398 -78.16159443977911, 107.14337072618113 -78.16159443977911, 107.14337072618113 -77.84894806201999, 91.75421449721745 -77.84894806201999, 91.75421449721745 -78.16159443977911, 88.26987723782943 -78.16159443977911, 88.26987723782943 -78.47424081753822, 85.65662429328843 -78.47424081753822, 85.65662429328843 -78.78688719529734, 80.43011840420642 -78.78688719529734, 80.43011840420642 -79.09953357305645, 74.62288963855976 -79.09953357305645, 74.62288963855976 -79.41217995081557, 72.59035957058342 -79.41217995081557), + (4.355421574235005 -76.91100892874263, 3.774698697670338 -76.91100892874263, 3.774698697670338 -77.22365530650175, 3.4843372593880044 -77.22365530650175, 3.4843372593880044 -77.53630168426088, 2.9036143828233367 -77.53630168426088, 2.9036143828233367 -77.84894806201999, 2.3228915062586695 -77.84894806201999, 2.3228915062586695 -78.16159443977911, 2.0325300679763356 -78.16159443977911, 2.0325300679763356 -78.47424081753822, 1.4518071914116684 -78.47424081753822, 1.4518071914116684 -78.78688719529734, 1.1614457531293347 -78.78688719529734, 1.1614457531293347 -79.09953357305645, 0.5807228765646674 -79.09953357305645, 0.5807228765646674 -79.41217995081557, 0.2903614382823337 -79.41217995081557, 0.2903614382823337 -79.72482632857468, 0 -79.72482632857468), + (72.29999813230108 -79.41217995081557, 70.26746806432475 -79.41217995081557, 70.26746806432475 -79.09953357305645, 67.65421511978374 -79.09953357305645, 67.65421511978374 -78.78688719529734, 65.04096217524274 -78.78688719529734, 65.04096217524274 -78.47424081753822, 62.427709230701744 -78.47424081753822, 62.427709230701744 -78.16159443977911, 60.395179162725405 -78.16159443977911, 60.395179162725405 -77.84894806201999, 58.94337197131374 -77.84894806201999, 58.94337197131374 -77.53630168426088, 57.7819262181844 -77.53630168426088, 57.7819262181844 -77.22365530650175, 56.330119026772735 -77.22365530650175, 56.330119026772735 -76.91100892874263, 55.1686732736434 -76.91100892874263, 55.1686732736434 -76.59836255098352, 54.007227520514064 -76.59836255098352, 54.007227520514064 -76.2857161732244, 53.13614320566706 -76.2857161732244, 53.13614320566706 -75.97306979546529, 51.97469745253773 -75.97306979546529, 51.97469745253773 -75.66042341770617, 51.10361313769073 -75.66042341770617, 51.10361313769073 -75.34777703994706, 50.232528822843726 -75.34777703994706, 50.232528822843726 -75.03513066218794, 49.07108306971439 -75.03513066218794, 49.07108306971439 -74.72248428442882, 47.61927587830272 -74.72248428442882, 47.61927587830272 -74.40983790666971, 46.45783012517339 -74.40983790666971, 46.45783012517339 -74.09719152891059, 45.00602293376172 -74.09719152891059, 45.00602293376172 -73.78454515115148, 43.55421574235005 -73.78454515115148, 43.55421574235005 -73.47189877339235, 42.39276998922072 -73.47189877339235, 42.39276998922072 -73.15925239563325, 41.23132423609138 -73.15925239563325, 41.23132423609138 -72.84660601787412, 40.06987848296205 -72.84660601787412, 40.06987848296205 -72.533959640115, 38.90843272983271 -72.533959640115, 38.90843272983271 -72.22131326235589, 37.16626410013871 -72.22131326235589, 37.16626410013871 -71.90866688459677, 35.13373403216237 -71.90866688459677, 35.13373403216237 -71.59602050683766, 33.10120396418604 -71.59602050683766, 33.10120396418604 -71.28337412907854, 30.48795101964504 -71.28337412907854, 30.48795101964504 -70.97072775131943, 25.26144513056303 -70.97072775131943, 25.26144513056303 -71.28337412907854, 23.80963793915136 -71.28337412907854, 23.80963793915136 -71.59602050683766, 22.648192186022026 -71.59602050683766, 22.648192186022026 -71.90866688459677, 21.777107871175026 -71.90866688459677, 21.777107871175026 -72.22131326235589, 20.61566211804569 -72.22131326235589, 20.61566211804569 -72.533959640115, 19.74457780319869 -72.533959640115))MULTILINESTRING ((297.3301128011097 -98.17096261636256, 295.00722129485104 -98.17096261636256, 295.00722129485104 -98.48360899412167, 290.07107684405133 -98.48360899412167, 290.07107684405133 -98.79625537188079, 287.167462461228 -98.79625537188079, 287.167462461228 -99.1089017496399, 286.0060167080987 -99.1089017496399, 286.0060167080987 -99.42154812739902, 284.84457095496936 -99.42154812739902, 284.84457095496936 -99.73419450515813, 283.97348664012236 -99.73419450515813, 283.97348664012236 -100.04684088291725, 282.81204088699303 -100.04684088291725, 282.81204088699303 -100.35948726067637, 281.940956572146 -100.35948726067637, 281.940956572146 -100.67213363843548, 281.069872257299 -100.67213363843548, 281.069872257299 -100.9847800161946, 280.198787942452 -100.9847800161946, 280.198787942452 -101.29742639395371, 279.327703627605 -101.29742639395371, 279.327703627605 -101.61007277171284, 278.456619312758 -101.61007277171284, 278.456619312758 -101.92271914947194, 277.87589643619333 -101.92271914947194, 277.87589643619333 -102.23536552723107, 277.00481212134633 -102.23536552723107, 277.00481212134633 -102.54801190499018, 275.5530049299347 -102.54801190499018, 275.5530049299347 -102.23536552723107, 274.39155917680534 -102.23536552723107, 274.39155917680534 -101.92271914947194, 272.9397519853937 -101.92271914947194, 272.9397519853937 -101.61007277171284, 271.77830623226436 -101.61007277171284, 271.77830623226436 -101.29742639395371, 270.32649904085264 -101.29742639395371, 270.32649904085264 -100.9847800161946, 268.874691849441 -100.9847800161946, 268.874691849441 -100.67213363843548, 267.4228846580293 -100.67213363843548, 267.4228846580293 -100.35948726067637, 265.6807160283353 -100.35948726067637, 265.6807160283353 -100.04684088291725, 264.22890883692367 -100.04684088291725, 264.22890883692367 -99.73419450515813, 263.35782452207667 -99.73419450515813, 263.35782452207667 -99.42154812739902, 262.4867402072297 -99.42154812739902, 262.4867402072297 -99.1089017496399, 261.6156558923827 -99.1089017496399, 261.6156558923827 -98.79625537188079, 260.7445715775356 -98.79625537188079, 260.7445715775356 -98.48360899412167, 259.8734872626886 -98.48360899412167, 259.8734872626886 -98.17096261636256, 259.00240294784163 -98.17096261636256, 259.00240294784163 -97.85831623860344, 258.13131863299463 -97.85831623860344, 258.13131863299463 -97.54566986084433, 257.26023431814764 -97.54566986084433, 257.26023431814764 -97.2330234830852, 256.38915000330064 -97.2330234830852, 256.38915000330064 -96.92037710532608, 255.80842712673598 -96.92037710532608, 255.80842712673598 -96.60773072756697, 254.93734281188898 -96.60773072756697, 254.93734281188898 -96.29508434980785, 254.06625849704199 -96.29508434980785, 254.06625849704199 -95.98243797204874, 253.4855356204773 -95.98243797204874, 253.4855356204773 -96.60773072756697, 253.19517418219496 -96.60773072756697, 253.19517418219496 -96.92037710532608, 252.90481274391263 -96.92037710532608, 252.90481274391263 -97.54566986084433, 252.6144513056303 -97.54566986084433, 252.6144513056303 -97.85831623860344, 252.32408986734796 -97.85831623860344, 252.32408986734796 -98.48360899412167, 252.03372842906563 -98.48360899412167, 252.03372842906563 -98.79625537188079, 251.7433669907833 -98.79625537188079, 251.7433669907833 -99.42154812739902, 251.45300555250097 -99.42154812739902, 251.45300555250097 -100.04684088291725, 251.16264411421864 -100.04684088291725, 251.16264411421864 -100.35948726067637, 250.8722826759363 -100.35948726067637, 250.8722826759363 -100.9847800161946, 250.58192123765397 -100.9847800161946, 250.58192123765397 -101.61007277171284, 250.29155979937164 -101.61007277171284, 250.29155979937164 -102.23536552723107, 250.0011983610893 -102.23536552723107, 250.0011983610893 -102.54801190499018, 249.71083692280698 -102.54801190499018, 249.71083692280698 -103.17330466050842, 249.42047548452464 -103.17330466050842, 249.42047548452464 -103.79859741602665, 249.1301140462423 -103.79859741602665, 249.1301140462423 -104.42389017154488, 248.83975260795998 -104.42389017154488, 248.83975260795998 -105.04918292706311, 248.54939116967762 -105.04918292706311, 248.54939116967762 -105.67447568258135, 248.2590297313953 -105.67447568258135, 248.2590297313953 -105.98712206034047, 247.96866829311296 -105.98712206034047, 247.96866829311296 -106.6124148158587, 247.67830685483062 -106.6124148158587, 247.67830685483062 -107.23770757137693, 247.3879454165483 -107.23770757137693, 247.3879454165483 -107.86300032689516, 247.09758397826596 -107.86300032689516, 247.09758397826596 -108.48829308241339, 246.80722253998363 -108.48829308241339, 246.80722253998363 -109.11358583793162, 246.5168611017013 -109.11358583793162, 246.5168611017013 -109.73887859344985, 246.22649966341896 -109.73887859344985, 246.22649966341896 -110.3641713489681, 245.93613822513663 -110.3641713489681, 245.93613822513663 -110.98946410448633, 245.6457767868543 -110.98946410448633), + (186.12168193897588 -106.92506119361781, 185.83132050069355 -106.92506119361781, 185.83132050069355 -106.6124148158587, 185.54095906241122 -106.6124148158587, 185.54095906241122 -105.98712206034047, 185.2505976241289 -105.98712206034047, 185.2505976241289 -105.67447568258135, 184.96023618584655 -105.67447568258135, 184.96023618584655 -105.04918292706311, 184.66987474756422 -105.04918292706311, 184.66987474756422 -104.73653654930399, 184.3795133092819 -104.73653654930399, 184.3795133092819 -104.42389017154488, 184.08915187099956 -104.42389017154488, 184.08915187099956 -104.11124379378576, 183.79879043271723 -104.11124379378576, 183.79879043271723 -103.79859741602665, 183.5084289944349 -103.79859741602665, 183.5084289944349 -103.48595103826753, 183.21806755615256 -103.48595103826753, 183.21806755615256 -103.17330466050842, 182.92770611787023 -103.17330466050842, 182.92770611787023 -102.8606582827493, 182.34698324130557 -102.8606582827493, 182.34698324130557 -102.54801190499018, 181.47589892645854 -102.54801190499018, 181.47589892645854 -102.23536552723107, 178.2819231053529 -102.23536552723107, 178.2819231053529 -102.54801190499018, 177.99156166707056 -102.54801190499018, 177.99156166707056 -102.8606582827493, 177.70120022878822 -102.8606582827493, 177.70120022878822 -103.17330466050842, 177.12047735222356 -103.17330466050842, 177.12047735222356 -103.48595103826753, 176.8301159139412 -103.48595103826753, 176.8301159139412 -103.79859741602665, 176.53975447565887 -103.79859741602665, 176.53975447565887 -104.11124379378576, 175.9590315990942 -104.11124379378576, 175.9590315990942 -104.42389017154488, 175.66867016081187 -104.42389017154488, 175.66867016081187 -104.73653654930399, 175.37830872252954 -104.73653654930399, 175.37830872252954 -105.04918292706311, 174.79758584596487 -105.04918292706311, 174.79758584596487 -105.36182930482224, 174.50722440768254 -105.36182930482224, 174.50722440768254 -105.67447568258135, 174.2168629694002 -105.67447568258135, 174.2168629694002 -105.98712206034047, 173.63614009283555 -105.98712206034047, 173.63614009283555 -106.29976843809958, 173.05541721627088 -106.29976843809958, 173.05541721627088 -106.6124148158587, 172.47469433970622 -106.6124148158587, 172.47469433970622 -106.92506119361781, 171.89397146314155 -106.92506119361781, 171.89397146314155 -107.23770757137693, 171.6036100248592 -107.23770757137693, 171.6036100248592 -107.55035394913605, 171.02288714829453 -107.55035394913605, 171.02288714829453 -107.86300032689516, 170.44216427172987 -107.86300032689516, 170.44216427172987 -108.17564670465428, 170.15180283344753 -108.17564670465428, 170.15180283344753 -108.48829308241339, 169.57107995688287 -108.48829308241339, 169.57107995688287 -108.80093946017251, 168.9903570803182 -108.80093946017251, 168.9903570803182 -109.11358583793162, 168.69999564203587 -109.11358583793162, 168.69999564203587 -109.42623221569075, 168.1192727654712 -109.42623221569075, 168.1192727654712 -109.73887859344985, 167.53854988890654 -109.73887859344985, 167.53854988890654 -110.05152497120898, 167.2481884506242 -110.05152497120898, 167.2481884506242 -110.3641713489681, 166.66746557405955 -110.3641713489681, 166.66746557405955 -110.67681772672721, 166.3771041357772 -110.67681772672721, 166.3771041357772 -110.98946410448633, 165.79638125921252 -110.98946410448633, 165.79638125921252 -111.30211048224544, 165.5060198209302 -111.30211048224544, 165.5060198209302 -111.61475686000456, 164.92529694436553 -111.61475686000456, 164.92529694436553 -111.92740323776367, 164.6349355060832 -111.92740323776367, 164.6349355060832 -112.24004961552279, 164.05421262951853 -112.24004961552279, 164.05421262951853 -112.5526959932819, 163.7638511912362 -112.5526959932819, 163.7638511912362 -112.86534237104102, 163.18312831467154 -112.86534237104102, 163.18312831467154 -113.17798874880015, 162.8927668763892 -113.17798874880015, 162.8927668763892 -113.49063512655925, 162.60240543810687 -113.49063512655925, 162.60240543810687 -113.80328150431838, 162.31204399982454 -113.80328150431838, 162.31204399982454 -114.11592788207749, 162.0216825615422 -114.11592788207749, 162.0216825615422 -114.42857425983661, 161.4409596849775 -114.42857425983661, 161.4409596849775 -114.74122063759572, 161.15059824669518 -114.74122063759572, 161.15059824669518 -115.05386701535484, 160.86023680841285 -115.05386701535484, 160.86023680841285 -115.36651339311396, 160.56987537013052 -115.36651339311396, 160.56987537013052 -115.67915977087307, 160.2795139318482 -115.67915977087307, 160.2795139318482 -115.9918061486322, 159.98915249356585 -115.9918061486322, 159.98915249356585 -116.3044525263913, 159.69879105528352 -116.3044525263913, 159.69879105528352 -116.61709890415042, 159.4084296170012 -116.61709890415042, 159.4084296170012 -116.92974528190953, 159.11806817871886 -116.92974528190953, 159.11806817871886 -117.24239165966866, 158.82770674043653 -117.24239165966866, 158.82770674043653 -117.55503803742778, 158.5373453021542 -117.55503803742778, 158.5373453021542 -118.18033079294601, 158.24698386387186 -118.18033079294601, 158.24698386387186 -118.49297717070512, 157.95662242558953 -118.49297717070512, 157.95662242558953 -118.80562354846424, 157.6662609873072 -118.80562354846424, 157.6662609873072 -119.11826992622335, 157.37589954902487 -119.11826992622335, 157.37589954902487 -119.43091630398247, 157.08553811074253 -119.43091630398247, 157.08553811074253 -120.0562090595007, 156.7951766724602 -120.0562090595007, 156.7951766724602 -120.36885543725982, 156.50481523417787 -120.36885543725982, 156.50481523417787 -120.99414819277806, 156.2144537958955 -120.99414819277806, 156.2144537958955 -121.30679457053716, 155.92409235761318 -121.30679457053716, 155.92409235761318 -121.9320873260554, 155.63373091933084 -121.9320873260554, 155.63373091933084 -122.55738008157363, 155.3433694810485 -122.55738008157363, 155.3433694810485 -123.18267283709187, 155.05300804276618 -123.18267283709187, 155.05300804276618 -123.8079655926101, 154.76264660448385 -123.8079655926101, 154.76264660448385 -124.74590472588744, 154.47228516620152 -124.74590472588744, 154.47228516620152 -125.6838438591648, 154.18192372791918 -125.6838438591648, 154.18192372791918 -126.93442937020126, 153.89156228963685 -126.93442937020126, 153.89156228963685 -129.43560039227418, 153.60120085135452 -129.43560039227418, 153.60120085135452 -134.12529605866095, 153.89156228963685 -134.12529605866095, 153.89156228963685 -139.4402844805659, 154.18192372791918 -139.4402844805659, 154.18192372791918 -141.0035163693615), + (239.5481865829253 -103.48595103826753, 239.5481865829253 -103.17330466050842, 239.25782514464296 -103.17330466050842, 239.25782514464296 -102.54801190499018, 238.96746370636063 -102.54801190499018, 238.96746370636063 -101.92271914947194, 238.6771022680783 -101.92271914947194, 238.6771022680783 -101.29742639395371, 238.38674082979597 -101.29742639395371, 238.38674082979597 -100.67213363843548, 238.0963793915136 -100.67213363843548, 238.0963793915136 -100.04684088291725, 237.80601795323128 -100.04684088291725, 237.80601795323128 -99.42154812739902, 237.51565651494894 -99.42154812739902, 237.51565651494894 -98.79625537188079, 237.2252950766666 -98.79625537188079, 237.2252950766666 -98.48360899412167, 236.93493363838428 -98.48360899412167, 236.93493363838428 -97.85831623860344, 236.64457220010195 -97.85831623860344, 236.64457220010195 -97.54566986084433, 236.35421076181962 -97.54566986084433, 236.35421076181962 -96.92037710532608, 236.06384932353728 -96.92037710532608, 236.06384932353728 -96.60773072756697, 235.77348788525495 -96.60773072756697, 235.77348788525495 -96.29508434980785, 235.48312644697262 -96.29508434980785, 235.48312644697262 -95.66979159428962, 235.1927650086903 -95.66979159428962, 235.1927650086903 -95.35714521653051, 234.90240357040796 -95.35714521653051, 234.90240357040796 -95.04449883877139, 234.61204213212562 -95.04449883877139, 234.61204213212562 -94.73185246101227, 234.3216806938433 -94.73185246101227, 234.3216806938433 -94.41920608325316, 234.03131925556096 -94.41920608325316, 234.03131925556096 -94.10655970549404, 233.74095781727863 -94.10655970549404, 233.74095781727863 -93.79391332773493, 233.4505963789963 -93.79391332773493, 233.4505963789963 -93.4812669499758, 233.16023494071393 -93.4812669499758, 233.16023494071393 -93.1686205722167, 232.8698735024316 -93.1686205722167, 232.8698735024316 -92.85597419445757, 232.57951206414927 -92.85597419445757, 232.57951206414927 -92.54332781669845, 232.28915062586694 -92.54332781669845, 232.28915062586694 -92.23068143893934, 231.9987891875846 -92.23068143893934, 231.9987891875846 -91.91803506118022, 231.70842774930227 -91.91803506118022, 231.70842774930227 -91.60538868342111, 231.41806631101994 -91.60538868342111, 231.41806631101994 -91.29274230566199, 230.54698199617295 -91.29274230566199, 230.54698199617295 -90.98009592790288, 229.38553624304362 -90.98009592790288, 229.38553624304362 -90.66744955014376, 228.51445192819662 -90.66744955014376, 228.51445192819662 -90.35480317238465, 227.35300617506726 -90.35480317238465, 227.35300617506726 -90.04215679462553, 226.48192186022027 -90.04215679462553, 226.48192186022027 -89.7295104168664, 225.32047610709094 -89.7295104168664, 225.32047610709094 -89.4168640391073, 224.1590303539616 -89.4168640391073, 224.1590303539616 -89.10421766134817, 222.99758460083228 -89.10421766134817, 222.99758460083228 -88.79157128358906, 221.83613884770293 -88.79157128358906, 221.83613884770293 -88.47892490582994, 220.6746930945736 -88.47892490582994, 220.6746930945736 -88.16627852807083, 219.51324734144427 -88.16627852807083, 219.51324734144427 -88.79157128358906, 219.22288590316194 -88.79157128358906, 219.22288590316194 -89.4168640391073, 218.9325244648796 -89.4168640391073, 218.9325244648796 -90.04215679462553, 218.64216302659727 -90.04215679462553, 218.64216302659727 -90.66744955014376, 218.35180158831494 -90.66744955014376, 218.35180158831494 -91.29274230566199))MULTILINESTRING ((280.4891493807343 -146.6311511690256, 280.4891493807343 -144.12998014695268, 280.198787942452 -144.12998014695268, 280.198787942452 -142.56674825815708, 279.90842650416965 -142.56674825815708, 279.90842650416965 -141.31616274712061, 279.6180650658873 -141.31616274712061, 279.6180650658873 -140.37822361384326, 279.327703627605 -140.37822361384326, 279.327703627605 -139.4402844805659, 279.03734218932266 -139.4402844805659, 279.03734218932266 -138.50234534728858, 278.7469807510403 -138.50234534728858, 278.7469807510403 -137.87705259177034, 278.456619312758 -137.87705259177034, 278.456619312758 -137.56440621401123, 278.16625787447566 -137.56440621401123, 278.16625787447566 -136.93911345849298, 277.87589643619333 -136.93911345849298, 277.87589643619333 -136.62646708073387, 277.585534997911 -136.62646708073387, 277.585534997911 -136.00117432521563, 277.29517355962867 -136.00117432521563, 277.29517355962867 -135.68852794745652, 277.00481212134633 -135.68852794745652, 277.00481212134633 -135.3758815696974, 276.714450683064 -135.3758815696974, 276.714450683064 -135.0632351919383, 276.13372780649934 -135.0632351919383, 276.13372780649934 -135.3758815696974, 275.843366368217 -135.3758815696974, 275.843366368217 -136.00117432521563, 275.5530049299347 -136.00117432521563, 275.5530049299347 -136.62646708073387, 275.26264349165234 -136.62646708073387, 275.26264349165234 -137.2517598362521, 274.97228205337 -137.2517598362521, 274.97228205337 -137.87705259177034, 274.6819206150877 -137.87705259177034, 274.6819206150877 -138.8149917250477, 274.39155917680534 -138.8149917250477, 274.39155917680534 -139.4402844805659, 274.101197738523 -139.4402844805659, 274.101197738523 -140.37822361384326, 273.8108363002407 -140.37822361384326, 273.8108363002407 -141.31616274712061, 273.52047486195835 -141.31616274712061, 273.52047486195835 -142.56674825815708, 273.230113423676 -142.56674825815708, 273.230113423676 -144.12998014695268, 272.9397519853937 -144.12998014695268, 272.9397519853937 -145.69321203574825, 272.64939054711135 -145.69321203574825, 272.64939054711135 -147.88173668006206, 272.359029108829 -147.88173668006206, 272.359029108829 -156.32318887955822))MULTILINESTRING ((286.296378146381 0, 286.296378146381 -1.563231888795582, 286.58673958466335 -1.563231888795582, 286.58673958466335 -2.8138173998320477, 286.296378146381 -2.8138173998320477, 286.296378146381 -4.064402910868513, 286.0060167080987 -4.064402910868513, 286.0060167080987 -4.689695666386746, 285.71565526981635 -4.689695666386746, 285.71565526981635 -5.314988421904979, 285.425293831534 -5.314988421904979, 285.425293831534 -5.627634799664095, 285.1349323932517 -5.627634799664095, 285.1349323932517 -5.940281177423212, 284.84457095496936 -5.940281177423212, 284.84457095496936 -6.252927555182328, 284.554209516687 -6.252927555182328, 284.554209516687 -6.565573932941445, 284.2638480784047 -6.565573932941445, 284.2638480784047 -6.878220310700561, 283.97348664012236 -6.878220310700561, 283.97348664012236 -7.1908666884596775, 283.68312520184 -7.1908666884596775, 283.68312520184 -7.503513066218794, 283.3927637635577 -7.503513066218794, 283.3927637635577 -7.81615944397791, 282.81204088699303 -7.81615944397791, 282.81204088699303 -8.128805821737027, 282.5216794487107 -8.128805821737027, 282.5216794487107 -8.441452199496144, 281.940956572146 -8.441452199496144, 281.940956572146 -8.75409857725526, 281.65059513386365 -8.75409857725526, 281.65059513386365 -9.066744955014375, 281.069872257299 -9.066744955014375, 281.069872257299 -9.379391332773492, 280.4891493807343 -9.379391332773492, 280.4891493807343 -9.69203771053261, 279.90842650416965 -9.69203771053261, 279.90842650416965 -10.004684088291725, 279.6180650658873 -10.004684088291725, 279.6180650658873 -10.31733046605084, 279.03734218932266 -10.31733046605084, 279.03734218932266 -10.629976843809958, 278.456619312758 -10.629976843809958, 278.456619312758 -10.942623221569075, 277.87589643619333 -10.942623221569075, 277.87589643619333 -11.25526959932819, 277.29517355962867 -11.25526959932819, 277.29517355962867 -11.567915977087306, 276.714450683064 -11.567915977087306, 276.714450683064 -11.880562354846424, 275.5530049299347 -11.880562354846424, 275.5530049299347 -12.193208732605541, 274.101197738523 -12.193208732605541, 274.101197738523 -12.505855110364656, 272.64939054711135 -12.505855110364656, 272.64939054711135 -12.818501488123772, 271.19758335569963 -12.818501488123772, 271.19758335569963 -13.13114786588289, 269.745776164288 -13.13114786588289, 269.745776164288 -13.443794243642007, 268.2939689728763 -13.443794243642007, 268.2939689728763 -13.756440621401122, 266.84216178146465 -13.756440621401122, 266.84216178146465 -14.069086999160238, 265.6807160283353 -14.069086999160238, 265.6807160283353 -14.381733376919355, 262.777101645512 -14.381733376919355, 262.777101645512 -14.694379754678472, 259.00240294784163 -14.694379754678472, 259.00240294784163 -15.007026132437588, 256.0987885650183 -15.007026132437588, 256.0987885650183 -15.319672510196703, 253.4855356204773 -15.319672510196703, 253.4855356204773 -15.63231888795582, 250.8722826759363 -15.63231888795582, 250.8722826759363 -15.944965265714938, 248.54939116967762 -15.944965265714938, 248.54939116967762 -16.257611643474053, 245.93613822513663 -16.257611643474053, 245.93613822513663 -16.57025802123317, 243.3228852805956 -16.57025802123317, 243.3228852805956 -16.882904398992288, 241.58071665090162 -16.882904398992288, 241.58071665090162 -17.195550776751404, 239.83854802120763 -17.195550776751404, 239.83854802120763 -17.50819715451052, 238.38674082979597 -17.50819715451052, 238.38674082979597 -17.820843532269635, 236.93493363838428 -17.820843532269635, 236.93493363838428 -18.13348991002875, 235.48312644697262 -18.13348991002875, 235.48312644697262 -18.44613628778787, 233.74095781727863 -18.44613628778787, 233.74095781727863 -18.758782665546985, 232.28915062586694 -18.758782665546985, 232.28915062586694 -19.0714290433061, 230.2566205578906 -19.0714290433061, 230.2566205578906 -19.38407542106522, 223.86866891567928 -19.38407542106522, 223.86866891567928 -19.696721798824335, 213.99638001407993 -19.696721798824335, 213.99638001407993 -19.38407542106522, 207.0277054953039 -19.38407542106522, 207.0277054953039 -19.0714290433061, 203.54336823591592 -19.0714290433061, 203.54336823591592 -18.758782665546985, 199.47830809996324 -18.758782665546985, 199.47830809996324 -18.44613628778787, 184.08915187099956 -18.44613628778787, 184.08915187099956 -18.758782665546985, 177.4108387905059 -18.758782665546985, 177.4108387905059 -19.0714290433061, 171.6036100248592 -19.0714290433061, 171.6036100248592 -19.38407542106522, 166.3771041357772 -19.38407542106522, 166.3771041357772 -19.696721798824335, 158.5373453021542 -19.696721798824335, 158.5373453021542 -20.00936817658345, 140.24457469036716 -20.00936817658345, 140.24457469036716 -20.322014554342566, 135.01806880128515 -20.322014554342566, 135.01806880128515 -20.63466093210168, 130.3722857887678 -20.63466093210168, 130.3722857887678 -20.9473073098608, 127.75903284422682 -20.9473073098608, 127.75903284422682 -21.259953687619916, 126.01686421453282 -21.259953687619916, 126.01686421453282 -21.57260006537903, 123.98433414655648 -21.57260006537903, 123.98433414655648 -21.88524644313815, 122.24216551686249 -21.88524644313815, 122.24216551686249 -22.197892820897266, 120.49999688716848 -22.197892820897266, 120.49999688716848 -22.51053919865638, 119.0481896957568 -22.51053919865638, 119.0481896957568 -22.823185576415497, 117.59638250434514 -22.823185576415497, 117.59638250434514 -23.135831954174613, 115.85421387465114 -23.135831954174613, 115.85421387465114 -23.44847833193373, 114.40240668323948 -23.44847833193373, 114.40240668323948 -23.761124709692847, 112.9505994918278 -23.761124709692847, 112.9505994918278 -24.073771087451963, 112.0795151769808 -24.073771087451963, 112.0795151769808 -24.386417465211082, 110.91806942385146 -24.386417465211082, 110.91806942385146 -24.699063842970197, 110.3373465472868 -24.699063842970197, 110.3373465472868 -25.011710220729313, 109.4662622324398 -25.011710220729313, 109.4662622324398 -25.32435659848843, 109.17590079415747 -25.32435659848843, 109.17590079415747 -25.637002976247544, 108.59517791759279 -25.637002976247544, 108.59517791759279 -25.949649354006663, 108.30481647931046 -25.949649354006663, 108.30481647931046 -26.574942109524894, 108.01445504102813 -26.574942109524894, 108.01445504102813 -27.20023486504313, 108.30481647931046 -27.20023486504313, 108.30481647931046 -27.82552762056136, 108.59517791759279 -27.82552762056136, 108.59517791759279 -28.138173998320475, 108.88553935587512 -28.138173998320475, 108.88553935587512 -28.450820376079594, 109.17590079415747 -28.450820376079594, 109.17590079415747 -28.76346675383871, 109.75662367072213 -28.76346675383871, 109.75662367072213 -29.076113131597825, 110.3373465472868 -29.076113131597825, 110.3373465472868 -29.388759509356944, 110.62770798556913 -29.388759509356944, 110.62770798556913 -29.70140588711606, 111.49879230041614 -29.70140588711606, 111.49879230041614 -30.014052264875176, 112.0795151769808 -30.014052264875176, 112.0795151769808 -30.32669864263429, 112.9505994918278 -30.32669864263429, 112.9505994918278 -30.639345020393407, 113.53132236839247 -30.639345020393407, 113.53132236839247 -30.951991398152526, 114.69276812152181 -30.951991398152526, 114.69276812152181 -31.26463777591164, 115.5638524363688 -31.26463777591164, 115.5638524363688 -31.577284153670757, 117.01565962778048 -31.577284153670757, 117.01565962778048 -31.889930531429876, 117.88674394262748 -31.889930531429876, 117.88674394262748 -32.20257690918899, 118.46746681919214 -32.20257690918899, 118.46746681919214 -32.51522328694811, 119.0481896957568 -32.51522328694811, 119.0481896957568 -32.82786966470722, 119.62891257232148 -32.82786966470722, 119.62891257232148 -33.14051604246634, 119.91927401060381 -33.14051604246634, 119.91927401060381 -33.45316242022545, 120.49999688716848 -33.45316242022545, 120.49999688716848 -33.765808797984576, 121.08071976373314 -33.765808797984576, 121.08071976373314 -34.07845517574369, 121.6614426402978 -34.07845517574369, 121.6614426402978 -34.39110155350281, 122.24216551686249 -34.39110155350281, 122.24216551686249 -34.70374793126192, 122.82288839342715 -34.70374793126192, 122.82288839342715 -35.01639430902104, 123.40361126999181 -35.01639430902104, 123.40361126999181 -35.329040686780154, 123.98433414655648 -35.329040686780154, 123.98433414655648 -35.64168706453927, 124.56505702312116 -35.64168706453927, 124.56505702312116 -35.954333442298385, 125.14577989968582 -35.954333442298385, 125.14577989968582 -36.2669798200575, 126.01686421453282 -36.2669798200575, 126.01686421453282 -36.57962619781662, 126.59758709109748 -36.57962619781662, 126.59758709109748 -36.89227257557574, 127.17830996766216 -36.89227257557574, 127.17830996766216 -37.204918953334854, 127.75903284422682 -37.204918953334854, 127.75903284422682 -37.51756533109397, 128.3397557207915 -37.51756533109397, 128.3397557207915 -37.830211708853085, 129.21084003563848 -37.830211708853085, 129.21084003563848 -38.1428580866122, 130.08192435048548 -38.1428580866122, 130.08192435048548 -38.455504464371316, 130.9530086653325 -38.455504464371316, 130.9530086653325 -38.76815084213044, 131.8240929801795 -38.76815084213044, 131.8240929801795 -39.080797219889554, 132.6951772950265 -39.080797219889554, 132.6951772950265 -39.39344359764867, 133.5662616098735 -39.39344359764867, 133.5662616098735 -39.706089975407785, 134.72770736300282 -39.706089975407785, 134.72770736300282 -40.0187363531669, 135.88915311613218 -40.0187363531669, 135.88915311613218 -40.331382730926016, 137.34096030754384 -40.331382730926016, 137.34096030754384 -40.64402910868513, 138.50240606067317 -40.64402910868513, 138.50240606067317 -40.95667548644425, 140.24457469036716 -40.95667548644425, 140.24457469036716 -41.26932186420336, 144.59999626460217 -41.26932186420336, 144.59999626460217 -41.581968241962485, 156.50481523417787 -41.581968241962485, 156.50481523417787 -41.8946146197216, 164.6349355060832 -41.8946146197216, 164.6349355060832 -41.581968241962485, 174.50722440768254 -41.581968241962485, 174.50722440768254 -41.26932186420336, 175.37830872252954 -41.26932186420336, 175.37830872252954 -40.95667548644425, 176.53975447565887 -40.95667548644425, 176.53975447565887 -40.64402910868513, 177.70120022878822 -40.64402910868513, 177.70120022878822 -40.331382730926016, 178.57228454363522 -40.331382730926016, 178.57228454363522 -40.0187363531669, 180.02409173504688 -40.0187363531669, 180.02409173504688 -39.706089975407785, 181.1855374881762 -39.706089975407785, 181.1855374881762 -39.39344359764867, 182.34698324130557 -39.39344359764867, 182.34698324130557 -39.080797219889554, 183.79879043271723 -39.080797219889554, 183.79879043271723 -38.76815084213044, 185.2505976241289 -38.76815084213044, 185.2505976241289 -38.455504464371316, 186.70240481554055 -38.455504464371316, 186.70240481554055 -38.1428580866122, 187.8638505686699 -38.1428580866122, 187.8638505686699 -37.830211708853085, 189.02529632179923 -37.830211708853085, 189.02529632179923 -37.51756533109397, 190.18674207492856 -37.51756533109397, 190.18674207492856 -37.204918953334854, 191.63854926634022 -37.204918953334854, 191.63854926634022 -36.89227257557574, 192.79999501946958 -36.89227257557574, 192.79999501946958 -36.57962619781662, 193.9614407725989 -36.57962619781662, 193.9614407725989 -36.2669798200575, 195.12288652572823 -36.2669798200575, 195.12288652572823 -35.954333442298385, 196.28433227885756 -35.954333442298385, 196.28433227885756 -35.64168706453927, 198.60722378511625 -35.64168706453927, 198.60722378511625 -35.954333442298385, 201.8011996062219 -35.954333442298385, 201.8011996062219 -36.2669798200575, 210.2216813164096 -36.2669798200575, 210.2216813164096 -36.57962619781662, 213.99638001407993 -36.57962619781662, 213.99638001407993 -36.89227257557574, 217.48071727346792 -36.89227257557574, 217.48071727346792 -37.204918953334854, 219.8036087797266 -37.204918953334854, 219.8036087797266 -37.51756533109397, 220.6746930945736 -37.51756533109397, 220.6746930945736 -37.830211708853085, 221.5457774094206 -37.830211708853085, 221.5457774094206 -38.1428580866122, 222.4168617242676 -38.1428580866122, 222.4168617242676 -38.455504464371316, 222.99758460083228 -38.455504464371316, 222.99758460083228 -38.76815084213044, 223.86866891567928 -38.76815084213044, 223.86866891567928 -39.080797219889554, 224.73975323052628 -39.080797219889554, 224.73975323052628 -39.39344359764867, 225.32047610709094 -39.39344359764867, 225.32047610709094 -39.706089975407785, 225.9011989836556 -39.706089975407785, 225.9011989836556 -40.0187363531669, 226.7722832985026 -40.0187363531669, 226.7722832985026 -40.331382730926016, 227.35300617506726 -40.331382730926016, 227.35300617506726 -40.64402910868513, 227.93372905163193 -40.64402910868513, 227.93372905163193 -40.95667548644425, 228.80481336647895 -40.95667548644425, 228.80481336647895 -41.26932186420336, 229.38553624304362 -41.26932186420336, 229.38553624304362 -41.581968241962485, 229.96625911960828 -41.581968241962485, 229.96625911960828 -41.8946146197216, 230.54698199617295 -41.8946146197216, 230.54698199617295 -42.20726099748072, 231.41806631101994 -42.20726099748072, 231.41806631101994 -42.51990737523983, 233.4505963789963 -42.51990737523983, 233.4505963789963 -42.83255375299895, 235.48312644697262 -42.83255375299895, 235.48312644697262 -43.14520013075806, 237.51565651494894 -43.14520013075806, 237.51565651494894 -43.45784650851718, 239.5481865829253 -43.45784650851718, 239.5481865829253 -43.7704928862763, 241.87107808918395 -43.7704928862763, 241.87107808918395 -44.08313926403542, 247.3879454165483 -44.08313926403542, 247.3879454165483 -44.39578564179453, 254.64698137360665 -44.39578564179453, 254.64698137360665 -44.70843201955365, 257.26023431814764 -44.70843201955365, 257.26023431814764 -45.02107839731276, 259.8734872626886 -45.02107839731276, 259.8734872626886 -45.33372477507188, 262.777101645512 -45.33372477507188, 262.777101645512 -45.646371152830994, 265.390354590053 -45.646371152830994, 265.390354590053 -45.95901753059011, 266.2614389049 -45.95901753059011, 266.2614389049 -46.271663908349225, 267.132523219747 -46.271663908349225, 267.132523219747 -46.58431028610835, 268.2939689728763 -46.58431028610835, 268.2939689728763 -46.89695666386746, 269.1650532877233 -46.89695666386746, 269.1650532877233 -47.20960304162658, 270.0361376025703 -47.20960304162658, 270.0361376025703 -47.522249419385695, 270.9072219174173 -47.522249419385695, 270.9072219174173 -47.83489579714481, 271.77830623226436 -47.83489579714481, 271.77830623226436 -48.147542174903926, 272.9397519853937 -48.147542174903926, 272.9397519853937 -48.46018855266304, 273.8108363002407 -48.46018855266304, 273.8108363002407 -48.772834930422164, 274.6819206150877 -48.772834930422164, 274.6819206150877 -49.08548130818128, 275.5530049299347 -49.08548130818128, 275.5530049299347 -49.398127685940395, 276.42408924478167 -49.398127685940395, 276.42408924478167 -49.71077406369951, 277.00481212134633 -49.71077406369951, 277.00481212134633 -49.398127685940395, 279.6180650658873 -49.398127685940395, 279.6180650658873 -49.71077406369951, 284.2638480784047 -49.71077406369951, 284.2638480784047 -50.023420441458626, 288.32890821435734 -50.023420441458626, 288.32890821435734 -49.71077406369951, 288.909631090922 -49.71077406369951, 288.909631090922 -49.398127685940395, 289.49035396748667 -49.398127685940395, 289.49035396748667 -49.08548130818128, 290.36143828233367 -49.08548130818128, 290.36143828233367 -48.772834930422164, 290.94216115889833 -48.772834930422164, 290.94216115889833 -48.46018855266304, 291.8132454737453 -48.46018855266304, 291.8132454737453 -48.147542174903926, 292.39396835031005 -48.147542174903926, 292.39396835031005 -47.83489579714481, 293.26505266515704 -47.83489579714481, 293.26505266515704 -47.522249419385695, 293.8457755417217 -47.522249419385695, 293.8457755417217 -47.20960304162658, 294.7168598565687 -47.20960304162658, 294.7168598565687 -46.89695666386746, 295.5879441714157 -46.89695666386746, 295.5879441714157 -46.58431028610835, 296.4590284862627 -46.58431028610835, 296.4590284862627 -46.271663908349225, 297.3301128011097 -46.271663908349225)) \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/lang/artifactMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/lang/artifactMessages.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,25 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modeldata +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey + +timeSeries= Timeseries +verticalProfile = Verticalprofile +horizontalProfile = Horizontalprofile +featureid = Object +mesh_coordinate = Coordinate Value (x y) +mesh_point = Meshpoint +measurementid = Measurement depth +parameterid = Parameter +minvalue = Minvalue +maxvalue = Maxvalue +dateid = Measurement date +vehicleid = Ship +cruiseid = Cruise +trackid = Track +surveyid = Survey Info +axisid = Axis +depthid = Depth \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/lang/artifactMessages_de_DE.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/lang/artifactMessages_de_DE.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,25 @@ +fis_marnet = Marnet +fis_imis = IMIS +fis_staun = STAUN +fis_modeldata = Modelldaten +fis_delphin = Delphin +fis_thermosalinograph = Thermosalinograph +fis_chemusurvey = Chemusurvey + +timeSeries= Zeitserie +verticalProfile = Vertikalprofil +horizontalProfile = Horizontalprofil +featureid = ObjeKt +mesh_coordinate = Koordinaten Wert (x y) +mesh_point = Messpunkt +measurementid = Messtiefe +parameterid = Parameter +minvalue = Minimalwert +maxvalue = Maximalwert +dateid = Messdatum +vehicleid = Schiff +cruiseid = Reise +trackid = Track +surveyid = Messinformation +axisid = Achse +depthid = Tiefe diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + true + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries/timeseries_step_06_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/timeseries_mesh/timeseries_step_08_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalcrosssection_mesh/verticalcrosssection_step_07_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile/verticalprofile_step_07_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,2 @@ + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_instantaneouspoint/verticalprofile_step_05_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_describe.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_describe.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + true + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_01_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_01_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_01_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_01_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_02_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_02_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_02_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_02_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_03_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_03_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_03_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_03_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_04_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_04_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_04_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_04_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_05_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_05_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_05_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_05_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_06_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_06_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_06_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_06_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_07_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_07_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_07_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_07_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_08_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_08_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_08_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_08_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_09_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_09_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_09_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_09_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_10_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_advance.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_advance.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_feed.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_feed.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_chart.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_chart.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,13 @@ + + + + + /> + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_csv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_csv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_odv.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_odv.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_statistics.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/test/ressources/verticalprofile_mesh/verticalprofile_step_11_out_statistics.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/ChangeLog Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,2396 @@ +2010-04-28 Ingo Weinzierl + + * Changes, NEWS, ChangeLog: Summarized changes. + +2010-04-28 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java: Removed + trailing whitespace. + +2010-04-28 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/DescribeUIAction.java: Removed + duplicated and unused imports. + +2010-04-27 Ingo Weinzierl + + Issue225 + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added global forwards + for imprint and info. + + * src/main/webapp/WEB-INF/jsp/header.jsp, + src/main/webapp/WEB-INF/jsp/footer.jsp: Adapted links for imprint and info + pages. + + * src/main/webapp/WEB-INF/jsp/imprint.jsp, + src/main/webapp/WEB-INF/jsp/info.jsp: New pages for imprint and an info + page. + + * src/main/resources/applicationMessages_en.properties: Renamed 'about' -> + 'imprint'. + +2010-04-27 Ingo Weinzierl + + Issue225 + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Render a + parameter matrix if there is just a single parameter as well. This allows + us to render a legend for multi select boxes at another place - this fixes + the missing legend for parameter select boxes. + +2010-04-26 Ingo Weinzierl + + * src/main/webapp/images/img.gif, + src/main/webapp/images/stock_data-save.png, + src/main/webapp/images/bg_fieldset.gif, + src/main/webapp/images/list-item.gif, + src/main/webapp/images/bg_fieldset_ie6.gif, + src/main/webapp/scripts/calendar-setup.js, + src/main/webapp/scripts/calendar-en.js, + src/main/webapp/scripts/calendar.js, + src/main/webapp/scripts/calendar-de.js, + src/main/webapp/scripts/calendar-setup_stripped.js, + src/main/webapp/scripts/jquery-1.4.2.min.js, + src/main/webapp/scripts/calendar_stripped.js: Removed JavaScript files and + images that are not used anymore. + +2010-04-26 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added an error + message if that should be displayed if an artifact is out of date. + +2010-04-26 Ingo Weinzierl + + Issue236 & Issue242 + + * src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java, + src/main/java/de/intevation/gnv/action/DescribeUIAction.java: Display + error messages if the artifact server is down - this have been broken. + +2010-04-26 Ingo Weinzierl + + Issue258 + + * src/main/java/de/intevation/gnv/action/LoadAction.java: An error message + is displayed if the user tried to load an existing project and the + artifact server is down. + +2010-04-26 Ingo Weinzierl + + Issue259 + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Added target 'chart' as url request parameter when performing the html + form to change the chart output. The reason for doing this is, that the + InternetExplorer seems no to add the value of + elements to the request object which is sent to the server. + +2010-04-26 Ingo Weinzierl + + Issue225 + + * src/main/webapp/styles/gnv.css: Reduced the size of links in header and + footer. + +2010-04-26 Ingo Weinzierl + + Issue225 + + * src/main/webapp/styles/gnv.css: Adjusted the style of fieldsets - there is + a gap between the fieldset border and input elements in IE now as well. + The size of select boxes and textareas is fixed now. + +2010-04-25 Ingo Weinzierl + + Issue225 + + * src/main/webapp/styles/gnv.css: A new style class. Most of this is copied + from default.css but a lot of content which is not used anymore has been + removed. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Restructuring. The parameter panel + and the content div container are placed in a table row now. Very wide + html elements in the content div container don't break the layout anymore. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: Moved html elements to render + OpenLayers into index.jsp. Removed JavaScript code to adjust layout. + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Added style class to the table that contains the chart options. + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Removed JavaScript code to + adjust layout. + + * src/main/webapp/scripts/jquery-1.4.2.min.js: Removed. Not used anymore. + +2010-04-23 Ingo Weinzierl + + Issue225 + + * src/main/webapp/styles/default.css: Adapted some font size in the + parameter panel. + +2010-04-23 Ingo Weinzierl + + Issue225 + + * src/main/webapp/WEB-INF/jsp/index.jsp: Replaced the standard html input + button with an image as the choose button. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added specific + strings that represent pathes to german and english load button images. + + * src/main/webapp/styles/default.css: New styles to adjust the upload box + and the load button. + + + * src/main/webapp/images/load.png, + src/main/webapp/images/laden.png: Images for project load button. + +2010-04-23 Ingo Weinzierl + + Issue237 + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: Added http request parameter to + the mapserver path to simplify the GetCapabilities call for the user. + +2010-04-23 Ingo Weinzierl + + Issue254 + + * src/main/java/de/intevation/gnv/action/SwitchLanguageAction.java: New + controller to toggle between german and english language. + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java, + src/main/java/de/intevation/gnv/action/DescribeUIAction.java: Use the + locale stored in the artifact to create the user interface. At the + beginning, this will be the locale of the request object. If the user + chooses another language by calling the SwitchLanguageAction controller, + this locale becomes the prefered locale, and the browser settings are no + more relevant. + + * src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java, + src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java: + Now, the SessionModel has two methods to set and retrieve the current + locale which is used to create a language specific user interface. + + * src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java: + Initial creation of the SessionModel gets the locale of the request + object. If this locale is changed by the user via SwitchLanguageAction + controller, changes in the browser settings won't have an effect anymore. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Add the controller to + switch between languages. + + * src/main/webapp/WEB-INF/jsp/header.jsp: The header contains a link to + toggle between german and english language - a click on it will trigger + the SwitchLanguageAction. + +2010-04-22 Ingo Weinzierl + + Issue221 + + * src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java: + Added methods to quote html characters in strings. + + * src/main/java/de/intevation/gnv/action/WMSAction.java: Call methods to + quote html characters in strings inserted by the user. Used to be safe + from html injections. + +2010-04-19 Hans Plum + + Issue 241: Set Path to Tomcat Standard Logging + + * src/main/webapp/WEB-INF/classes/log4j.properties: + Adapted logging path for webclient gnv to the central tomcat mechamism + in order to resolve the dependency to the artefact-server directory + layout. + +2010-04-19 Ingo Weinzierl + + Issue227 + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Added a new method to retrieve the current locale. + + * src/main/java/de/intevation/gnv/action/DescribeUIAction.java: Feed the xsl + transformer with a tooltip text for the back-button. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added a tooltip text + for the back-button. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Use the + tooltip text that is fed in DescribeUIAction. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Removed a + PropertiesReader which isn't used there. + +2010-04-19 Sascha L. Teichmann + + * src/main/resources/applicationMessages.properties: Forgot a dot. ;-) + +2010-04-19 Ingo Weinzierl + + Issue224 + + * src/main/resources/applicationMessages.properties: Fixed a typo in the + german text of the overlay display. + +2010-04-18 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Using unix line endings only. + +2010-04-17 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Removed trailing whitespace. + +2010-04-14 Hans Plum + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: + Adapted background layers to a global and local visibale layer (World + Relief (2 Minute Raster) + +2010-04-14 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Changed language + strings. + + * src/main/webapp/styles/default.css: Adapted css classes. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp, + src/main/webapp/WEB-INF/jsp/header.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Adapeted design. + + * src/main/webapp/scripts/gnviewer.js: Added javascript methods to adapt the + size of the content panel. + + * src/main/webapp/scripts/jquery-1.4.2.min.js: JavaScript library doing + general javascript stuff. + +2010-04-13 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added resource + pointing to the image of the 'choose'-button. + + * src/main/webapp/images/auswaehlen.png, + src/main/webapp/images/choose.png: Selfmade 'choose'-buttons for english + and german language. + + * src/main/webapp/WEB-INF/jsp/index.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp: Removed standard + html input buttons with selfmade ones. + +2010-04-13 Ingo Weinzierl + + * src/main/webapp/styles/default.css: Adapted style of links. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Replaced input buttons for + loading/saving projects with links. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Added javascript function to + toggle the visibility of the file upload button/chooser. + +2010-04-13 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Fixed a display + bug in the measurement panel for one parameter. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: New strings for + header and footer links. + + * src/main/webapp/styles/default.css: Added and adapted style classes. + + * src/main/webapp/WEB-INF/jsp/header.jsp: Added links for restarting the app, + retrieving information about it and switching the current language. + + * src/main/webapp/WEB-INF/jsp/footer.jsp: Added navigation links to 'home', + a contact page and an about page. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp, + src/main/webapp/WEB-INF/jsp/index.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_wms_options_inc.jsp: Changed + the design of the whole application regarding the bsh styleguide. + +2010-04-13 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticValue.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticValue.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactObject.java : + Added more Javadocs. + +2010-04-13 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/package.html, + src/main/java/de/intevation/gnv/artifactdatabase/objects/map/package.html, + src/main/java/de/intevation/gnv/artifactdatabase/client/exception/package.html, + src/main/java/de/intevation/gnv/artifactdatabase/client/package.html, + src/main/java/de/intevation/gnv/action/package.html, + src/main/java/de/intevation/gnv/action/sessionmodel/package.html, + src/main/java/de/intevation/gnv/util/package.html: Added first part of + package descriptions. + +2010-04-13 Hans Plum + + * src/main/webapp/images/svg.png, + src/main/webapp/images/delete.png, + src/main/webapp/images/map_go.png, + src/main/webapp/images/diagram_export.png, + src/main/webapp/images/chart_curve.png, + src/main/webapp/images/arrow_refresh.png, + src/main/webapp/images/pdf.png, + src/main/webapp/images/data_export.png, + src/main/webapp/images/chart_bar.png, + src/main/webapp/images/statistics.png, + src/main/webapp/images/disk.png, + src/main/webapp/images/tick.png, + src/main/webapp/images/back_button.png: + Converted relevant icons to the requirements of BSH Corporate Design, + 19.06.2009, S. 172: Hue: 172; Saturation: 34; Brightness: 28. + +2010-04-12 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/propertiesreader/PropertiesReader.java, + src/main/java/de/intevation/gnv/propertiesreader/ServletPropertiesReader.java, + src/main/java/de/intevation/gnv/propertiesreader/PropertiesReaderFactory.java, + src/main/java/de/intevation/gnv/propertiesreader/MapPropertiesReader.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/InputParameter.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputParameter.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultInputParameter.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputParameter.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticValue.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactObject.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticsSet.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ExportMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticsSet.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultExportMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactObject.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultLayer.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultMapService.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/map/Layer.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/map/MapService.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseClientException.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java, + src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java, + src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java, + src/main/java/de/intevation/gnv/action/CommunicationKeys.java, + src/main/java/de/intevation/gnv/action/DoExportAction.java, + src/main/java/de/intevation/gnv/action/WMSAction.java, + src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java, + src/main/java/de/intevation/gnv/action/ShowStatisticAction.java, + src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java, + src/main/java/de/intevation/gnv/action/DescribeUIAction.java, + src/main/java/de/intevation/gnv/action/LoadAction.java, + src/main/java/de/intevation/gnv/action/CreateHistogramAction.java, + src/main/java/de/intevation/gnv/action/SelectFisAction.java, + src/main/java/de/intevation/gnv/action/DoOutputAction.java, + src/main/java/de/intevation/gnv/action/CreateChartAction.java, + src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java, + src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java, + src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java, + src/main/java/de/intevation/gnv/action/sessionmodel/DiagrammOptions.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java, + src/main/java/de/intevation/gnv/action/StoreAction.java, + src/main/java/de/intevation/gnv/util/ArtifactNamespaceContext.java, + src/main/java/de/intevation/gnv/util/XSLTransformer.java: Added JavaDoc + comments. + +2010-04-12 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for + chart button in actions panel. + + * src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Changed the + label of the chart button in the actions panel ('Diagramm speichern' -> + 'Diagramm'). + +2010-04-09 Ingo Weinzierl + + Issue210 + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Changed the + parameter-measurement matrix rendering. Its content is no more selectable + - it is just to inform the user about the existence of a measurement for a + given parameter. Instead, there is a new row with a checkbox for each + measurement in the header of the matrix. So, the user is able to select a + measurement without a relation to a specific parameter - all parameters + which are available for this measurement are effected by this choice in + future outputs. + + * src/main/webapp/styles/default.css: New classes for styling the + parameter-measurement matrix. + + * src/main/webapp/images/delete.png, + src/main/webapp/images/tick.png: New icons to inform the user about the + existence of a measurement for a given parameter. + +2010-04-09 Ingo Weinzierl + + Issue216 + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Added a missing character to the url of the image export. + +2010-03-29 Ingo Weinzierl + + Issue13 & Issue18 + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp, + src/main/webapp/WEB-INF/jsp/header.jsp: Added a reload link. A click on + this link rebuilds the ui with the description of the current artifact. + + Note: If the artifact server ist down, nothing happens when using this + link. A click on this link triggers a controller which sends a + describe-request to the artifact server. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added a new controller + to build the current user interface. This could be used if the artifact + server is down and the ui brakes after an user interaction. After the + artifact server being restarted, this controller can be called to rebuild + the ui with the current artifact description. + + * src/main/webapp/styles/default.css: Moved exception message and reload + link a bit to avoid overlapping elements. Added a new class to adjust the + style of the reload link. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added strings for + reload-link. + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/package.html: New. + Added package description with text 'DOCUMENT ME!'. + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Bring @author javadoc tags in form '@author John Doe' + + find -name \*.java | \ + xargs sed -i \ + -e 's/@author[ ]\+\([^(<]\+\)[<(]\([^>)]\+\)[>)]/@author \1<\/a>/g' \ + -e 's@[ ]\+@@g' + +2010-03-29 Sascha L. Teichmann + + * rc/main/java/de/intevation/gnv/**/*.java: + Ordered imports. Removed needless imports. Removed empty headers. + +2010-03-29 Ingo Weinzierl + + Issue30 + + * src/main/java/de/intevation/gnv/action/DescribeUIAction.java: Use the + correct locale for i18n supported by HttpServletRequest object. The + application language is switched after the next server round-trip if the + user changes the preferred browser language. + Hint: Struts' Action class has a method getLocale(HttpServletRequest) + which should return the currently selected locale. This method seems to be + buggy - returns session's initial locale. + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java: + Inherit from DescribeUIAction. The rendering stuff is now done by + DescribeUIAction. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added missing forward + used for stepping back to a previous state in SelectArtifactFactory + action. + +2010-03-29 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: + Removed trailing whitespace. + find -name \*.java | xargs sed -i 's/[ \t]\+$//' + +2010-03-26 Ingo Weinzierl + + Issue197 + + * src/main/java/de/intevation/gnv/action/WMSAction.java: Parse the time to + live of an artifact from meta document and set an attribute 'ttl' of the + request object. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: Added a new row showing + the time to live beneath the layer name and wms url. + + * src/main/resources/applicationMessages_en.properties, + src/main/resources/applicationMessages.properties: Added new label for + availability of an artifact/wms-layer. + + * src/main/webapp/styles/default.css: Moved OpenLayers map a bit south. + +2010-03-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Improved the copying of input stream to output stream a bit. + +2010-03-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/LoadAction.java: Just copy the + input stream to the output stream without parsing it and without creating + a temporary xml document. + +2010-03-22 Tim Englich + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp, + src/main/java/de/intevation/gnv/action/WMSAction.java (execute): + Improved ExceptionHandling during WMS-Publishing. + Now the OL-GUI will only be shown if the WMS was published succsessfull. + +2010-03-19 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (publishWMS), + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (publishWMS), + src/main/java/de/intevation/gnv/action/WMSAction.java (execute): + Improved ExceptionHandling during WMS-Publishing. + The responsedocument will be scanned for Exceptionreports. + Also if no URL, Mapfile or Layer was retrieved from the Responsedocument + the Exceptionpage will be visualized instead an corrupt Openlayersclient. + +2010-03-19 Tim Englich + + * src/main/resources/applicationMessages.properties: + Added new German resource for fis_marinefeatures according to msg1067 + of Issue2005. + +2010-03-19 Tim Englich + + * src/main/resources/applicationMessages*.properties: + Added Ressources for new FIS Marine Features. + +2010-03-19 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/LoadAction.java: Use the uploaded + file to start an artifact import. Create a new Artifact object if the + import was successful and fetch the current artifact description with user + interface part to restore the gui. Display an error message if something + failed while importing. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java: + Added a new method doImport to import artifacts from xml documents. A + describe document without ui part is returned if an import was successful. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added error messages + for the case that something failed while importing artifacts from xml + documents. + + * src/main/webapp/WEB-INF/jsp/header.jsp: Replace whitespaces from exception + request parameter with dots. Exceptions thrown by the artifact server + corresponds to a specific resource key. Failures coming from the artifact + server are displayed language specific on this way. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added missing forwards + to import action. + +2010-03-19 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java (addParameters): + Some Codecleanup done. + +2010-03-19 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp: + Integrated a Switch will be load different Geometries into the + Requestbody of an Mapviewercall. + You cann add gt=POINT , gt=LINESTRING or gt=POLYGON to the URL to switch + between the different Geometries. + The Values of the Geometries are the same as used in the GUI of the GNV. + +2010-03-17 Ingo Weinzierl + + Issue208 First steps for exporting artifacts. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java: + New method to export an artifact. + + * pom.xml: Added Apache common-fileupload 1.2.1 lib. + + * src/main/java/de/intevation/gnv/action/CommunicationKeys.java: Further + error message key added which is displayed beneath project load/store + buttons if an error occured while these operations. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added error messages + for errors which occure while loading/storing projects. + + * src/main/webapp/styles/default.css: Added a new style class to adjust + error messages which may occur while loading/storing projects. + + * src/main/java/de/intevation/gnv/action/StoreAction.java: New controller + which triggers an artifact export. After pushing the corresponding button, + the artifact is returned as xml document and a file dialog is displayed. + + * src/main/java/de/intevation/gnv/action/LoadAction.java: New controller to + import artifacts which have former been exported. XML documents are + successfully read from fileupload. + TODO: Use these documents to create artifacts. No artifacts are loaded + yet! + + * src/main/java/de/intevation/gnv/util/XMLUtils.java: Added a method to + write documents to a stream. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added LoadAction and + StoreAction. The controller are available under /gnv/load and /gnv/store. + + * src/main/webapp/WEB-INF/jsp/header.jsp: Removed placeholder string for + storing/loading the current project state and added buttons to start + an export of the current project's state (the current artifact) or reload + an artifact from a xml document. + +2010-03-16 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Changed the + rendering of measurement/parameter matrix. The matrix will now look like + this: + + | measurement label | measurement label + ------------------------------------------------------- + parameter label | measurement value | measurement value + parameter label | measurement value | measurement value + +2010-03-15 Ingo Weinzierl + + Issue198 + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Added the method signature for publishing wms layers. 'publishWMS' + requires a collection of InputParameters which are used to create the + request xml document. These input parameters can be used to adjust some + wms settings. At the moment, the only parameter which written to the + request xml document is the title for a wms layer. + + * src/main/java/de/intevation/gnv/action/WMSAction.java: Search for user + input and append given input values to request xml document. Put the layer + title into request object to be accessible in jsp files. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Render wms option panel if wms is + requested. + + * src/main/webapp/WEB-INF/jsp/includes/display_wms_options_inc.jsp: New. + Option panel for wms customization. At the moment, the user has the + possibility to adjust wms layers' title. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added some labels + for wms options. + +2010-03-12 Tim Englich + + * src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java (testArtifactDatabaseClient): + Fixed Compilation-Error because of InterfaceChanges of the + ArtifactDatabaseClient-Interface. + +2010-03-12 Tim Englich + + * src/main/resources/applicationMessages*.properties: + Integrated Resource for FIS Contis and Nauthis. + +2010-03-10 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Throw different exceptions if an error occured in the artifact server. + On this way, we are able to distinguish between general server errors or + errors caused by an invalid user input. + + * src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: + Catch the exceptions thrown by DefaultArtifactDatabaseClient and set an + attribute at the request object for each exception type. The attributes + will take effect on different places in the user interface. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java: + Exception used to be thrown if an invalid user input error occured. + + * src/main/java/de/intevation/gnv/action/CommunicationKeys.java: Added some + keys to store different error messages in the Http session. + + * src/main/webapp/styles/default.css: Added new style class to adjust the + style of error messages caused by invalid user input. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Display invalid input errors at + the top of the input area. + +2010-03-09 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/log4j.properties, + src/main/webapp/WEB-INF/classes/log4j.properties: Moved logging + configuration. The config file did not have any effect in config + directory. In classes directory, it has. + + * src/main/webapp/WEB-INF/web.xml: Removed logging section which is no more + necessary anymore. + +2010-03-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Parse + user input from chart/histogram options panel and check if integer and + doubles are valid - if we find a value which is not valid for the + configured type, we set an exception message which is displayed in the + chart/histogram options panel and sets the corresponding parameter to its + default value. + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Display error message in options panel if there is one. + + * src/main/resources/applicationMessages_en.properties, + src/main/resources/applicationMessages.properties: + Added strings to display error messages when the user entered a bad + formatted number in chart/histogram options panel. + + * src/main/java/de/intevation/gnv/action/CommunicationKeys.java: Added two + further error message keys used to store error messages for + chart/histogram options. + + * src/main/webapp/styles/default.css: Added a new class 'chartException' to + adjust the style of an error message in chart/histogram options panel. + +2010-03-08 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Adjusted xpath expression to find exception nodes in xml documents again. + The prefix 'art:' has been missing. + +2010-03-08 Ingo Weinzierl + + Issue187 + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Exports with + target 'img' will get a file extension that corresponds to their + mime-type. There was no code path for 'img' before, which caused the + problem, that 'img'-exports had a '.txt'-file extension. + +2010-03-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: + Removed duplicated imports. + +2010-03-05 Ingo Weinzierl + + Issue190 + + * src/main/java/de/intevation/gnv/action/CreateHistogramAction.java, + src/main/java/de/intevation/gnv/action/CreateChartAction.java: Reset + diagram options. Switching between chart and histogram caused some 'null' + values in text fields. After resetting these options, we don't have these + problems anymore - text fields will be filled with default values in this + case. + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_adons_inc.jsp: + Removed useless file. + +2010-03-05 Tim Englich + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + ISSUE 181: Removed duplicate Drawaing of the Lengendvalue of Groupelements + for choosing different heights for several Parameters + +2010-03-05 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + 'publishWMS' returns a whole document which contains meta information used + for mapfile generation - not just a string. These information contain + MapServer URL and the path to its mapfile. + + * src/main/java/de/intevation/gnv/action/WMSAction.java: Fetch MapServer + settings from resulting document after wms-publishing to display these + values in gui. + + * src/main/java/de/intevation/gnv/util/XMLUtils.java: Converted class + methods into static methods to use them without initializing an object of + XMLUtils. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: Show MapServer and layer + information in gui and use MapServer settings to feed OpenLayers client. + + * src/main/webapp/styles/default.css: Added some classes to adjust style of + information table (wms service, layer name) and map area. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added column labels + for displaying MapServer information. + +2010-03-04 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/index.jsp, + src/main/webapp/WEB-INF/jsp/wmslayout.jsp: Removed map-div from index.jsp + and moved it to wmslayout. So, we don't have an empty div with grey border + in our application if there is no map currently existing. Load images from + MapServer as 'image/png'. + + * src/main/webapp/styles/default.css: Adjusted style for customizing + map-div. + +2010-03-02 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Added export mode to 'out'-xml document. + + * src/main/java/de/intevation/gnv/action/DoOutputAction.java, + src/main/java/de/intevation/gnv/action/DoExportAction.java: Call + 'doOutput' for triggering an output like chart, histogram, csv or odv with + a new parameter export mode which contains the export format (img, pdf, + svg). + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Added export + mode to HTTP-Get requests. + +2010-03-02 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + Implemented a One-Step-Back-History. The user is able to step back to + the last state and to the state for choosing the fis. + +2010-03-02 Ingo Weinzierl + + Issue184 + + * src/main/webapp/WEB-INF/jsp/index.jsp: Display chart per default, when + reaching a final state, which doesn't need any further user input. + +2010-03-01 Ingo Weinzierl + + Issue183 + + * src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java: + Take care on exceptions and render an error message if an exception + occured. + +2010-03-01 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Removed little + copy-paste mistake while setting file-extension for exports. + +2010-03-01 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Set + file-extension according to mime type for histogram exports. + +2010-02-26 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Render a matrix + for measurement selection. + + * src/main/webapp/styles/default.css: Added new css class to adjust the + matrix' column headers. + +2010-02-25 Ingo Weinzierl + + Issue178 + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Added a code + path for export actions, where no export mode is given. + +2010-02-24 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Added + user selected type of bin setting (number of bins, bin width) to diagram + options and request object which are used to create links for chart + images. + + * src/main/java/de/intevation/gnv/action/DoOutputAction.java: Added user + selected type of bin setting to InputParameters which are used to create + xml documents for 'out' target. + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp: Added + checkboxes to select the field to adjust bins in histogram charts (bin + width or number of bins). When selecting a checkbox, the other box becomes + disabled. + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: JavaScript function to toggle + checkboxes. + +2010-02-24 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp: Append + user inserted parameter from histogram options (width, height, bin width, + number of bins) to http request when fetching the histogram image. + +2010-02-23 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputMode.java: + New method returning export modes. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultExportMode.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ExportMode.java: + Object storing information about mime-type, description and name of an + export mode. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Parse export modes from describe document and put them into OutputMode + objects. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Now, this + action is able to adjust histogram parameter as well. + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: An export is + triggered regarding a new parameter 'mode' which value can be 'pdf', + 'svg' or 'img'. Before, we just took care on 'target' parameter. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Transformed draw + button into an update button. + + * src/main/webapp/images/arrow_refresh.png: Icon for update button. (source: + famfamfam) + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Moved + exports from action panel into options panel. Actions (chart, histogram, + etc) are devided from exports (png, pdf, svg). + +2010-02-23 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/struts-config.xml: Foward to wmslayout.jsp + instead of mainlayout.jsp if the user selected wms target. + + * src/main/webapp/WEB-INF/jsp/wmslayout.jsp: New page for rendering a wms + client (OpenLayers). JavaScript loading take place in this page. If the + user select the wms target, a forward to this page will be done. + + TODO: Include OpenLayers library from local filesystem instead of loading + it from openlayers.org! + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Removed OpenLayers JavaScript + library and function to initialize OpenLayers. This reduces traffic while + parameterization. + +2010-02-23 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/CreateChartAction.java: Class to + trigger chart rendering. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Changed + request parameter from 'diagram' (deprecated) to 'chart'. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added title and + labels for histogram options. + + * src/main/webapp/images/chart_curve.png: Chart icon (source: famfamfam) + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added new action to + trigger chart rendering analog to histogram action. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Render chart option panel only if + the user already selected charts. + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: Show + diagram/chart options panel only if the user chose one of them. Placed + these option panels beneath the action panel. + + * src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Added new + icon for chart rendering. + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Removed js debug output. + +2010-02-22 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/struts-config.xml: New action 'WMSAction'. + It triggers the generation of shapefiles and mapfile and sets an internal + flag to intialize an OpenLayers map. + + * src/main/java/de/intevation/gnv/action/WMSAction.java: Action which + triggers the creation of shapefiles and mapfile. An internal flag is set + to initialize an OpenLayers map with the layer even published. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java: + Added a new method to send a request to the artifact server and start + shapefile and mapfile creation. + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Added javascript functions to + read url parameters and initialize OpenLayers. + + * src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Call 'wms.do' + after clicking WMS button which triggers WMSAction. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Added a div-container for rendering + an OpenLayers map. + + * src/main/webapp/styles/default.css: New class for styling map + div-container. + + * src/main/java/de/intevation/gnv/util/XMLUtils.java: Made method static to + be able to use it without creating an object of this class. + + +2010-02-15 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added an action + 'histogram' to render histograms. + + * src/main/java/de/intevation/gnv/action/CreateHistogramAction.java: Added a + new action for rendering histograms. + + * src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Display an + icon for histograms if this output mode is present for this artifact. + + * src/main/webapp/images/chart_bar.png: Icon for histograms from famfamfam + iconset. + + * src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp: JSP for + rendering histograms. + + * src/main/webapp/styles/default.css: Added a style class for adapting + histogram div. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Include display_histogram_inc if + histogram action have been chosen by user. + + * src/main/resources/applicationMessages_en.properties, + src/main/resources/applicationMessages.properties: Button label and + alternative image text for histograms. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Removed + comment lines at the beginning of the file. These empty comment lines + would cause trouble later, when inserting GPL text automatically with a + script. + +2010-02-12 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Render an + icon to trigger a step-back in history for each state. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added missing forwards + used for stepping back to former states. + +2010-02-12 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp: + Added further XML-Nodes for simulating the MapViewer-Call more detailed. + +2010-02-12 Tim Englich + + * src/main/webapp/WEB-INF/config/struts-config.xml: + Added new Action for Calling the Page with the Form for simmulating + the MapViewer-Interface-request. + Using the URL + http://localhost:8080/gnv/mvcall.do + you will retrieve the Formular with the MapViewer-Interface-Request-body + + * src/main/webapp/WEB-INF/jsp/header.jsp: + Added an Switch that will manage that the GUI with the Form of the + MapViewer-Interface-Document only will be displaied if it is requested. + + * src/main/java/de/intevation/gnv/action/mapviewer/ShowMapViewerCallBodyAction.java (execute): + Added new Action for handling the Request that should show the Form + for insterting the MapViewer-Interface-Document. + +2010-02-12 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Modified the Create-Artifact-Request-Body that a Geometry will be put into + the Parameter if one is given e.g. using the MapViewer-Interface request. + +2010-02-09 Tim Englich + + * src/test/ressources/externalinterfacecall_curl.xml, + src/test/ressources/samplecall.txt: + Added Sampledata and a sample how to call the MapViewer-Interface using CURL. + +2010-02-09 Tim Englich + + * src/main/webapp/styles/default.css: + Added some stylinginformation for the Textarea for the XML-Document. + * src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp: + Integrated an Textarea so that is possible to manipulate the XML-Document + which simulates the MapViewer-Interface-Body. + +2010-02-09 Tim Englich + + * src/main/java/de/intevation/gnv/action/mapviewer/MapViewerCallAction.java (execute): + Removed trailing and leading Whitespaces from the Parametervalue which + contains the XML-Document to avoid XML-Parsingerrors. + +2010-02-09 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (createMetaDataRequestBody): + Fixed a NPE. Now it is possible to put an Mapservice without an Layer into + the Request-Document of am Mapviewer-Interface-Call. + +2010-02-05 Ingo Weinzierl + + Issue170 + + * pom.xml: Changed log4j version to 1.2.14 (later version causes errors and + breaks maven build process). + +2010-02-02 Tim Englich + + * src/main/webapp/WEB-INF/jsp/header.jsp: + Added temporally Include of includes/display_mapviewercall_inc.jsp for the + Simulation of the MapViewer-Interface-Request. + + * src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp: + Added new Includefile with the Formular which includes the Data for the + Simulation of the MapViewer-Interface-Request. + +2010-02-01 Tim Englich + + * src/main/webapp/WEB-INF/config/struts-config.xml: + Added am Action for handling the MapViewer-Interface. + if /gnv/extcall.do is called the processing of the defined + Information will be done and the GUI will be displayed. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java: + Implementation of the interface ParametrizedArtifactObject fro the + representation of ArtifactFactories which has further Information. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactObject.java (addParameters): + Added new Interfacedefinition ParametrizedArtifactObjects for representing those + ArtifactObjects which includes further Informations. E.g. for creating an + new Artifact. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java (equals): + Override equals-method to get ap proper comparisons of the kinds of objects. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (getArtifactFactoryMetaInformation): + Added Method to retrieve Metainformations form the ArtifactDatabases. + Also added the possibility to send further Informations (e.g: Parameters) + in the Request-body of an Create-Artifact-Call. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (getArtifactFactoryMetaInformation): + Added Method to retrieve Metainformations form the ArtifactDatabases. + + * src/main/java/de/intevation/gnv/action/mapviewer/MapViewerCallAction.java (execute): + Added further Businesslogic to the Action which will handle the MapViewer- + InterfaceCall. Now the retrieved Informations will be sent to the + ArtifactDatabase an the retrieved Informations will be used to reduce + the displayed "Fachinformationssysteme". And also will be used to + send these Informations (e.g: Parameters) during the creation of an + new Artifact. + +2010-01-27 Hans Plum + + RELEASE 0.3 + + * Changes, NEWS, ChangeLog: Summerized activities + +2010-01-27 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Added a + workarround to avoid input failures caused by multi select boxes with only + one entry. They look like text input fields and don't force the user to + select a row. In this case, the single entry is selected automatically. + +2010-01-25 Ingo Weinzierl + + * src/main/webapp/styles/default.css: Added a class for dynamic tables + - enabled input fields - to adjust font size of input fields. + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: Removed + local-name() method, inserted a table for 'group' items (like input fields + of dates) and resized the height of multi select boxes - max 5 items or + less. + + * src/main/webapp/WEB-INF/jsp/index.jsp: Removed a typo which made the html + output invalid. + +2010-01-22 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Add width, + height and the boolean value to adjust the visibility of points in charts + to the pdf and svg export links. + +2010-01-22 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added legend for + summary box. + + * src/main/webapp/styles/default.css: Adapted some css classes regarding the + position of boxes and removed background image in fieldsets. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Removed + useless div container (div container is now outside the xsl sheet). + + * src/main/webapp/WEB-INF/jsp/index.jsp: Moved former parameter into a + fieldset and added a label to this fieldset. + +2010-01-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/ShowStatisticAction.java: This + action 'calculates' the statistic and shows the result in the gui. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added controller and + forwards. + + * src/main/webapp/images/statistics.png: Statistic icon. FIXME: Give a Source here! + + * src/main/webapp/WEB-INF/jsp/index.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp: Added symbol + in action box to show the statistic. + + * src/main/webapp/styles/default.css: Adjusted some parameter for a proper + placement of the statistic box. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for + statistic icon. + +2010-01-22 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/DescribeUIAction.java: New action. + The only task of this action is to parse the describe document and create + static and dynamic user interface out of it. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java, + src/main/java/de/intevation/gnv/action/DoOutputAction.java, + src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java, + src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java, + src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java: + Removed xsl transformation. Classes which needs xsl transformation inherit + from DescribeUIAction which does the transformation. Now, it is much + easier to write new actions, because they do not need to parse the + describe document and create static and dynamic user interfaces. + + Removed some useless imports. + +2010-01-22 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/index.jsp, + src/main/webapp/WEB-INF/jsp/header.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_adons_inc.jsp, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp: + - Improved the design and the usibility concept ("Bedienkonzept"). + Removed the useless "draw" button after reaching the last state which + has some output modes. + - Render chart options - if chart creation is possible for this state - and show + export actions. + - Moved chart options and export actions to the left side beneath the + static and dynamic panals for parameterization. + - Removed some warnings and errors regaring html conformance. + + * src/main/webapp/styles/default.css: Made some necessary adjustments + regarding the movement of chart option and action boxes. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for + action box. + + * src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java: + Removed pathes of xsl sheets from code and put them to a central place. + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Added + urls to xsl transformer for step-back links and create a dynamic ui only + if there is content for it - avoid creation of empty boxes. + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: Write + dynamic ui only if there is content. Some code formatting done. + + * src/main/webapp/images/back_button.png: Button to step back to a previous + state. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added forwards to fis + selection and previous states. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Enabled + link to step back to fis selection. + +2010-01-20 Ingo Weinzierl + + Issue149 + + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java: Show + chart if there are output modes existing for this state. Set internal + value of checkboxes to 'true' if they are selected. + + TODO: We should check if there is an output mode named 'chart' before + rendering a chart. + +2010-01-20 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for + char option 'draw data points'. + +2010-01-20 Ingo Weinzierl + + * src/main/webapp/styles/default.css, + src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Adapted + style of static ui to bsh style. Improved indentation. + +2010-01-19 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl, + src/main/webapp/WEB-INF/jsp/index.jsp: Commented links to step back in + history out and always render a fis select box (reason for this is the + next release and a too buggy 'step-back-history'). + +2010-01-19 Tim Englich + + * src/test/ressources/externalinterfacecall.xml: + Added an Request-Document which contains an Call which might be + send from the MapViewer to the GNV. + + * src/test/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserTestCase.java: + Added TestCase for testing the functionality of the XMLExternalCallParser-Implementation. + +2010-01-19 Tim Englich + * src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultMapService.java: + DefaultImplementation of the Interface MapService. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/map/MapService.java : + Added a new Interfacespecification for representing an MapService retrieved + by an MapViewer-Call + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultLayer.java: + DefaultImplementation of the Interface Layer. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/map/Layer.java: + Added a new Interfacespecification for representing an Layer retrieved + by an MapViewer-Call + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java + (getArtifactFactoryMetaInformation), src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java + (getArtifactFactoryMetaInformation): + Added new Method for retrieving Metainformation for the ArtifactFactories using + the Data which is parsed using the ExternalCallParser. + + * src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserException.java (ExternalCallParserException): + New ExceptionClass which is used to specify Exception which occurs during parsing + an ExternalCallParser. + + * src/main/java/de/intevation/gnv/action/mapviewer/parser/XMLExternalCallParser.java : + Added an Implementation of the Inteface ExternalCallParser which is able to parse + an XML-Document. + + * src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParser.java : + Added a new Interface which provides the required Methods for parsing an + Request from the MapViewer an provide the parsed Data. + + * src/main/java/de/intevation/gnv/action/mapviewer/MapViewerCallAction.java: + Added new Action which provied the reauired logic for Implementing the + Interface to the MapViewer. + +2010-01-18 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added a new controller + which causes a return to the point, where the user can choose a fis. + + * src/main/java/de/intevation/gnv/action/SelectFisAction.java: Controller to + reset the SessionModel and to jump back to fis selection. + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: Made + the link to return to the fis select box available in XSL. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Check the + 'fis' attribute is contained in select1 nodes and create a link in this + case. + +2010-01-18 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java: + Render the static part of the gui as well - not just the dynamic part. + + * src/main/webapp/WEB-INF/jsp/index.js: Do not include the fis combo box if + the describe document contains a static part, which means that the user + already selected a fis. + + * src/main/webapp/styles/default.css: Added 20px space at the top of the + static table. Otherwise the table hides the links to load and save + projects. + +2010-01-17 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Simpler + demo WKT polygon. + +2010-01-17 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: + Only render chart addons when we have a chart. + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: + Set right file extensions if we have WMS or ZIP export. + +2010-01-17 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: + Add links to download zip files and WMS layers if they are + available. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: + Added i10n for new download link types. + + * src/main/webapp/images/svg.png: New. Gimp rendered PNG + of official SVG logo. Creative Commons license. + + * src/main/webapp/images/pdf.png: New. Crystal pdf icon. + LGPLv2 license. + + * src/main/webapp/images/disk.png, src/main/webapp/images/map_go.png: + famfamfam icons for disk and map. Creative Commons license. + +2010-01-15 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java, + src/main/java/de/intevation/gnv/util/XSLTransformer.java: + Cleanup imports. + +2010-01-14 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: + Fixed a bug which caused that the user was not able to draw charts + anymore. Query the 'output' node of the describe document and render a + 'draw'-button if existing. If 'output' is not existing, render a 'select' + button to step forward to the next step. + +2010-01-13 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Added 'doAdvance' method to be able to advance only - without feed or + describe. We need this method to step back to previous states. Advance was + bundled with feed and describe, before. + + * src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java: + Some code refactoring. + + * src/main/java/de/intevation/gnv/util/XSLTransformer.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: Set + parameter of xsl transformer which contains the url to step back to a + previous state. This parameter is used in xsl sheet to render a + link into the user interface. + + * src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java: + New controller to step back to a previous state. + + * src/main/webapp/WEB-INF/config/struts-config.xml: Added a new action which + calls PreviousArtifactStepAction to step back to previous states. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + Refactored gui rendering. The static part of the parameter list is + rendered in a table with three columns (icon to step back, parameter name, + selected value). The target state to step back to is contained as + attribute 'art:state' in 'xform:select', 'xfom:select1' and 'xform:group' + nodes. + + * src/main/webapp/styles/default.css: Added a style class to adapt the first + column of the static part's table. + +2009-01-13 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Shortened + fractions digits to four places to be displayable in static + ui description. + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Fixed target id of text input field. + +2009-01-13 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp, + src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Added demo wkt polygon to test the "Horizontalschitt". + Remove this when we have the GIS interface. + +2010-01-09 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Use XMLUtils.ElementCreator to create new elements for xml documents. + +2010-01-08 Tim Englich + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute), + src/main/java/de/intevation/gnv/action/DoOutputAction.java (execute): + Removed Encodingerrors from listed Files. All Files are now UTF-8 compliant. + +2010-01-05 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/util/ArtifactNamespaceContext.java: + NamespaceContext class used by gnv artifacts. + + * src/main/java/de/intevation/gnv/util/XMLUtils.java: Added + ArtifactNamespaceContext as default namespace context while creating + XPath objects. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Removed + local-name() methods. + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java: Adjust + xpathes regarding namespace changes. + +2010-01-05 Ingo Weinzierl + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Removed + for-each statements and replaced them with templates. + +2010-01-04 Ingo Weinzierl + + * src/main/webapp/styles/default.css: Added new classes for displaying + parameters and values in left panel. + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: Static + nodes will be rendered as text instead of disabled xforms. + +2009-12-17 Sascha L. Teichmann + + RELEASE 0.3 + + * Changes, NEWS, ChangeLog: Summerized activities + +2009-12-17 Sascha L. Teichmann + + * src/main/resources/applicationMessages.properties: + s/Modeldaten/Modelldaten/ + +2009-12-17 Sascha L. Teichmann + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp: Added demo wkt linestrings + via xslt and javascript. + +2009-12-17 Hans Plum + + Issue 129: Release 0.2: Verbesserung der �bersetzungen + + * src/main/resources/applicationMessages.properties: + Fixed i18n strings reported by experts + +2009-12-14 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Added switch between boolean and other Values to determin wether a checkbox + is required or an text-field should be used. + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java (execute): + Added parsing of boolean-Option-Values to provide this Feature. + +2009-12-14 Hans Plum + + Issue109: Tomcat: Konfiguration des Kontexts enth�lt Redundanz + + * src/main/webapp/META-INF/context.xml: + Removed obsolete configuration attributes. + +2009-12-09 Sascha L. Teichmann + + * src/main/resources/applicationMessages.properties: Fixed some + spelling problems. + +2009-12-01 Tim Englich + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Removed feed Call before Chart- and Statisticsgeneration is called, because + it is not longer required by the Artifactdatabase. + + +2009-12-01 Ingo Weinzierl + + * src/main/webapp/WEB-INF/web.xml: Reverted changes in config from last + revision, which have been committed by mistake. + +2009-12-30 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Add svg + extension to file when exporting charts to svg. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for svg + export link. + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: Added link + for svg export in html gui. + +2009-12-30 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: Added + link for pdf export in html gui. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for pdf + export link. + + * src/main/java/de/intevation/gnv/action/DoExportAction.java: Added pdf + extension to file when exporting charts as pdf. + + NOTE: Update gnv-artifacts to rev381 which supports pdf export. + +2009-11-23 Tim Englich + + * src/main/resources/applicationMessages*.properties: + Added Properties which hold the Version-information of the + GNV which will be set by te Maven package-process. + * src/main/webapp/WEB-INF/config/struts-config.xml: + Added an Action which make the Version-Information accessible. + Now it is possible to get those Information using /version.do + * src/main/webapp/WEB-INF/jsp/version.jsp: + Added an Page where it is possible to get the Information about the current + Version of the GNV and the ArtifactDatabase + * pom.xml: + Added Plugin for creating the BildTime and BildVersion of the gnv. + Replace Tokens in the /src/main/ressources Files + +2009-11-20 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Removed mistake from xml structure of the artifact protocol. Mime-type + node was 'out' instead of 'mime-type'. + +2009-11-13 Hans Plum + + RELEASE-0.2 + + * Changes, NEWS: + Summerized activities. + +2009-11-13 Hans Plum + + * ChangeLog: + Unified entries with references to issues. + +2009-11-13 Tim Englich + + * src/main/webapp/WEB-INF/web.xml: + Added Documentation of Configuration-Entries. + +2009-11-12 Tim Englich + + * src/main/webapp/styles/default.css: + Added CSS-Entry for the Exception Message Container and + put the div at a proper place. + * src/main/resources/applicationMessages*.properties: + Added localized Exception Messages. + * src/main/webapp/WEB-INF/jsp/header.jsp: + Added the localization of Exception Messages. + +2009-11-12 Tim Englich + + Issue 71: Error while Serialisation of Sessions + + * src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java, + src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Imports organized. + * src/main/java/de/intevation/gnv/artifactdatabase/objects/*.java: + Made all Interfaces Serailizable and add UID to all Objects issue71 + +2009-11-12 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp: + Implemented a better GUI-Structure for displaying the Statisticdata. + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticsSet.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticsSet.java: + Added new Beanstructur for a better Representation of the Statistics which + is generated by the ArtifactDatabase. + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (calculateStatistics): + Changed the parsing algorithm of the Document which is generated + by the ArtifactDatabase. + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (calculateStatistics): + Changed Return-Value to ArtifacStatisticsSet according to the new Structur of + Statistics that will be generated by the ArtifactDatabase. + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Changed the Resultvalue from ArtifactStatisticValue to ArtifacStatisticsSet according + to API-Changes of the ArtifactDatabaseClient + +2009-11-11 Tim Englich + + Issue 80: Error handling when session got expired + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Catch NPE and tell the user that the Session has expired. issue80 + +2009-11-11 Tim Englich + + Issue 81: Input of coordinate values do not show up after update + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + Remove
Tag after Input-Elements + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Add an
-Tag after the generation of Select-Boxes to get + a better look and feel in the ui. issue81 + * src/main/webapp/WEB-INF/jsp/index.jsp: + Replace NonBreakingSpace-Strings from UI issue81 + +2009-11-11 Tim Englich + + Issue 81: Input of coordinate values do not show up after update + + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + BugFix: Text-Inputfields will now be diabaled in static-ui issue81 + +2009-11-06 Ingo Weinzierl + + * src/main/resources/applicationMessages.properties: Replaced german umlaut + witch ascii character. + +2009-11-06 Ingo Weinzierl + + * pom.xml: Changed Restlet repository from M3 to Snapshot. + +2009-11-06 Ingo Weinzierl + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: Added link + for exporting data in ODV format. + + * src/main/resources/applicationMessages.properties, + src/main/resources/applicationMessages_en.properties: Added label for + odv export and changed label of CSV export. + +2009-11-05 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java (ArtifactDatabaseClientFactory): + Removed some deprecatde TODO-Tasks. + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (getCurrentStepDescription): + Changed the Describe-Call of an Artifact from get to post an add the Flag which + determines if the UI should be delivered to the client. + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (getCurrentStepDescription): + Added the possibility to put an Flag which determines if the UI should be delivered from + the artifact-database to the Metodsignature. + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute), + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute), + src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java (execute), + src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java (testArtifactDatabaseClient): + Added the Flag if the UI should be delivered by the artifact-database to the Method-Call. + +2009-10-28 Tim Englich + + * src/main/resources/applicationMessages*.properties: + Added Ressources for two new FIS. Current Meter and Ice Station Reports + +2009-10-27 Tim Englich + + * src/main/resources/applicationMessages_en.properties: + Added Ressources for two new FIS. Seegangsarchiv and SEACAT + +2009-10-22 Tim Englich + + Issue 58: Behaviour by missing DB connection + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Bugfix NPE was thrown when an Exception occured in the Called ArtifactDatabase-Server issue58. + +2009-10-21 Tim Englich + + Issue 28: Client is not multi-instance enabled + + * src/main/webapp/META-INF/context.xml: + Added context.xml to permitt cookies to provide + Multisession-Usability for a single Client issue28 + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp: + Added URL-Rewrite to add the SessionID to the requested URL to get + the System work without cookies. issue28 + +2009-10-19 Tim Englich + + Issue 55: Unified input of coordinate input + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl, + src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + Added uniform Visualization of Single Input-Elements in GUI. issue55 + +2009-10-19 Tim Englich + + Issue 51: Translations for diagram options to be improved + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp, + src/main/resources/applicationMessages*.properties: + Integrated Ressouces for OutputOptions issue51 + +2009-10-19 Tim Englich + + Issue 35: Wrong data input forces GNV to start from beginning + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Now the UI will compelte be shown if the User has done an Mistake entering + values to input-fields eg. Coordinates or formatted Date-Strings. issue 35 + +2009-10-19 Tim Englich + + Issue 47: Improving translations in time series + + * src/main/resources/applicationMessages_en.properties: + Changed Lablevalues according to issue47 + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Add the possibility to render XForms-Group-Lables as Legend-Entries of + one Step in the GUI + +2009-10-16 Tim Englich + + Issue 48: Improving translation of statistics panel + + * src/main/resources/applicationMessages_en.properties: + Conformation to the tanslation of the Statisticsdescriptors issue48 + +2009-10-16 Tim Englich + + Issue 49: Integration of FIS to Mesh + + * src/main/resources/applicationMessages_en.properties: + Adding the Names of the two new FIS to the Propertiesfiles issue49 + +2009-10-07 Sascha L. Teichmann + + RELEASE 0.1 + + * Changes, NEWS: Summarized changes. + +2009-10-06 Tim Englich + + * src/main/resources/applicationMessages.properties Edited: + Removed obsolet Entries + * src/main/resources/applicationMessages_en.properties Added: + Added the Support for english-Language + +2009-10-06 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (doGetRequestInternal) Edited: + Read the Status-Code from the Response and throw an Exception + which Message will be visualized in the GUI. gnv/issue18 + +2009-10-08 Sascha L. Teichmann + + * Changelog -> ChangeLog: Moved to make eclipse happier. + +2009-10-08 Sascha L. Teichmann + + * Changelog: Unified changelog style. + +2009-10-08 Sascha L. Teichmann + + * pom.xml: Remove XMLBeans stuff, set filtered resources to UTF-8 + +2009-10-06 Tim Englich + + * src/main/webapp/index.jsp Added: + Added Index-Page for Global-Forward to Start-URL of the Project gnv/issue14 + * src/main/webapp/WEB-INF/config/struts-config.xml Edited: + Added Global Forward to determine the Start-URL of the Project. gnv/issue14 + +2009-10-06 Tim Englich + + * src/main/webapp/WEB-INF/jsp/header.jsp Edited: + Deaktivate Links save Project and load Project gnv/issue12 + +2009-10-05 Tim Englich + + * src/main/resources/applicationMessages.properties Edited: + Added some more FIS-Ressource. + +2009-10-02 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java (getArtifactDatabaseClient): + Putting the ClientLanguage into the getArtifactDatabaseClient-Signature. + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (setLocale) Edited, + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (setLocale) Edited: + Added the Support of Setting the ClientLanguage to the ArtifactDatabaseClient + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute) Edited, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited, + src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java (execute) Edited, + src/main/java/de/intevation/gnv/action/DoOutputAction.java (execute) Edited, + src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java(execute) Edited: + Put the Locale of the Calling Client to the Communication with the ArtifactDatabase. + + * src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java (testArtifactDatabaseClient) Edited: + Added DefaultLocale German to the ArtfactDataBaseClient call. + +2009-10-02 Tim Englich + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Edited, + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl Edited: + Switched Value for legend from ref-Attribute to Label-Element + * src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp Edited: + Added translation for FIS (ArtifactFactorynames) + * src/main/resources/applicationMessages.properties Edited: + Added Germannameds for FIS. + +2009-10-02 Tim Englich + + * src/**/*.java Edited: + Format Code to max 80 Chars per Row + +2009-10-02 Tim Englich + + * src/main/java/de/intevation/gnv/util/XSLTransformer.java CLEANUP , + src/main/java/de/intevation/gnv/util/XMLUtils.java CLEANUP , + src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java CLEANUP , + src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java CLEANUP , + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java CLEANUP , + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java CLEANUP , + src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java CLEANUP , + src/main/java/de/intevation/gnv/action/DoOutputAction.java CLEANUP: + Change non static accesses to static members using declaring type + Change indirect accesses to static members to direct accesses (accesses through subtypes) + Remove unused imports + Add missing '@Override' annotations + Add missing '@Deprecated' annotations + Remove unnecessary casts + +2009-10-02 Tim Englich + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute) Edited, + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited, + * src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java (execute) Edited, + * src/main/java/de/intevation/gnv/action/DoOutputAction.java (execute) Edited, + * src/main/java/de/intevation/gnv/action/DoExportAction.java (execute) Edited, + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java (execute) edited: + Added ExceptionHandling to this Actions + * src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java (getExceptionForward) Edited: + Added Method for Resolving the ExceptionForward from the Mapping. + * src/main/webapp/WEB-INF/jsp/header.jsp Edited: + Read ExceptionMessage from RequestAttributes + +2009-09-28 Tim Englich + + * src/main/resources/applicationMessages.properties Edited: + Adding missing StatisticsDescription for Arithmetic Mean. + +2009-09-28 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticValue.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticValue.java Added: + Added the Interface and the Defaultimplementation for the Representation of Statistic-Values. + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited: + Added the Busionesslogic for Calculation the Statistics to the Action. + * src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java Edited, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java Edited: + Added the Methods for setting and getting the statistics to the SessionModel + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (calculateStatistics) Edited, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (calculateStatistics) Edited: + Added the Method for retrieving the Statistics from the current Artifcat. + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp Edited: + Put the Values of the Statitics into the View. + * src/main/webapp/styles/default.css Edited: + Changed CSS-for Statistics so that it would be displayed. + +2009-09-25 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp Edited: + Bug fixed in CSV_Export Link + +2009-09-25 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java Edietd: + Integrated some Method for accessing and Setting OutputModes to an ArtifactDescription. + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputParameter.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputMode.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputParameter.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputMode.java Edited: + Adding some Beans and their InterfaceDescription for the Representation of OutputModes + supported by an Artifact + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Edited: + Fetsching the OutputMode-Informations from the Describedocument and put them into a Collection + of OutputModes. + + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java Edited: + Restet SessionModel integrated. + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java Edited: + Cast for ArtifactDescription removed. + + * src/main/java/de/intevation/gnv/action/DoOutputAction.java Edited, + src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java Edited: + Dynamical read of OutputParameter for Outputgeneration + + * src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java Edited:, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java Edited: + Added some Method for retrieving Diagrammoptions and reset the SessionModel + + * src/main/java/de/intevation/gnv/action/sessionmodel/DiagrammOptions.java Edited: + Dynamic Options Support Added + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp Edited: + Dynamic Rendring of the Outputparameters of an ArtifactoutputType added. + Ath this Moment only The Outputparameter for Chart ist provided. + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp Edited : + Integrated dynamic Setting of Diagramm-Parameter to the Link. + Also Read MimeType from the OPutputParameters of the Artifact. + +2009-09-25 Tim Englich + + * src/main/java/de/intevation/gnv/action/DoOutputAction.java Edited: + Some Refactoring work done. + Logging Integrated. Extract Method for setting Responseheader Informations. + + * src/main/java/de/intevation/gnv/action/DoExportAction.java Added: + Action for performing the Exports eg. CSV and Chart + * src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java Added: + Action for do the Bussinesslogic for storing the Diagrammoptions that were + changed by the User. + * src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java Edited, + * src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java Edited: + Added Accessmethod for the Diagrammoptions. + + * src/main/java/de/intevation/gnv/action/sessionmodel/DiagrammOptions.java Added: + Bean for the Representation of Diagrammoptions + + * src/main/resources/applicationMessages.properties Edited: + Added som GUI Lables. + + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp Edited, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp Add, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp Add, + src/main/webapp/WEB-INF/jsp/includes/display_diagramm_adons_inc.jsp Add: + Added the GUI for the Statistics and Diagramoptions and tge Export. + + * src/main/webapp/WEB-INF/config/struts-config.xml Edited: + Added Actions for Performing Exports and Changing Diagramoptions. + +2009-09-24 Tim Englich + + * src/main/webapp/scripts/gnviewer.js Edited: + Removed unused Methods from File. + +2009-09-24 Tim Englich + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp Edited: + Obsolet Javascript References Removed + Added Javascript-Reference to the gnviewer.js File + * src/main/webapp/WEB-INF/jsp/index.jsp Edited: + Please Wait Dialog integrated if an Form will be submittend + +2009-09-24 Tim Englich + + * src/main/webapp/scripts/gnviewer.js Added: + Added Javascript-File from Old-Project Revision: 3101 + +2009-09-24 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Edited: + Codecleanup + ExceptionReporthandling integrated + +2009-09-24 Tim Englich + + * src/main/webapp/WEB-INF/config/log4j.properties Added: + Standard Log4J-properties-File which will log all Informations to the Console. + * src/main/webapp/WEB-INF/web.xml Edited: + Added init-Parameter to tell the Application where the Log4J-propertiesfile ist located. + * src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java (init) Edited: + Reading Logging-Properties from Propertiesfile. Path maust beconfigured in the web.xml File + + +2009-09-23 Tim Englich + + * src/main/webapp/WEB-INF/web.xml Edited: + Added Count of ArtifactDatabases and Database-URL to this File + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (ARTIFACTDATABASE_URL_ID) Edited: + Added Static Constants for identifing ArtifactDatabase URLS in PropertiesReader + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java (initialize) Edited: + Read ArtifactDatabase URLS from PropertiesReader + +2009-09-23 Tim Englich + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited: + Removed Image-Element and put it into the jsp-Page + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp Edited: + Moved Image-Element from Classfile to this location. + URL will now be encoded for usage without cookies. + * src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp Edited, + src/main/webapp/WEB-INF/jsp/index.jsp Edited: + URL will now be encoded for usage without cookies. + +2009-09-23 Tim Englich + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Edited: + Selection on Input-UI-Data will be fetched from the UI and visualized + in the GUI. + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl Edited: + Single Text Input-Elements now will be surround with an div and an form Element + 2009-09-22 Tim Englich + + * src/main/java/de/intevation/gnv/util/XSLTransformer.java Edited: + Logging reduced for a better Performance. XML-Nodes should not be logged because their size could + cause Problems in Log4J and the ConsoleAppender of Eclipse + +2009-09-21 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Remnoved logging of Resultdocuments becaus it slow down the Application. + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute): + Added support of ArtifactFactory Reload if Session was lost. + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute): + Added Support of more than one Product. + +2009-09-17 Tim Englich + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Some Refactoring work done. + * src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl: + Added XSL-Template for Transforming the stazic UI + * src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp: + Refactored FIS Rendering to it's own Include-File + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: + Refactored Diagramm Rendering to it's own Include-File + * src/main/webapp/WEB-INF/jsp/index.jsp: + Some Refactoring Work done. + * src/main/webapp/styles/default.css: + Some Changes in DIV-Formatting to get a propper Layout. + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (NextArtifactStepAction): + Static UI integrated + +2009-09-17 Tim Englich + + * src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp: + Refactored FIS Rendering to it's own Include-File + * src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp: + Refactored Diagramm Rendering to it's own Include-File + * src/main/webapp/WEB-INF/jsp/index.jsp: + Some Refactoring Work done. + * src/main/webapp/styles/default.css: + Some Changes in DIV-Formatting to get a propper Layout. + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (NextArtifactStepAction): + Static UI integrated + +2009-09-16 Tim Englich + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited: + UI also Rendered when Chart is already visualized. + * src/main/webapp/WEB-INF/jsp/index.jsp: + Some Stylingfixes done. + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl: + Legend-Element for SelectEntries Integrated + +2009-09-16 Tim Englich + + * src/main/webapp/WEB-INF/jsp/mainlayout.jsp Edited, + src/main/webapp/WEB-INF/jsp/index.jsp Edited: + Integrate the new Pageinfrastructur into the Mainlayout + + * src/main/webapp/WEB-INF/config/struts-config.xml Edited: + Integrate message-resources into the Strutsconfiguration and change + the mainpage from index.jsp to mainlayout.jsp + +009-09-16 Tim Englich + + * src/main/webapp/WEB-INF/jsp/header.jsp Added, + src/main/webapp/WEB-INF/jsp/footer.jsp Added, + src/main/resources/applicationMessages.properties:Added, + src/main/webapp/WEB-INF/jsp/mainlayout.jsp Added, + src/main/webapp/styles/*, + src/main/webapp/scipts/*, + src/main/webapp/images/*: + Import of MainLayout, Styles, images and Scripts from old System Revision: 3101 Does not compile + +2009-09-16 Tim Englich + + * src/main/webapp/WEB-INF/config/struts-config.xml Edited, + src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Edited, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (doOutput) (doFeed) Edited, + src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java (execute) Edited, + src/main/java/de/intevation/gnv/action/DoOutputAction.java Added: + Chartoutput Added to the View + +2009-09-16 Tim Englich + + * src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java Edited: + Added Transformerlogic to the Testcase + + * src/main/webapp/WEB-INF/jsp/index.jsp Edited: + Integrated the UI of the Artifact + + * src/main/webapp/WEB-INF/config/struts-config.xml Edited: + Added ActionHandling for managing the next Businesslogic to go to the next Step of an Artifact + + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Edited: + Added Transformation-Rules for Input-Elements + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultInputParameter.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/objects/InputParameter.java Added: + Infrastructur for providing InputParametes as an Object + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java (getInputParameter) (setInputParameter) Edited: + Add Methods for providing the reuired Input-Parametes of the current ArtifactDescription + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Edited, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (doNextStep) Edited: + Added doNextStep Method for doing all ControllerWork to move the Artifact into the next Step + + * src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java Added: + Action for switching to the next Step of an Artifact + +2009-09-15 Tim Englich + + * src/test/java/de/intevation/gnv/util/XSLTransformerTestCase.java: + New Testcase for testing the usability of XSL-Transformations + * src/test/ressources/describe-ui-test.xml Added: + An Sample-Document for testing XSL-Transformations + * src/main/webapp/WEB-INF/jsp/index.jsp Edited: + Added the html-Fragment of the transformated Describe-Methode-response to the document. + * src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Added: + XSL-Template for transforming an Xform-Element to a HTML-Select-Element + * src/main/java/de/intevation/gnv/util/XSLTransformer.java Added: + XSl-Transformer for doing XSL-Transformations of the ResultDocuments of + the ArtifactDatabase + * src/main/java/de/intevation/gnv/util/XMLUtils.java Edited: + Integrate a Method for writing an XML-Node to a String for debugging. + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java: + Some Unused imports removed an select the first Child of the ui Node. + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java (execute) Edited: + Integration of the Describe-Stuff for rendering an GUi + +2009-09-15 Tim Englich + + * src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java (testArtifactDatabaseClient) Edited: + Added "Create Artifact" and "Describe Artifact" to the Testszenario. + +2009-09-14 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java, + src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java, + src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java: + Support for Initial DescribeCall to ArtifactDatabase implemented + +2009-09-14 Tim Englich + + * src/main/webapp/WEB-INF/config/struts-config.xml: + Added two ActionMappings: + One for showing all FIS (ArtifactFactories) in an View. + The other for selceting one ArtifactFactory an visualizing the First Step of an Artifact. + * src/main/webapp/WEB-INF/jsp/index.jsp Edited: + Added an Combobox for selecting an FIS + * src/main/webapp/WEB-INF/web.xml: + Added the Servletmapping for the Struts Framework + * src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java Added, + src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java Added, + src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java Edited: + Some ActionHandler added for Handling the different Requests of the GNV. + FetchArtifactFactoriesAction: Will provides the Controllerlogic for Queriing all Reachable ArtifactFactories. + SelectArtifactFactoryAction will select one Specific ArtifactFactory and will create + an Instance in the ArtifactDatabase. + + * src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java Added, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java Added, + src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java Added: + Interface and Defaultimplementation of an Model which can store the Session-Specific Informations. + e.g. Reachable ArtifactFactories and the current Artifact which should be used. + +2009-09-14 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Edited: + All Methods for doing the create-Request and reading the Result-Document implemented. + * src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java (createNewArtifact) Edited: + Add Method for creating a new Artifact in the ArtifactDatabase + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java (Artifact): + Added new Class for the Representation of an Artifact + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java (getHash) Edited, + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactObject.java (getHash) Edited + getHash Method added. Now it will be possible to read the Hash of an Artifact send by the Artifactdatabase. + * src/main/java/de/intevation/gnv/propertiesreader/PropertiesReaderFactory.java (getInstance) Edited: + Bug Fixed. factory will now be instantiated. + * src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java Edited, + Integration of temporal Basic Log4J Support. + +2009-09-11 Tim Englich + + * pom.xml: Further Dependencies and Plugins added + Deleted some utdated Files + +2009-09-11 Tim Englich + + * src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java Added: + Testcase for querying Artifacfactorydescriptions from the ArtifactDatabase + +2009-09-11 Tim Englich + + * src/main/webapp/WEB-INF/jsp/index.jsp Added , + src/main/webapp/WEB-INF/config/struts-config.xml Added, + src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java Added + src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java Added: + Basic Struts-Infrastructur Added + +2009-09-11 Tim Englich + + * src/main/java/de/intevation/gnv/propertiesreader/ServletPropertiesReader.java Added, + src/main/java/de/intevation/gnv/propertiesreader/PropertiesReaderFactory.java Added, + src/main/java/de/intevation/gnv/propertiesreader/PropertiesReader.java Added, + src/main/java/de/intevation/gnv/propertiesreader/MapPropertiesReader.java Added: + Infrastructur for Reading Properties from a Map or SercletConfig an provide them + to the whole Application. + +2009-09-11 Tim Englich + + * src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactObject.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java Added: + ObjectStructor for Representing delivered Objects from the ArtifactDatabase + + * src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseClientException.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java Added, + src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java Added: + Integrated Interface-Structure to handle the communication to the ArtifactDatabase + +2009-09-10 Tim Englich + + * .svnignore Added: Added Eclipse specific Files and Folders to the Ignorelist + +2009-09-10 Tim Englich + + * pom.xml: Created with maven and put the Moduledependencies into it + * Changes | Changelog | NEWS | README | TODO: Added + * src/**: Added to the Project diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/Changes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/Changes Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,127 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for renaming wms layers (#198) + + * Added control elements for saving and loading artifacts (#208). + Apache's commons.file-updload library is used for file upload. + + * Support for changing the language between german and english via + button in the gui. The intial language is determined by browser + settings. After the user changes this settings by clicking the button + in the gui, the browser locale is ignored in future (#30, #254) + + * Improved error handling. The user is able to reload the current + parameterization with the help of a link shown in the gui if an error + occured (#13). After clicking that link, the describe document of the + current artifact is requested and the gui is created again (#13, #18, + #236). + + * Improve input validation in chart/histogram panels. + + * Improve the design of the gui according to BSH style guides. + + FIXES: + + * Adjusted file extension of image exports (#187) + * Display time to live of an artifact (#197) + * Added missing character in the link to trigger an image export of + charts (#216) + * Restructuring of parameter-measurement matrix. Just the selection of + different depths is possible (#210) + * Added tooltip text for the step-back button (#227) + * Replace html characters to avoid html injections (#221) + * Adapted the MapServer path shown in the gui (#237) + * Fixed a bug in IE that avoided exporting charts as image (#259). + * Loading an artifact without running artifact server ends with a + warning and a message to try it later again (#258) + * Display an error message if the user tries to work with an outdated + artifact (#242) + * Repaired logging with log4j + + +2010-03-08 RELEASE 0.5 + + + +2010-01-27 RELEASE 0.4 + + New: + + * Improved internal handling of each selection state and + moved calculation step before rendering (instead of one step) + + * Internal Preparation of 1-step-back history: Split up in + static (Summary of parameters ) and dynamic section + (Selectable parameters) + + * Added support for Shapefile and WMS Handling if they are available + + * First implementation of MapViewer Interface + + * Improved structure of div-containers + + Fixed: + + * Width and height of diagramm made changeable for user (#149) + + +2009-12-17 RELEASE 0.3 + + New: + + * Support for WKT line strings in GUI in form of text fields. + * Added control for boolean values. + * Litte demo WKT line string via Javascrip to demonstrate + new WKT option. + * Drawing of diagrams is to be triggeres explicitly now. + * Added options to export diagrams as PDF and SVG. + * Little info about running version. + + Fixed: + + * Various i18n messages (Issue 129) + * Removed some redundancy from the Tomcat configuration (Issue 109) + * Some communication problems with the artifact database server. + +2009-11-13 RELEASE 0.2 + + New: + + * Enable client for multi-instances in the same browser by using + SessionIDs + + * Added support for all FIS + * Added support for skipping transition steps + * Added support for CSV and ODV formats via a common mechanism + * Updated to a newer version of RESTlet API + * Added first documentation for configuration + + +2009-10-07 RELEASE 0.1 + + New: + + * Initial Struts 1.x based Web-Client for the REST based + artifact database. + + * UI mainly inspired by the prototype from conterra. + + * It implements a runtime system for working with artifacts + by storing a client side proxy model in the session of + the servlet context. The workflow is completely controlled + by the artifact living in the artifact database. + + * The input forms are generated by XSL transformation from + the 'describe' output of the artifact. + + * Output is rendered as PNG, downloadable PNGs, CSV and + statistics all produced serverside in the artifact database. + + * i18n/i10n is done by Struts and broadcasted via REST to + the REST beased artifact database. Supported languages: + German and English + + * The connection to the REST server is configure in web.xml + default: http://localhost:8181 diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/NEWS Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,83 @@ +2010-04-28 RELEASE 1.0 + + NEW: + + * Support for renaming wms layers + + * Added control elements in the gui for saving and loading projects + + * Support for changing the language between german and english via + button in the gui. + + * Improved error handling. The user is able to reload the current + parameterization with the help of a link shown in the gui if an error + occured. + + * Improve the design of the gui according to BSH style guides. + + +2010-03-08 RELEASE 0.5 + + +2010-01-27 RELEASE 0.4 + + * Adapted GUI to new concept + * handling selected parameters in a central summary to make GUI + more compact + * Splitting date selections into 2 steps: yearly and + exact point of time + * Enabling Point-Rendering for rendering in diagrams + * arranging productspecific actions (Exports, Statistics) + in a central field in order to have direct access to end products + at one place + + * Added support for Shapefile Download + + * Added first mechanism for publishing as Cross-sections as WMS + + * Reworked HTML to be HTML standard compatible + + * Added some new icons + + * Integrated basic styling of BSH + + * Added WKT-Line and Polygon Input for (temporary testing only) + + +2009-12-17 RELEASE 0.3 + + * PDF and SVG export of diagrams. + * support for WKT line strings + * Fixed some internal communication problems. + + +2009-11-13 RELEASE 0.2 + + * Added support for all required FIS: + Marnet, IMIS, STAUN, Modelldaten, Eisklimatologie, Eismeldungen, SST, + Delphin, Thermosalinograph, Chemusurvey, GTS, CTD, XBT, SeaCat, + Seegangsarchiv, Strommesser (Req. TG_0020.001) + + * Added support for vertical profiles (Chapter 3.3.3.2.2) + + * Added support for horizontal profiles (Chapter 3.3.3.2.3); + part independent of MapViewer + + * Added a first support for ODV format (Req. TG_0040.005) + + * Enabling client for multi-instances (Req. 00_0000.007) + + * Adding of support of internal area filter (Req. TG_0020.012 b) + + * Added more support for internationalization (TG_0050.004) + + * Improved error handling with more user-friendly messages + + * Added required statistical support (Chapter 3.3.3.3.1) + + +2009-10-07 RELEASE 0.1 + + * Initial realease of the web client which is a lightweight + runtime system for artifacts. + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/pom.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,163 @@ + + 4.0.0 + de.intevation.bsh + gnv + war + 1.0-SNAPSHOT + gnv + http://maven.apache.org + + UTF-8 + + + + maven-restlet + Public online Restlet repository + http://maven.restlet.org + + + + + commons-fileupload + commons-fileupload + 1.2.1 + + + junit + junit + 3.8.1 + test + + + org.restlet + org.restlet + 2.0-SNAPSHOT + + + org.restlet + org.restlet.ext.xml + 2.0-SNAPSHOT + + + tomcat + servlet-api + 5.5.15 + provided + + + struts + struts-el + 1.2.9 + runtime + + + struts + struts + 1.2.9 + compile + + + log4j + log4j + 1.2.14 + + + + gnv + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + maven-war-plugin + + + + ${basedir}/src/main/webapp + + images/ + WEB-INF/jsp/application/ + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + de.intevation.artifactdatabase.App + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.1 + + java + + -classpath + + de.intevation.artifactdatabase.App + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + + true + true + 1.5 + + 1.2.3 + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-2 + + + initialize + + create + + + + + false + false + {0, date, yyyy-MM-dd HH:mm:ss} + {0,date,yyyy-MM-dd HH:mm:ss} + + timestamp + + + no_revision + + + + + + + + + src/main/resources + true + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/ArtifactDatabaseActionBase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,78 @@ +package de.intevation.gnv.action; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * @author Tim Englich + * + */ +public class ArtifactDatabaseActionBase extends Action { + + protected final static String SUCCSESS_FORWARD_ID = "success"; + protected final static String EXCEPTION_FORWARD_ID = "success"; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(ArtifactDatabaseActionBase.class); + + /** + * Constructor + */ + public ArtifactDatabaseActionBase() { + super(); + } + + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("ArtifactDatabaseActionBase.execute"); + + ActionForward forward = mapping.findForward(SUCCSESS_FORWARD_ID); + return forward; + } + + + protected ActionForward getExceptionForward(ActionMapping mapping) { + log.debug("ArtifactDatabaseActionBase.getExceptionForward"); + ActionForward lForward = mapping.findForward(EXCEPTION_FORWARD_ID); + return lForward; + } + + + protected String encode(String s) { + log.debug("String to encode: " + s); + s = s.replaceAll("<", "<"); + s = s.replaceAll(">", ">"); + s = s.replaceAll("\"", """); + s = s.replaceAll("&", "&"); + + log.debug("Encoded string: " + s); + return s; + } + + + protected String[] encode(String[] s) { + if (s == null) + return null; + + String[] good = new String[s.length]; + for (int i = 0; i < good.length; i++) { + good[i] = encode(s[i]); + } + + return good; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/ChangeOptionsAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,196 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.DiagrammOptions; +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; +import de.intevation.gnv.artifactdatabase.objects.OutputParameter; + +import java.text.NumberFormat; +import java.text.ParseException; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is called to change options used in charts and histograms + * (e.g. width, height, etc). + * + * @author Tim Englich + */ +public class ChangeOptionsAction extends DescribeUIAction { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ChangeOptionsAction.class); + + /** + * Constructor + */ + public ChangeOptionsAction() { + super(); + } + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("NextArtifactStepAction.execute"); + try { + SessionModel sm = SessionModelFactory.getInstance() + .getSessionModel(request); + + ArtifactDescription ad = sm.getArtifactDescription(); + + String target = request.getParameter("target"); + OutputMode outputMode = sm.getOutputMode(target); + if (outputMode != null) { + + Collection op = outputMode + .getOutputParameters(); + if (op != null) { + Iterator it = op.iterator(); + DiagrammOptions diagrammOptions = new DiagrammOptions(); + while (it.hasNext()) { + OutputParameter parameter = it.next(); + String name = parameter.getName(); + String old = parameter.getValue(); + String value = request.getParameter(name); + String type = parameter.getType(); + + if (log.isDebugEnabled()) { + log.debug("Change chart options now..."); + log.debug("Parameter name: " + name); + log.debug("Parameter type: " + type); + log.debug("Parameter value: " + value); + } + + if (type.equalsIgnoreCase("boolean")){ + if (value == null){ + value = "false"; + } + else { + value = "true"; + } + + diagrammOptions.setValue(name,value); + } + else if (type.equalsIgnoreCase("integer")) { + if (validInteger(request.getLocale(), value)) { + diagrammOptions.setValue(name, value); + } + else { + log.warn("Text is not a valid integer: "+value); + diagrammOptions.setValue(name, old); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE, + "input.not.a.integer" + ); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_VALUE, + value + ); + } + } + else if (type.equalsIgnoreCase("double")) { + if (validDouble(request.getLocale(), value)) { + diagrammOptions.setValue(name, value); + } + else { + log.warn("Text is not a valid double: "+value); + diagrammOptions.setValue(name, old); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE, + "input.not.a.double" + ); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_VALUE, + value + ); + } + } + } + sm.setDiagrammOptions(diagrammOptions); + + // XXX Little workarround. We should implement a 'choice' type, + // if we need further choice elements! (iw) + String bintype = request.getParameter("bintype"); + if (bintype != null) { + diagrammOptions.setValue("bintype", bintype); + sm.setDiagrammOptions(diagrammOptions); + request.setAttribute("bintype", bintype); + } + } + } + + Map tmpOuts = ad.getOutputModes(); + if (tmpOuts == null || tmpOuts.isEmpty()) { + request.setAttribute("furthertargets", true); + } + else { + request.setAttribute(target, true); + } + + return super.execute(mapping, form, request, response); + } catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, e + .getMessage()); + return super.getExceptionForward(mapping); + } + } + + protected boolean validInteger(Locale locale, String value) { + try { + if (value.split("\\.").length > 1 || value.split("\\,").length > 1){ + return false; + } + + NumberFormat format = NumberFormat.getIntegerInstance(locale); + format.setParseIntegerOnly(true); + Number number = format.parse(value); + + if (number.longValue() < 0) + return false; + + return (number instanceof Integer) || (number instanceof Long); + } + catch (ParseException pe) { + return false; + } + } + + protected boolean validDouble(Locale locale, String value) { + try { + NumberFormat format = NumberFormat.getInstance(locale); + Number number = format.parse(value); + + if (number.doubleValue() < 0) + return false; + + return (number instanceof Double) || validInteger(locale, value); + } + catch (ParseException pe) { + return false; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/CommunicationKeys.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/CommunicationKeys.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,36 @@ +package de.intevation.gnv.action; + +/** + * This class defines some keys used to store different exception types in the + * session. + * + * @author Tim Englich + */ +public class CommunicationKeys { + /** + * The Key which should be used for accessing ExceptionMessages + */ + public final static String REQUEST_EXCEPTION_MESSAGE_ID = "request_exception_message_id"; + + /** + * Key used to store exceptions relating to wrong user input. + */ + public final static String REQUEST_EXCEPTION_INPUT_ID = "request_exception_input_id"; + + /** + * Key used to store exceptions relating to more general errors occured in + * the server. + */ + public final static String REQUEST_EXCEPTION_MESSAGE = "request_exception_message"; + + /** + * Key used to store exceptions relating to an invalid input format. + */ + public final static String REQUEST_EXCEPTION_VALUE = "request_exception_value"; + + /** + * Key used to store exceptions relating to a load/save project error. + */ + public final static String REQUEST_EXCEPTION_PROJECT = "request_exception_project"; +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/CreateChartAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/CreateChartAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is called to display charts.
+ * An attribute 'chart' on the request object is activated which inserts an + * image calling a chart output of the server. + * + * @author Ingo Weinzierl + */ +public class CreateChartAction extends DescribeUIAction { + + private static Logger logger = Logger.getLogger(CreateChartAction.class); + + + public CreateChartAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception { + logger.debug("Create chart."); + + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + sm.setDiagrammOptions(null); + request.setAttribute("chart", true); + + return super.execute(mapping, form, request, response); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/CreateHistogramAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/CreateHistogramAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is called to display histograms.
+ * An attribute 'histogram' on the request object is activated which inserts an + * image calling a histogram output of the server. + * + * @author Ingo Weinzierl + */ +public class CreateHistogramAction extends DescribeUIAction { + + private static Logger logger = Logger.getLogger(CreateHistogramAction.class); + + + public CreateHistogramAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception { + logger.debug("Create histogram."); + + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + sm.setDiagrammOptions(null); + request.setAttribute("histogram", true); + + return super.execute(mapping, form, request, response); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/DescribeUIAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/DescribeUIAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,161 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import de.intevation.gnv.util.ArtifactNamespaceContext; +import de.intevation.gnv.util.XMLUtils; +import de.intevation.gnv.util.XSLTransformer; + +import java.util.Locale; +import java.util.ResourceBundle; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.apache.struts.Globals; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +import org.w3c.dom.Node; + +/** + * This controller is called to fetch the current artifact description using the + * describe operation. The describe document is used to feed an XSL transformer + * that parses the xml and creats html output representing the parameter panel. + * The html code is stored as attribute on the request object which is queried + * in a jsp page later. + * + * @author Ingo Weinzierl + */ +public class DescribeUIAction extends ArtifactDatabaseActionBase { + + public static final String XPATH_DYNAMIC_UI = "art:dynamic"; + public static final String XPATH_STATIC_UI = "art:static"; + + public static final String XSL_SHEET_DYNAMIC = + "WEB-INF/config/templates/describe-ui.xsl"; + + public static final String XSL_SHEET_STATIC = + "WEB-INF/config/templates/describe-ui-static.xsl"; + + private static Logger logger = Logger.getLogger(DescribeUIAction.class); + + + public DescribeUIAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response + ) throws Exception + { + logger.info("describe user interface"); + try { + // render describe document and create user interface + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + Locale tmp = sm.getCurrentLocale(); + Locale locale = tmp != null ? tmp : request.getLocale(); + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance().getArtifactDatabaseClient(locale); + request.getSession().setAttribute(Globals.LOCALE_KEY, locale); + ArtifactObject artifactFactory = sm.getSelectedArtifactFactory(); + + if (artifactFactory == null) { + logger.error("No connection to artifact server."); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + "java.io.ioexception..connection.refused"); + + return super.getExceptionForward(mapping); + } + + ArtifactDescription artifactDescription = + adc.getCurrentStepDescription( + artifactFactory, + sm.getCurrentArtifact(), + true); + + Node currentUI = artifactDescription.getCurrentUI(); + if (currentUI != null) { + ResourceBundle res = ResourceBundle.getBundle( + "applicationMessages", locale); + String editText = res.getString("gnviewer.history.back.button"); + + XSLTransformer transformer = new XSLTransformer(); + + String url = response.encodeURL( + mapping.findForward("back").getPath()); + transformer.addParameter("back-url", url); + transformer.addParameter("edit", editText); + + String fisUrl = response.encodeURL( + mapping.findForward("selectfis").getPath()); + transformer.addParameter("selectfis", fisUrl); + + // fetch dynamic part from describe document and transform it + Node dynamicNode = (Node) XMLUtils.xpath( + currentUI, + XPATH_DYNAMIC_UI, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE + ); + + String ui = transformer.transform( + dynamicNode, + "UTF-8", + request.getRealPath(XSL_SHEET_DYNAMIC + )); + + if (ui != null && ui.length() > 1) + request.setAttribute("ui", ui); + + // fetch static part from describe document and transform it + Node staticNode = (Node) XMLUtils.xpath( + currentUI, + XPATH_STATIC_UI, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE + ); + + String staticUI = transformer.transform( + staticNode, + "UTF-8", + request.getRealPath(XSL_SHEET_STATIC)); + + if (staticUI != null && staticUI.length() > 1) + request.setAttribute("staticui", staticUI); + } + + return super.execute(mapping, form, request, response); + } + catch (Exception e) { + logger.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + + return super.getExceptionForward(mapping); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/DoExportAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/DoExportAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,212 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter; +import de.intevation.gnv.artifactdatabase.objects.ExportMode; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; +import de.intevation.gnv.artifactdatabase.objects.OutputParameter; + +import java.io.OutputStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is called to trigger an export (e.g. pdf, svg, image). A + * 'save-file' dialog is opened to save the export. + * + * @author Tim Englich + */ +public class DoExportAction extends ArtifactDatabaseActionBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(DoExportAction.class); + + /** + * Constructor + */ + public DoExportAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception + { + try { + String target = request.getParameter("target"); + String mimeType = request.getParameter("mimetype"); + String mode = request.getParameter("mode"); + + log.debug("Target: " + target); + log.debug("MimeType: " + mimeType); + log.debug("ExportMode: " + mode); + + SessionModel sm = SessionModelFactory.getInstance() + .getSessionModel(request); + OutputMode outputMode = sm.getOutputMode(target); + if (outputMode != null) { + ExportMode exportMode = outputMode.getExportMode(mode); + + if (target.equals(mode) || (exportMode != null + && exportMode.getMimeType().equals(mimeType))) + { + Collection inputParameter = outputMode + .getOutputParameters(); + Collection ips = null; + if (inputParameter != null) { + ips = new ArrayList(inputParameter.size()); + Iterator it = inputParameter.iterator(); + while (it.hasNext()) { + String name = it.next().getName(); + String[] values = request.getParameterValues(name); + InputParameter ip = new DefaultInputParameter(name, + values); + ips.add(ip); + } + } + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)); + + this.setHeaders(mode, mimeType, response, request); + + OutputStream outputStream = response.getOutputStream(); + adc.doOutput( + sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact(), + outputStream, + target, + mode, + mimeType, + ips); + + outputStream.flush(); + outputStream.close(); + } + else if (exportMode == null) { + Collection inputParameter = outputMode + .getOutputParameters(); + Collection ips = null; + if (inputParameter != null) { + ips = new ArrayList(inputParameter.size()); + Iterator it = inputParameter.iterator(); + while (it.hasNext()) { + String name = it.next().getName(); + String[] values = request.getParameterValues(name); + InputParameter ip = new DefaultInputParameter(name, + values); + ips.add(ip); + } + } + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)); + + this.setHeaders(target, mimeType, response, request); + + OutputStream outputStream = response.getOutputStream(); + adc.doOutput( + sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact(), + outputStream, + target, + mode, + mimeType, + ips); + + outputStream.flush(); + outputStream.close(); + } + else { + if (outputMode == null) { + log.error("Outputmode is not supported."); + } + else if (!exportMode.getMimeType().equals(mimeType)) { + log.error("MimeType "+mimeType+" wis not supported."); + } + // TODO FIXME: Fehlerbehandlung + } + } + return super.execute(mapping, form, request, response); + } catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, e + .getMessage()); + return super.getExceptionForward(mapping); + } + } + + protected void setHeaders(String target, String mimeType, + HttpServletResponse response, + HttpServletRequest request) { + log.debug("DoExportAction.setHeaders"); + try { + response.setHeader("Content-Type", mimeType); + String fileName = "GNVEXPORT_" + System.currentTimeMillis() + "."; + + target = target.toLowerCase(); + log.debug("******************************************************"); + log.debug("TARGET: " + target); + log.debug("MIMETYPE: " + mimeType); + + if (target.equals("chart")) { + fileName = fileName + + mimeType.substring(mimeType.indexOf("/") + 1); + } + else if (target.equals("histogram")) { + fileName = fileName + + mimeType.substring(mimeType.indexOf("/") + 1); + } + else if (target.equals("img")) { + fileName = fileName + + mimeType.substring(mimeType.indexOf("/") + 1); + } + else if (target.equals("pdf")) { + fileName = fileName + "pdf"; + } else if (target.equals("svg")) { + fileName = fileName + "svg"; + } else if (target.equals("csv")) { + fileName = fileName + "csv"; + } else if (target.equals("zip")) { + fileName = fileName + "zip"; + } else if (target.equals("wms")) { + fileName = fileName + "xml"; + } else { + fileName = fileName + "txt"; + } + log.debug("FileName for Export: " + fileName); + response.setHeader("Content-Disposition", "attachment;filename=" + + fileName); + } catch (Exception e) { + log.error(e, e); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/DoOutputAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/DoOutputAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,136 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; +import de.intevation.gnv.artifactdatabase.objects.OutputParameter; + +import java.io.OutputStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller calls the out operation of the server directly. Html img-tags + * in jsp pages use this action to fetch charts and histograms. + * + * @author Tim Englich + * + */ +public class DoOutputAction extends ArtifactDatabaseActionBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(DoOutputAction.class); + + /** + * Constructor + */ + public DoOutputAction() { + super(); + } + + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("DoOutputAction.execute"); + try { + String target = request.getParameter("target"); + String mimeType = request.getParameter("mimetype"); + String mode = request.getParameter("mode"); + + log.debug("Target: " + target); + log.debug("MimeType: " + mimeType); + log.debug("ExportMode: " + mode); + + // TODO Check if is propper; + + SessionModel sm = SessionModelFactory.getInstance() + .getSessionModel(request); + OutputMode outputMode = sm.getOutputMode(target); + if (outputMode != null && outputMode.getMimeType().equals(mimeType)) { + Collection inputParameter = outputMode + .getOutputParameters(); + Collection ips = null; + if (inputParameter != null) { + ips = new ArrayList(inputParameter.size()+1); + Iterator it = inputParameter.iterator(); + while (it.hasNext()) { + String name = it.next().getName(); + String[] values = request.getParameterValues(name); + InputParameter ip = new DefaultInputParameter(name, + values); + ips.add(ip); + } + + if (request.getParameter("bintype") != null) { + InputParameter ip = new DefaultInputParameter( + "bintype", request.getParameterValues("bintype")); + ips.add(ip); + } + } + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)); + + this.setHeaders(target, mimeType, response, request); + + OutputStream outputStream = response.getOutputStream(); + adc.doOutput( + sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact(), + outputStream, + target, + mode, + mimeType, + ips); + + outputStream.flush(); + outputStream.close(); + } else { + if (outputMode == null) { + log.error("Outputmode is not supported."); + } else if (!outputMode.getMimeType().equals(mimeType)) { + log.error("MimeType " + mimeType + + " wis not supported."); + } + // TODO FIXME: Fehlerbehandlung + } + return super.execute(mapping, form, request, response); + } catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, e + .getMessage()); + return super.getExceptionForward(mapping); + } + } + + protected void setHeaders(String target, String mimeType, + HttpServletResponse response, + HttpServletRequest request) { + response.setHeader("Content-Type", mimeType); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,78 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import java.util.Collection; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller fetches artifact factories from artifact server and stores + * them on a SessionModel object. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class FetchArtifactFactoriesAction extends ArtifactDatabaseActionBase { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(FetchArtifactFactoriesAction.class); + + public FetchArtifactFactoriesAction() { + super(); + } + + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("ArtifactDatabaseActionBase.execute"); + try { + Collection artifactFactories = + ArtifactDatabaseClientFactory.getInstance() + .getArtifactDatabaseClient(getLocale(request)) + .getArtifactFactories(); + + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + + sm.setArtifacteFactories(artifactFactories); + + return super.execute(mapping, form, request, response); + } + catch (ArtifactDatabaseClientException e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + + return super.getExceptionForward(mapping); + } + catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + + return super.getExceptionForward(mapping); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/LoadAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/LoadAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,167 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException; + +import de.intevation.gnv.artifactdatabase.objects.Artifact; +import de.intevation.gnv.artifactdatabase.objects.ArtifactFactory; + +import de.intevation.gnv.util.ArtifactNamespaceContext; +import de.intevation.gnv.util.XMLUtils; + +import java.io.IOException; +import java.io.InputStream; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; + +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +import org.w3c.dom.Document; + +/** + * This controller is called for reloading projects from xml files. It waits for + * an xml document named 'document' and feeds the artifact server with this + * document. After a successful feed, the artifact description is fetched and + * displayed in the gui. + * + * @author Ingo Weinzierl + */ +public class LoadAction extends ArtifactDatabaseActionBase { + + public static final String RESOURCE_UPLOAD_FAILURE = "upload.failure"; + public static final String RESOURCE_INVALID_ARTIFACT = "invalid.artifact"; + + private static Logger logger = Logger.getLogger(LoadAction.class); + + public LoadAction() { + super(); + } + + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception + { + logger.info("Import artifact."); + + ServletFileUpload upload = new ServletFileUpload(); + Document artifactDocument = null; + + try { + FileItemIterator iter = upload.getItemIterator(request); + while (iter.hasNext()) { + FileItemStream item = (FileItemStream) iter.next(); + String name = item.getFieldName(); + + // the file input field of our form is named 'document' + if (name.equals("document")) { + InputStream stream = item.openStream(); + + if (stream.available() == 0) { + logger.error("No artifact document found."); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_PROJECT, + RESOURCE_UPLOAD_FAILURE); + + return super.getExceptionForward(mapping); + } + + artifactDocument = XMLUtils.readDocument(stream); + if (artifactDocument == null) { + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_PROJECT, + RESOURCE_INVALID_ARTIFACT); + + return super.getExceptionForward(mapping); + } + + try { + ArtifactDatabaseClientFactory adcf = + ArtifactDatabaseClientFactory.getInstance(); + ArtifactDatabaseClient adc = + adcf.getArtifactDatabaseClient(getLocale(request)); + ArtifactFactory factory = (ArtifactFactory) + (( List)adc.getArtifactFactories()).get(0); + + SessionModelFactory sf = + SessionModelFactory.getInstance(); + SessionModel sm = sf.getSessionModel(request); + sm.selectArtifactFactory(factory.getId()); + + Document describe = adc.doImport( + factory, + artifactDocument); + + String uuid = XMLUtils.xpathString( + describe, + "/art:result/art:uuid/@value", + ArtifactNamespaceContext.INSTANCE); + String hash = XMLUtils.xpathString( + describe, + "/art:result/art:hash/@value", + ArtifactNamespaceContext.INSTANCE); + + Artifact artifact = new Artifact(uuid, hash); + sm.setCurrentArtifact(artifact); + + if (logger.isDebugEnabled()) { + logger.debug( + "Imported artifact UUID: "+artifact.getId()); + logger.debug( + "Imported artifact HASH: "+artifact.getHash()); + } + } + catch (ArtifactDatabaseClientException adce) { + logger.error(adce, adce); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + adce.getMessage()); + + // XXX + return super.getExceptionForward(mapping); + } + + return new DescribeUIAction().execute( + mapping, form, request, response); + } + } + } + catch (IOException ioe) { + logger.error(ioe, ioe); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_PROJECT, + ioe.getMessage()); + + return super.getExceptionForward(mapping); + } + + // no document found or not valid + logger.error("Upload failure: No document found or invalid."); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_PROJECT, + RESOURCE_UPLOAD_FAILURE); + + return super.getExceptionForward(mapping); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,166 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller feeds the artifact server with the current input data and + * refreshes the gui with the current artifact description after the next state + * is reached. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class NextArtifactStepAction extends DescribeUIAction { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(SelectArtifactFactoryAction.class); + + /** + * Constructor + */ + public NextArtifactStepAction() { + super(); + } + + /** + * @see de.intevation.gnv.action.ArtifactDatabaseActionBase#execute(org.apache.struts.action.ActionMapping, + * org.apache.struts.action.ActionForm, + * javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("NextArtifactStepAction.execute"); + SessionModel sm = SessionModelFactory.getInstance() + .getSessionModel(request); + ArtifactDescription ad = sm.getArtifactDescription(); + + Locale tmp = sm.getCurrentLocale(); + Locale locale = tmp != null ? tmp : request.getLocale(); + + if (ad != null){ + Collection inputParameter = ad.getInputParameter(); + Collection ips = null; + if (inputParameter != null) { + ips = new ArrayList(inputParameter.size()); + Iterator it = inputParameter.iterator(); + while (it.hasNext()) { + String name = it.next(); + String[] values = request.getParameterValues(name); + InputParameter ip = new DefaultInputParameter(name, values); + ips.add(ip); + } + } + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance().getArtifactDatabaseClient(locale); + + Map outs = ad.getOutputModes(); + if (outs == null || outs.isEmpty()) { + // TODO: Woher kommt der zu erreichende Status; + String target = null; + if (ad.getReachableStates().size() > 1) { + target = request.getParameter("product"); // TODO HACK for + // Propducts every + // other Step has + // currently only + // one reachable + // state. + } else { + target = ad.getReachableStates().iterator().next(); + } + + try { + adc.doNextStep( + sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact(), + target, + ips + ); + } + catch (ArtifactDatabaseInputException e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID, + e.getMessage()); + } + catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + } + + Map tmpOuts = ad.getOutputModes(); + request.setAttribute( + "furthertargets", + tmpOuts == null || tmpOuts.isEmpty() + ); + } else { + try{ + adc.getCurrentStepDescription( + sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact(), + true + ); + + request.setAttribute("diagramm", true); + + } + catch (ArtifactDatabaseInputException e) { + log.debug("================ CATCH ME ======================"); + log.debug("===== ERROR MSG: " + e.getMessage()); + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID, + e.getMessage()); + } + catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + } + + request.setAttribute("furthertargets", false); + } + }else{ + log.warn("SessionTimeout has occured"); + request.setAttribute(CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + "SessionTimeout has occured"); + new FetchArtifactFactoriesAction().execute(mapping, form, request, response); + } + return super.execute(mapping, form, request, response); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/PreviousArtifactStepAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,96 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is used to step back to a previous state of the current + * artifact. After calling the advance operation of the artifact server have + * been called successfully, the describe document of the current artifact is + * fetched and a new gui is rendered. + * + * @author Ingo Weinzierl + */ +public class PreviousArtifactStepAction extends DescribeUIAction { + + + public static final String URL_STATE_KEY = "target"; + + private static Logger logger = + Logger.getLogger(PreviousArtifactStepAction.class); + + + public PreviousArtifactStepAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response + ) throws Exception { + + SessionModel session = SessionModelFactory.getInstance().getSessionModel( + request); + + ArtifactDescription ad = session.getArtifactDescription(); + if (ad == null) { + logger.warn("Session timed out."); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + "SessionTimeout has occured"); + new FetchArtifactFactoriesAction().execute( + mapping, form, request, response); + + return super.execute(mapping, form, request, response); + } + + // TODO check if target is reachable + + ArtifactDatabaseClientFactory f = + ArtifactDatabaseClientFactory.getInstance(); + ArtifactDatabaseClient client = + f.getArtifactDatabaseClient(getLocale(request)); + + ArtifactObject artifactFactory = session.getSelectedArtifactFactory(); + ArtifactObject currentArtifact = session.getCurrentArtifact(); + + String target = (String) request.getParameter(URL_STATE_KEY); + logger.debug("Step back to previous state: " + target); + + try { + client.doAdvance( + artifactFactory, + currentArtifact, + target + ); + } + catch (Exception e) { + logger.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + } + + return super.execute(mapping, form, request, response); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/SelectArtifactFactoryAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,82 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import java.util.Collection; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is called to select a specific fis. + * + * @author Tim Englich + */ +public class SelectArtifactFactoryAction extends DescribeUIAction { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(SelectArtifactFactoryAction.class); + + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("SelectArtifactFactoryAction.execute"); + String selectedArtifactFactoryID = request + .getParameter("artifactFactory"); + log.debug("Selected ArtifactFactory ==> " + selectedArtifactFactoryID); + + try { + SessionModel sm = SessionModelFactory.getInstance() + .getSessionModel(request); + Collection artifactFactories = sm + .getArtifactFactories(); + // Removes the Artifactspecific Attributes from the SessionModel- + sm.resetModel(); + if (artifactFactories == null || artifactFactories.isEmpty()) { + new FetchArtifactFactoriesAction().execute(mapping, form, + request, response); + + } + + sm.selectArtifactFactory(selectedArtifactFactoryID); + ArtifactObject af = sm.getSelectedArtifactFactory(); + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)); + ArtifactObject artifact = adc.createNewArtifact(af); + sm.setCurrentArtifact(artifact); + + return super.execute(mapping, form, request, response); + } catch (Exception e) { + log.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, e + .getMessage()); + return super.getExceptionForward(mapping); + } + } + + /** + * Constructor + */ + public SelectArtifactFactoryAction() { + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/SelectFisAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/SelectFisAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is used to step back to the fis selection. It is called when + * pushing the step-back button besides the currently selected fis. + * + * @author Ingo Weinzierl + */ +public class SelectFisAction extends ArtifactDatabaseActionBase { + + private static Logger logger = Logger.getLogger(SelectFisAction.class); + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response + ) { + logger.info("Goto fis selection."); + + try { + + SessionModelFactory fac = SessionModelFactory.getInstance(); + SessionModel sm = fac.getSessionModel(request); + + sm.resetModel(); + + return new FetchArtifactFactoriesAction().execute( + mapping, form, request, response); + } + catch (Exception e) { + logger.error(e, e); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + + return super.getExceptionForward(mapping); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/ShowStatisticAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/ShowStatisticAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,69 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet; + +import java.util.Collection; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is used to display to statistic of the current + * parameterization. + * + * @author Ingo Weinzierl + */ +public class ShowStatisticAction extends DescribeUIAction { + + private static Logger logger = Logger.getLogger(ShowStatisticAction.class); + + + public ShowStatisticAction() { + super(); + } + + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response + ) throws Exception + { + logger.info("show statistic"); + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + + ArtifactDatabaseClient adc = ArtifactDatabaseClientFactory.getInstance() + .getArtifactDatabaseClient(getLocale(request)); + + try{ + Collection statistics = + adc.calculateStatistics(sm.getSelectedArtifactFactory(), + sm.getCurrentArtifact()); + + sm.setStatistics(statistics); + + request.setAttribute("statistic", true); + } + catch (Exception e) { + logger.error(e, e); + } + + return super.execute(mapping, form, request, response); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/StoreAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/StoreAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,90 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import java.io.OutputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * This controller is used to save the current artifact to an xml file. A file + * dialog is opened to save the file to the local disk. + * + * @author Ingo Weinzierl + */ +public class StoreAction extends ArtifactDatabaseActionBase { + + public static final String RESOURCE_DOWNLOAD_FAILURE = "no.artifact.chosen"; + + private static Logger logger = Logger.getLogger(StoreAction.class); + + public StoreAction() { + super(); + } + + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception + { + SessionModelFactory sf = SessionModelFactory.getInstance(); + SessionModel sm = sf.getSessionModel(request); + + ArtifactDatabaseClientFactory adcf = + ArtifactDatabaseClientFactory.getInstance(); + ArtifactDatabaseClient adc = + adcf.getArtifactDatabaseClient(getLocale(request)); + ArtifactObject artifact = sm.getCurrentArtifact(); + + // no artifact set at the moment (which means, the user didn't select a + // fis yet. + if (artifact == null) { + logger.warn("No artifact/fis selected yet."); + + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_PROJECT, + RESOURCE_DOWNLOAD_FAILURE); + + return super.execute(mapping, form, request, response); + } + + logger.info("Export artifact " + artifact.getId()); + setHeaders(response, artifact.getId()); + + OutputStream out = response.getOutputStream(); + adc.doExport( + sm.getSelectedArtifactFactory(), + artifact, + out); + + out.flush(); + out.close(); + + return null; + } + + protected void setHeaders(HttpServletResponse response, String uuid) { + String filename = "GNVArtefakt_" + uuid + ".xml"; + + response.setHeader("Content-Type", "application/xml"); + response.setHeader( + "Content-Disposition", + "attachment;filename=" + filename); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/SwitchLanguageAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/SwitchLanguageAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,62 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import java.util.Locale; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * Toggle the current language used to create the user interface. Two + * languages are available now - german and english. + * + * @author Ingo Weinzierl + */ +public class SwitchLanguageAction extends DescribeUIAction { + + public static Logger logger = Logger.getLogger(SwitchLanguageAction.class); + + @Override + public ActionForward execute( + ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response + ) throws Exception + { + SessionModelFactory factory = SessionModelFactory.getInstance(); + SessionModel sm = factory.getSessionModel(request); + + sm.setCurrentLocale(switchLanguage(sm.getCurrentLocale())); + + return super.execute(mapping, form, request, response); + } + + + /** + * This method toggles between german and english language. + * + * @param currentLocale The locale which is currently used. + * @return an english locale, if the current locale is german - otherwise + * a german locale. + */ + protected Locale switchLanguage(Locale currentLocale) { + if (currentLocale.getLanguage().equals(Locale.GERMAN.getLanguage())) { + logger.info("Switch from german to english locale."); + return Locale.ENGLISH; + } + else { + logger.info("Switch from english to german locale."); + return Locale.GERMAN; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/WMSAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/WMSAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,182 @@ +package de.intevation.gnv.action; + +import de.intevation.gnv.action.sessionmodel.DiagrammOptions; +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient; +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; +import de.intevation.gnv.artifactdatabase.objects.OutputParameter; + +import de.intevation.gnv.util.XMLUtils; + +import java.text.DateFormat; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +import org.w3c.dom.Document; + +/** + * This controller is used to publish the results of the current artifact as + * WMS. The wms export mode of the artifact server is triggered which feeds a + * MapServer with the given shapefiles (path to the shapefiles is stored in the + * artifact). After calling this controller, the shapefiles are ready to be + * queried as WMS layers. + * + * @author Ingo Weinzierl + */ +public class WMSAction extends DescribeUIAction { + + public static final String XPATH_MAPSERVER_PATH = + "/art:meta/art:mapserver/art:server/text()"; + + public static final String XPATH_MAPSERVER_MAPFILE = + "/art:meta/art:mapserver/art:map/text()"; + + public static final String XPATH_LAYER_TITLE = + "/art:meta/art:layer/art:title/text()"; + + public static final String XPATH_LAYER_TTL = + "/art:meta/art:layer/art:ttl/text()"; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger logger = Logger.getLogger(WMSAction.class); + + /** + * Constructor + */ + public WMSAction() { + super(); + } + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + logger.debug("WMSAction.execute"); + try { + SessionModel sm = SessionModelFactory.getInstance().getSessionModel( + request); + + OutputMode outputMode = sm.getOutputMode("wms"); + Collection ips = null; + if (outputMode != null) { + Collection inputParameter = + outputMode.getOutputParameters(); + + if (inputParameter != null) { + ips = new ArrayList(inputParameter.size()); + Iterator it = inputParameter.iterator(); + DiagrammOptions diagrammOptions = new DiagrammOptions(); + + int params = 0; + while (it.hasNext()) { + String name = it.next().getName(); + String[] values = request.getParameterValues(name); + String value = request.getParameter(name); + InputParameter ip = new DefaultInputParameter(name, + encode(values)); + ips.add(ip); + + if (value != null) { + ++params; + diagrammOptions.setValue(name, encode(value)); + } + } + + if (params > 0) { + sm.setDiagrammOptions(diagrammOptions); + } + } + } + + ArtifactObject artifact = sm.getCurrentArtifact(); + + ArtifactDatabaseClientFactory factory = + ArtifactDatabaseClientFactory.getInstance(); + ArtifactDatabaseClient adc = factory.getArtifactDatabaseClient( + getLocale(request)); + ArtifactObject artifactfactory = sm.getSelectedArtifactFactory(); + + // do wms publishing + Document meta = adc.publishWMS(artifactfactory,artifact,ips); + String mapserverPath = XMLUtils.getStringXPath( + meta, XPATH_MAPSERVER_PATH); + String mapfilePath = XMLUtils.getStringXPath( + meta, XPATH_MAPSERVER_MAPFILE); + String layer = XMLUtils.getStringXPath( + meta, XPATH_LAYER_TITLE); + String tmpTTL = XMLUtils.getStringXPath( + meta, XPATH_LAYER_TTL); + layer = layer != null ? layer : artifact.getId(); + + String ttl = null; + if (tmpTTL != null) { + DateFormat df = DateFormat.getDateTimeInstance( + DateFormat.LONG, + DateFormat.LONG, + request.getLocale()); + + try { + long tmp = Long.parseLong(tmpTTL); + ttl = df.format(new Date(tmp)); + } + catch (NumberFormatException nfe) { + logger.error("Error while parsing time to live."); + logger.error(nfe,nfe); + + ttl = ""; + } + } + + if (logger.isDebugEnabled()) { + logger.debug("Mapserver path: " + mapserverPath); + logger.debug("Mapfile path: " + mapfilePath); + logger.debug("Layer title: " + layer); + logger.debug("Layer ttl: " + ttl); + } + + request.setAttribute("wms", true); + request.setAttribute("mapserver", mapserverPath); + request.setAttribute("mapfile", mapfilePath); + request.setAttribute("layer", layer); + request.setAttribute("ttl", ttl); + if (mapserverPath != null && + mapfilePath != null && + layer != null){ + request.setAttribute("wms_published", Boolean.TRUE); + return super.execute(mapping, form, request, response); + }else{ + return super.getExceptionForward(mapping); + } + } + catch (Exception e) { + logger.error(e, e); + request.setAttribute( + CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, + e.getMessage()); + + return super.getExceptionForward(mapping); + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/MapViewerCallAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/MapViewerCallAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,115 @@ +package de.intevation.gnv.action.mapviewer; + +import de.intevation.gnv.action.ArtifactDatabaseActionBase; + +import de.intevation.gnv.action.mapviewer.parser.ExternalCallParser; +import de.intevation.gnv.action.mapviewer.parser.XMLExternalCallParser; + +import de.intevation.gnv.action.sessionmodel.SessionModel; +import de.intevation.gnv.action.sessionmodel.SessionModelFactory; + +import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; + +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * @author Tim Englich + */ +public class MapViewerCallAction extends ArtifactDatabaseActionBase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(MapViewerCallAction.class); + + /** + * Constructor + */ + public MapViewerCallAction() { + super(); + } + + /** + * @see de.intevation.gnv.action.ArtifactDatabaseActionBase#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("MapViewerCallAction.execute"); + InputStream inputStream = null; + String documentvalue = request.getParameter("document"); + if (documentvalue != null){ + documentvalue = documentvalue.trim(); + inputStream = new ByteArrayInputStream(documentvalue.getBytes()); + }else{ + inputStream = request.getInputStream(); + } + + if (inputStream != null){ + try { + ExternalCallParser ecp = new XMLExternalCallParser(inputStream); + ecp.parse(); + String geometry = ecp.getGeometry(); + String srs = ecp.getSRS(); + Collection mapServices = ecp.getMapServices(); + + Collection availableFactories = + ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)) + .getArtifactFactoryMetaInformation(mapServices, + geometry, + srs); + + Collection providedFactories = + ArtifactDatabaseClientFactory + .getInstance() + .getArtifactDatabaseClient(getLocale(request)) + .getArtifactFactories(); + + // Sort out which ArtifactFactories should not be used. + Collection usedFactories = + new ArrayList(availableFactories.size()); + + Iterator it = availableFactories.iterator(); + while (it.hasNext()){ + ArtifactObject ao = it.next(); + if (providedFactories.contains(ao)){ + usedFactories.add(ao); + } + } + + SessionModel sm = SessionModelFactory + .getInstance() + .getSessionModel(request); + sm.resetModel(); + sm.setArtifacteFactories(usedFactories); + } catch (Exception e) { + log.error(e,e); + } + }else{ + log.error("Kein Anfragedokument übergeben."); + } + return super.execute(mapping, form, request, response); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/ShowMapViewerCallBodyAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/ShowMapViewerCallBodyAction.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,40 @@ +package de.intevation.gnv.action.mapviewer; + +import de.intevation.gnv.action.ArtifactDatabaseActionBase; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +/** + * @author Tim Englich + */ +public class ShowMapViewerCallBodyAction extends ArtifactDatabaseActionBase { + + /** + * the logger, used to log exceptions and additionally information + */ + private static Logger log = Logger + .getLogger(ShowMapViewerCallBodyAction.class); + + /** + * Constructor + */ + public ShowMapViewerCallBodyAction() { + super(); + } + + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + log.debug("ShowMapViewerCallBodyAction.execute"); + request.setAttribute("MAPVIEWERCALL", new Boolean(true)); + return super.execute(mapping, form, request, response); + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParser.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,20 @@ +package de.intevation.gnv.action.mapviewer.parser; + +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import java.util.Collection; + +/** + * @author Tim Englich + */ +public interface ExternalCallParser { + + + String getGeometry(); + + String getSRS(); + + Collection getMapServices(); + + void parse() throws ExternalCallParserException; +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.gnv.action.mapviewer.parser; + +/** + * @author Tim Englich + * + */ +public class ExternalCallParserException extends Exception { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -4917914097058485262L; + + /** + * Constructor + */ + public ExternalCallParserException() { + } + + /** + * Constructor + * @param arg0 + */ + public ExternalCallParserException(String arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + */ + public ExternalCallParserException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * @param arg0 + * @param arg1 + */ + public ExternalCallParserException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/XMLExternalCallParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/XMLExternalCallParser.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,153 @@ +package de.intevation.gnv.action.mapviewer.parser; + +import de.intevation.gnv.artifactdatabase.objects.map.DefaultLayer; +import de.intevation.gnv.artifactdatabase.objects.map.DefaultMapService; +import de.intevation.gnv.artifactdatabase.objects.map.Layer; +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import de.intevation.gnv.util.XMLUtils; + +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Tim Englich + */ +public class XMLExternalCallParser implements ExternalCallParser { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(XMLExternalCallParser.class); + + private static String XPATH_GEOMETRY = "/gnviewer/location/data"; + private static String XPATH_SRS = "/gnviewer/location/srs"; + private static String XPATH_MAPSERVICES_NODESET = "/gnviewer/mapservices/mapservice"; + private static String XPATH_LAYER = "layer"; + private static String ATTRIBUTE_ID = "id"; + private static String ATTRIBUTE_NAME = "name"; + private static String ATTRIBUTE_TYPE = "type"; + private static String ATTRIBUTE_URL = "url"; + + private String geometry = null; + private String srs = null; + + private Collection mapServices = null; + + private InputStream inputStream = null; + + /** + * Constructor + */ + public XMLExternalCallParser(InputStream inputStream) { + this.inputStream = inputStream; + } + + /** + * @see de.intevation.gnv.action.mapviewer.parser.ExternalCallParser#getGeometry() + */ + public String getGeometry() { + return this.geometry; + } + + /** + * @see de.intevation.gnv.action.mapviewer.parser.ExternalCallParser#getMapServices() + */ + public Collection getMapServices() { + return this.mapServices; + } + + /** + * @see de.intevation.gnv.action.mapviewer.parser.ExternalCallParser#parse() + */ + public void parse() throws ExternalCallParserException { + if (inputStream != null){ + XMLUtils xmlUtils = new XMLUtils(); + Document document = xmlUtils.readDocument(this.inputStream); + if (document != null){ + + this.geometry = xmlUtils.getStringXPath(document, XPATH_GEOMETRY); + this.srs = xmlUtils.getStringXPath(document, XPATH_SRS); + NodeList mapservicesNodes = + xmlUtils.getNodeSetXPath(document, XPATH_MAPSERVICES_NODESET); + if (mapservicesNodes != null){ + this.mapServices = new ArrayList(mapservicesNodes.getLength()); + for (int i = 0; i < mapservicesNodes.getLength(); i++){ + Element mapserviceNode = (Element)mapservicesNodes.item(i); + String mapserviceID = mapserviceNode.getAttribute(ATTRIBUTE_ID); + String mapserviceType = mapserviceNode.getAttribute(ATTRIBUTE_TYPE); + String mapserviceUrl = mapserviceNode.getAttribute(ATTRIBUTE_URL); + NodeList layerNodes = xmlUtils.getNodeSetXPath(mapserviceNode, XPATH_LAYER); + Collection layer = null; + if (layerNodes != null && layerNodes.getLength() > 0){ + layer = new ArrayList(layerNodes.getLength()); + layer = this.extractLayer(layer, null, layerNodes); + }else{ + log.debug("No Layer given for this Mapservice"); + } + MapService mapService = + new DefaultMapService(mapserviceID, layer, + mapserviceType, mapserviceUrl); + this.mapServices.add(mapService); + } + + }else{ + String errMsg = "XML-Document does not contain any Mapservices which are required."; + log.error(errMsg); + throw new ExternalCallParserException(errMsg); + } + + }else{ + String errMsg = "XML-Document could not be read from InputStream."; + log.error(errMsg); + throw new ExternalCallParserException(errMsg); + } + }else{ + String errMsg = "No InputStream given for parsing the Call."; + log.error(errMsg); + throw new ExternalCallParserException(errMsg); + } + } + + /** + * This Method extracts all Layers and put them into the Collection. + * @param layer + * @param groupId + * @param layerNodes + * @return + */ + private Collection extractLayer(Collection layer, String groupId, NodeList layerNodes){ + XMLUtils xmlUtils = new XMLUtils(); + for (int i = 0; i < layerNodes.getLength(); i++){ + Element layerNode = (Element)layerNodes.item(i); + String id = layerNode.getAttribute(ATTRIBUTE_ID); + String name = layerNode.getAttribute(ATTRIBUTE_NAME); + NodeList localLayerNodes = xmlUtils.getNodeSetXPath(layerNode, XPATH_LAYER); + Layer tmpLayer = new DefaultLayer(id, name, + (localLayerNodes != null && + localLayerNodes.getLength() > 0), + groupId); + layer.add(tmpLayer); + if (localLayerNodes != null && localLayerNodes.getLength() > 0){ + layer = this.extractLayer(layer, id, localLayerNodes); + } + } + return layer; + } + + /** + * @see de.intevation.gnv.action.mapviewer.parser.ExternalCallParser#getSRS() + */ + public String getSRS() { + return this.srs; + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/mapviewer/parser/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Controller triggered after user interactions. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/sessionmodel/DefaultSessionModel.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,165 @@ +package de.intevation.gnv.action.sessionmodel; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; + +import org.apache.log4j.Logger; + +/** + * The default implementation of SessionModel which stores the + * current artifact object and the digram options selected by the user. + * + * @author Tim Englich + * + */ +public class DefaultSessionModel implements SessionModel { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(DefaultSessionModel.class); + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 3431484439985158311L; + + private Collection artifactFactories = null; + + private ArtifactObject selectedArtifactFactory = null; + + private ArtifactObject currentArtifact = null; + + private DiagrammOptions diagrammOptions = null; + + private Collection statistics = null; + + private Locale currentLocale; + + /** + * Constructor + */ + public DefaultSessionModel() { + this(null); + } + + /** + * Constructor + * + * @param currentLocale A locale used to create the user interface. + */ + public DefaultSessionModel(Locale currentLocale) { + this.currentLocale = currentLocale; + } + + + public void selectArtifactFactory(String artiFactFactoryId) { + Collection artifactObjects = this + .getArtifactFactories(); + if (artifactObjects != null) { + Iterator unselect = artifactObjects.iterator(); + this.selectedArtifactFactory = null; + while (unselect.hasNext()) { + unselect.next().setSelected(false); + } + Iterator it = artifactObjects.iterator(); + while (it.hasNext()) { + ArtifactObject obj = it.next(); + if (obj.getId().equals(artiFactFactoryId)) { + obj.setSelected(true); + this.selectedArtifactFactory = obj; + break; + } + } + } + } + + + public void setArtifacteFactories( + Collection artifactFactories) { + this.artifactFactories = artifactFactories; + } + + + public Collection getArtifactFactories() { + return this.artifactFactories; + } + + + public ArtifactObject getSelectedArtifactFactory() { + return this.selectedArtifactFactory; + } + + + public ArtifactObject getCurrentArtifact() { + return this.currentArtifact; + } + + + public void setCurrentArtifact(ArtifactObject artifact) { + this.currentArtifact = artifact; + } + + + public DiagrammOptions getDiagrammOptions() { + return this.diagrammOptions; + } + + + public void setDiagrammOptions(DiagrammOptions diagrammOptions) { + this.diagrammOptions = diagrammOptions; + } + + + public ArtifactDescription getArtifactDescription() { + if (this.currentArtifact != null) { + return (ArtifactDescription) this.currentArtifact; + } + return null; + } + + + public OutputMode getOutputMode(String name) { + ArtifactDescription ad = this.getArtifactDescription(); + if (ad != null) { + if (ad.getOutputModes() != null) { + return ad.getOutputModes().get(name); + } + } + return null; + } + + + public void resetModel() { + log.debug("DefaultSessionModel.resetModel"); + this.selectedArtifactFactory = null; + this.currentArtifact = null; + this.diagrammOptions = null; + this.statistics = null; + + } + + + public Collection getStatistics() { + return this.statistics; + } + + public void setStatistics(Collection statistics) { + this.statistics = statistics; + } + + public Locale getCurrentLocale() { + return currentLocale; + } + + public void setCurrentLocale(Locale currentLocale) { + this.currentLocale = currentLocale; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/sessionmodel/DiagrammOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/sessionmodel/DiagrammOptions.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,41 @@ +package de.intevation.gnv.action.sessionmodel; + +import java.util.HashMap; +import java.util.Map; + +/** + * Stores key-value pairs used to save user input for changing diagram + * attributes. + * + * @author Tim Englich + */ +public class DiagrammOptions { + + private Map values = new HashMap(); + + /** + * Constructor + */ + public DiagrammOptions() { + super(); + } + + /** + * @return the value. + */ + public String getValue(String key) { + return this.values.get(key); + } + + + /** + * Set a value with the given key. + * + * @param key The given key. + * @param value The value to be stored. + */ + public void setValue(String key, String value) { + this.values.put(key, value); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/sessionmodel/SessionModel.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +package de.intevation.gnv.action.sessionmodel; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.Locale; + +/** + * This interface describe basic methods to store artifacts and diagram options. + * The SessionModel is saved in the session, which keeps alive during the work. + * + * @author Tim Englich + * + */ +public interface SessionModel extends Serializable { + + Collection getArtifactFactories(); + + void setArtifacteFactories(Collection artifactFactories); + + void selectArtifactFactory(String artiFactFactoryId); + + ArtifactObject getSelectedArtifactFactory(); + + ArtifactObject getCurrentArtifact(); + + void setCurrentArtifact(ArtifactObject artifact); + + void setDiagrammOptions(DiagrammOptions diagrammOptions); + + DiagrammOptions getDiagrammOptions(); + + OutputMode getOutputMode(String name); + + ArtifactDescription getArtifactDescription(); + + void resetModel(); + + void setStatistics(Collection statistics); + + Collection getStatistics(); + + void setCurrentLocale(Locale locale); + + Locale getCurrentLocale(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/sessionmodel/SessionModelFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,65 @@ +package de.intevation.gnv.action.sessionmodel; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; + +/** + * Creates and restores SessionModel objects from + * HttpServletRequest. + * + * @author Tim Englich + */ +public class SessionModelFactory { + + public final static String SESSION_MODEL_ID = "de.intevation.gnv.action.sessionmodel.SessionModel.ID"; + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(SessionModelFactory.class); + + /** + * The singleton Instance of this Factory. + */ + private static SessionModelFactory instance = null; + + /** + * Constructor + */ + private SessionModelFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * + * @return an singleton Instance of this Class + */ + public synchronized static SessionModelFactory getInstance() { + if (instance == null) { + instance = new SessionModelFactory(); + } + return instance; + } + + /** + * Getting the ArtifactDatabaseClient + * + * @return the ArtifactDatabaseClient + */ + public SessionModel getSessionModel(HttpServletRequest request) { + synchronized (request) { + SessionModel sm = null; + Object obj = request.getSession().getAttribute(SESSION_MODEL_ID); + if (obj instanceof SessionModel) { + sm = (SessionModel) obj; + } else { + sm = new DefaultSessionModel(request.getLocale()); + request.getSession().setAttribute(SESSION_MODEL_ID, sm); + } + + return sm; + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/action/sessionmodel/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/action/sessionmodel/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +Store important values in the session using classes and interfaces in this +package. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,227 @@ +package de.intevation.gnv.artifactdatabase.client; + +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException; +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactFactory; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; + +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import java.io.IOException; +import java.io.OutputStream; + +import java.util.Collection; +import java.util.Locale; + +import org.w3c.dom.Document; + +/** + * This interface describes basic methods for the communication between artifact + * server and this client. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public interface ArtifactDatabaseClient { + + public final static String ARTIFACTDATABASE_COUNT_ID = "de.intevation.gnv.artifactdatabase.client.ArtifactDatabase.count"; + + public final static String ARTIFACTDATABASE_URL_ID = "de.intevation.gnv.artifactdatabase.client.ArtifactDatabase.url"; + + /** + * Return the Artifactfactories which can be resolved. + * + * @return the Artifactfactories which can be resolved. + * @throws ArtifactDatabaseClientException if a general error occured in the + * artifact server. + * @throws ArtifactDatabaseInputException if the input data was valid. + */ + public Collection getArtifactFactories() + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + /** + * Call the create operation of the artifact server and returns a new + * artifact with the information returned by the artifact server. + * + * @param artifactFactory + * @return the new Artifact + * @throws ArtifactDatabaseClientException if a general error occured in the + * artifact server. + * @throws ArtifactDatabaseInputException if the input data was valid. + */ + public ArtifactObject createNewArtifact(ArtifactObject artifactFactory) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + /** + * Call the describe operation of the artifact server. + * + * @param artifactFactory + * @param currentArtifact + * @param includeUI + * @return the Current Artifact + * @throws ArtifactDatabaseClientException if a general error occured in the + * artifact server. + * @throws ArtifactDatabaseInputException if the input data was valid. + */ + public ArtifactDescription getCurrentStepDescription( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + boolean includeUI) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + /** + * + * @param artifactFactory + * @param currentArtifact + * @param target + * @param inputParameter + * @return the artifact description. + * @throws ArtifactDatabaseClientException if a general error occured in the + * artifact server. + * @throws ArtifactDatabaseInputException if the input data was valid. + */ + public ArtifactDescription doNextStep( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + String target, + Collection inputParameter) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + public void doAdvance( + ArtifactObject factory, + ArtifactObject artifact, + String target) + throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + /** + * @param artifactFactory + * @param currentArtifact + * @param inputParameter + * @throws ArtifactDatabaseClientException if a general error occured in the + * artifact server. + * @throws ArtifactDatabaseInputException if the input data was valid. + */ + public void doFeed(ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + Collection inputParameter) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + /** + * Call the out operation of the artifact server. + * + * @param artifactFactory + * @param currentArtifact + * @param stream + * @param targetName + * @param exportMode + * @param mimeType + * @param inputParameter + * @throws ArtifactDatabaseClientException + */ + public void doOutput( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + OutputStream stream, + String targetName, + String exportMode, + String mimeType, + Collection inputParameter) + throws ArtifactDatabaseClientException; + + + /** + * Write the current artifact to an xml file. + * + * @param artifactFactory + * @param currentArtifact + * @param out + * @throws ArtifactDatabaseClientException + */ + public void doExport( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + OutputStream out) + throws ArtifactDatabaseClientException; + + + /** + * Import an artifact from xml file. + * + * @param factory + * @param document + * @return a status message. If the import was successful, it contains + * information about the imported artifact, otherwise a failure is + * contained. + * @throws ArtifactDatabaseClientException + * @throws IOException + */ + public Document doImport( + ArtifactFactory factory, + Document document) + throws ArtifactDatabaseClientException, IOException; + + /** + * Publish shapefiles of an artifact as WMS layer. + * + * @param factory + * @param artifact + * @param inputParameter + * @return URL to wms service as string + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public Document publishWMS( + ArtifactObject factory, + ArtifactObject artifact, + Collection inputParameter + )throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + + + /** + * Start statistics calculation. + * + * @param artifactFactory + * @param currentArtifact + * @return the calculated statistic. + * @throws ArtifactDatabaseClientException + */ + public Collection calculateStatistics( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact) + throws ArtifactDatabaseClientException; + + /** + * Set the current locale. + * @param locale + */ + public void setLocale(Locale locale); + + /** + * Get the current locale. + * @return the current locale. + */ + public Locale getLocale(); + + /** + * Returns some meta information about the currently selected + * ArtifactFactory. + * + * @param mapServices + * @param geometry + * @param srs + * @return the information. + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public Collection getArtifactFactoryMetaInformation( + Collection mapServices, + String geometry, + String srs) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException; + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,57 @@ +package de.intevation.gnv.artifactdatabase.client; + +import java.util.Locale; + +import org.apache.log4j.Logger; + +/** + * Used to start a session with a new artifact. A new + * DefaultArtifactDatabaseClient is created. + * + * @author Tim Englich + * + */ +public class ArtifactDatabaseClientFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(ArtifactDatabaseClientFactory.class); + + /** + * The singleton Instance of this Factory. + */ + private static ArtifactDatabaseClientFactory instance = null; + + /** + * Constructor + */ + private ArtifactDatabaseClientFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * + * @return an singleton Instance of this Class + */ + public static synchronized ArtifactDatabaseClientFactory getInstance() { + if (instance == null) { + instance = new ArtifactDatabaseClientFactory(); + } + return instance; + } + + /** + * Getting the ArtifactDatabaseClient + * @param locale teh Local that should be used for the Communication + * @return the ArtifactDatabaseClient + */ + public ArtifactDatabaseClient getArtifactDatabaseClient(Locale locale) { + DefaultArtifactDatabaseClient adc = new DefaultArtifactDatabaseClient(); + adc.setLocale(locale); + return adc; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1129 @@ +package de.intevation.gnv.artifactdatabase.client; + +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException; +import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException; + +import de.intevation.gnv.artifactdatabase.objects.Artifact; +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactFactory; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet; +import de.intevation.gnv.artifactdatabase.objects.DefaultArtifactStatisticValue; +import de.intevation.gnv.artifactdatabase.objects.DefaultArtifactStatisticsSet; +import de.intevation.gnv.artifactdatabase.objects.DefaultExportMode; +import de.intevation.gnv.artifactdatabase.objects.DefaultOutputMode; +import de.intevation.gnv.artifactdatabase.objects.DefaultOutputParameter; +import de.intevation.gnv.artifactdatabase.objects.ExportMode; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; +import de.intevation.gnv.artifactdatabase.objects.OutputMode; +import de.intevation.gnv.artifactdatabase.objects.OutputParameter; +import de.intevation.gnv.artifactdatabase.objects.ParametrizedArtifactFactory; +import de.intevation.gnv.artifactdatabase.objects.ParametrizedArtifactObject; + +import de.intevation.gnv.artifactdatabase.objects.map.Layer; +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import de.intevation.gnv.propertiesreader.PropertiesReader; +import de.intevation.gnv.propertiesreader.PropertiesReaderFactory; + +import de.intevation.gnv.util.XMLUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.restlet.Client; + +import org.restlet.data.ClientInfo; +import org.restlet.data.Language; +import org.restlet.data.Method; +import org.restlet.data.Preference; +import org.restlet.data.Protocol; +import org.restlet.data.Request; +import org.restlet.data.Response; + +import org.restlet.representation.Representation; +import org.restlet.representation.StringRepresentation; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * The default implementation of ArtifactDatabaseClient which + * implements methods to communicate via HTTP protocol with the artifact server. + * + * @author Tim Englich + * @author Ingo Weinzierl + */ +public class DefaultArtifactDatabaseClient implements ArtifactDatabaseClient { + /** + * The URI of the namespace of the artifacts. + */ + public final static String NAMESPACE_URI = "http://www.intevation.de/2009/artifacts"; + + /** + * The XML prefix for the artifacts namespace. + */ + public final static String NAMESPACE_PREFIX = "art"; + + /** + * Xpath expression to get general exception messages related to server + * errors. + */ + public static final String EXCEPTION_GENERAL = + "/art:exceptionreport/art:exception/text()"; + + /** + * Xpath expression to get exception messages related to invalid user input. + */ + public static final String EXCEPTION_USER_INPUT = + "/art:exceptionreport/art:exception/art:input/text()"; + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger + .getLogger(DefaultArtifactDatabaseClient.class); + + /** + * The Databases which could be used + */ + private static Collection artifactDatabases = null; + + /** + * Is the Class initialized? + */ + private static boolean initialized = false; + + /** + * Request locale + */ + private Locale locale; + + + /** + * Constructor + */ + public DefaultArtifactDatabaseClient() { + + } + + public Collection getArtifactFactories() + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + Collection resultValues = null; + if (!initialized) { + this.initialize(); + } + try { + log.debug("DefaultArtifactDatabaseClient.getArtifactFactories"); + Iterator it = artifactDatabases.iterator(); + while (it.hasNext()) { + String server = it.next(); + String url = server + "/factories"; + Document document = this.doGetRequest(url); + if (resultValues == null) { + resultValues = this.getArtifactFactories(document, server,null); + } else { + resultValues.addAll(this.getArtifactFactories(document, + server,null)); + } + } + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + return resultValues; + } + + + /** + * Returns a collection of artifact factories retrieved by server. + * + * @param document + * @param server + * @param geometry + * @return a collection of factories. + */ + private Collection getArtifactFactories(Document document, + String server, + String geometry) { + NodeList artifactFactories = XMLUtils.getNodeSetXPath(document, + "/art:result/art:factories/art:factory"); + Collection resultValues = new ArrayList( + artifactFactories.getLength()); + if (artifactFactories != null) { + for (int i = 0; i < artifactFactories.getLength(); i++) { + Node artifactFactoryNode = artifactFactories.item(i); + String name = XMLUtils.getStringXPath(artifactFactoryNode, + "@art:name"); + String description = XMLUtils.getStringXPath( + artifactFactoryNode, "@art:description"); + + NodeList parameterNodeList = XMLUtils.getNodeSetXPath( + artifactFactoryNode, + "art:parameter"); + + if ((parameterNodeList != null && + parameterNodeList.getLength() > 0) || + geometry != null){ + Collection parameters = + new ArrayList(parameterNodeList.getLength()); + for (int j = 0; j < parameterNodeList.getLength(); j++){ + Element parameterNode = (Element)parameterNodeList.item(j); + parameters.add(parameterNode.getAttribute("id")); + } + ParametrizedArtifactObject pao = + new ParametrizedArtifactFactory(name, + description, + server); + pao.addParameters("parameter", parameters); + resultValues.add(pao); + if (geometry != null){ + Collection geometryList = new ArrayList(1); + geometryList.add(geometry); + pao.addParameters("geometry",geometryList); + } + }else{ + ArtifactObject artifactFactory = new ArtifactFactory(name, + description, + server); + resultValues.add(artifactFactory); + } + } + } + log.debug("Artifact Factories: " + resultValues.size()); + return resultValues; + } + + + private Document doGetRequest(String requestUrl) + throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException { + return this.doGetRequest(requestUrl, null); + } + + + private Document doGetRequest(String requestUrl, Document requestBody) + throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException { + XMLUtils xmlUtils = new XMLUtils(); + Representation output = doGetRequestInternal(requestUrl, requestBody); + Document document = XMLUtils.readDocument(output.getStream()); + this.check4ExceptionReport(document); + return document; + } + + protected Request initialize(Request request) { + return initialize(request, locale); + } + + /** + * Initialize the ClientInfo object of request with the + * given locale. + * + * @param request The request object. + * @param locale The locale. + * @return the prepared request object. + */ + protected Request initialize(Request request, Locale locale) { + if (locale != null) { + ClientInfo clientInfo = request.getClientInfo(); + String lang = locale.getLanguage(); + Language language = new Language(lang); + List> acceptedLanguages = + new ArrayList>(2); + acceptedLanguages.add(new Preference(language, 1.0f)); + acceptedLanguages.add(new Preference(Language.ALL, 0.5f)); + clientInfo.setAcceptedLanguages(acceptedLanguages); + } + return request; + } + + + private Representation doGetRequestInternal(String requestUrl, + Document requestBody) throws IOException { + Client client = new Client(Protocol.HTTP); + Request request = initialize(new Request(Method.GET, requestUrl)); + if (requestBody != null) { + String documentBody = XMLUtils + .writeDocument2String(requestBody); + Representation representation = new StringRepresentation( + documentBody); + request.setEntity(representation); + } + Response response = client.handle(request); + if (response.getStatus().getCode() != 200){ + throw new IOException(response.getStatus().getDescription()); + } + Representation output = response.getEntity(); + return output; + } + + + private InputStream doPostRequest(String requestUrl, Document requestBody) + throws IOException { + Client client = new Client(Protocol.HTTP); + Request request = initialize(new Request(Method.POST, requestUrl)); + String documentBody = XMLUtils.writeDocument2String(requestBody); + Representation representation = new StringRepresentation(documentBody); + request.setEntity(representation); + Response response = client.handle(request); + if (response.getStatus().getCode() != 200){ + throw new IOException(response.getStatus().getDescription()); + } + Representation output = response.getEntity(); + return output.getStream(); + } + + private synchronized void initialize() { + if (!initialized) { + PropertiesReader pr = PropertiesReaderFactory.getInstance() + .getPropertiesReader(); + int count = Integer.parseInt(pr.getPropertieValue( + ARTIFACTDATABASE_COUNT_ID, "0")); + artifactDatabases = new ArrayList(count); + for (int i = 0; i < count; i++) { + artifactDatabases.add(pr.getPropertieValue( + ARTIFACTDATABASE_URL_ID + "." + (i + 1), "N/N")); + } + initialized = true; + } + + } + + + /** + * Creates a new artifact with the given artifactFactory. A POST call + * is sent to the artifact server which creates a new artifact. + * + * @param artifactFactory The artifact factory used to create a new + * artifact. + * @return the created artifact of the artifact server. + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public ArtifactObject createNewArtifact(ArtifactObject artifactFactory) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + + try { + Document request = this.createCreateRequestBody(artifactFactory); + Document result = doPostRequest(artifactFactory, request, "create"); + return this.getArtifact(result); + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + } + + /** + * Returns a new artifact defined by uuid and hash values of the document + * returned by the artifact server after creating a new artifact. + * + * @param document Contains information about the server-side created + * artifact. + * @return a new artifact object. + */ + private ArtifactObject getArtifact(Document document) { + XMLUtils xmlUtils = new XMLUtils(); + String uuid = XMLUtils.getStringXPath(document, "/art:result/art:uuid/@value"); + String hash = XMLUtils.getStringXPath(document, "/art:result/art:hash/@value"); + log.info("NEW Artifact: " + uuid + " / " + hash); + return new Artifact(uuid, hash); + } + + private Document createCreateRequestBody(ArtifactObject artifactFactory) { + Document document = XMLUtils.newDocument(); + Node rootNode = this.createRootNode(document); + Element typeNode = this.createArtifactElement(document, "type"); + typeNode.setAttribute("name", "create"); + rootNode.appendChild(typeNode); + + Element factoryNode = this.createArtifactElement(document, "factory"); + factoryNode.setAttribute("name", artifactFactory.getId()); + rootNode.appendChild(factoryNode); + + if (artifactFactory instanceof ParametrizedArtifactObject){ + Map> parameterMap = + ((ParametrizedArtifactObject)artifactFactory).getParameters(); + if (parameterMap != null && !parameterMap.isEmpty() ){ + Iterator keyIt = parameterMap.keySet().iterator(); + while (keyIt.hasNext()){ + String key = keyIt.next(); + Iterator valueIt = parameterMap.get(key).iterator(); + while (valueIt.hasNext()){ + String value = valueIt.next(); + Element parameterNode = + this.createArtifactElement(document, "parameter"); + parameterNode.setAttribute("name", key); + parameterNode.setAttribute("value", value); + factoryNode.appendChild(parameterNode); + } + } + } + } + return document; + } + + private Element createRootNode(Document document) { + Element rootNode = this.createArtifactElement(document, "action"); + document.appendChild(rootNode); + return rootNode; + } + + + private Element createArtifactElement(Document document, String name) { + XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( + document, + NAMESPACE_URI, + NAMESPACE_PREFIX + ); + + return creator.create(name); + } + + + private Document doPostRequest(ArtifactObject artifactFactory, + Document request, String suburl) + throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException { + XMLUtils xmlUtils = new XMLUtils(); + String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl(); + InputStream is = this.doPostRequest(url + "/" + suburl, request); + Document result = XMLUtils.readDocument(is); + this.check4ExceptionReport(result); + return result; + } + + + /** + * Retrieve the current artifact description after calling the describe + * operation of the artifact server. + * + * @param artifactFactory + * @param currentArtifact + * @param includeUI Set this option to true, if the user interface + * description is required. + * @return the artifact description. + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public ArtifactDescription getCurrentStepDescription( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + boolean includeUI) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + try { + String url = this.getArtifactUrl(artifactFactory, currentArtifact); + Document request = this.createDescribeRequestBody(currentArtifact, + includeUI); + InputStream describeResult = this.doPostRequest(url, request); + + return this.readDescription(XMLUtils.readDocument(describeResult), + currentArtifact); + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + } + + + private Document createDescribeRequestBody(ArtifactObject currentArtifact, + boolean includeUI){ + Document document = XMLUtils.newDocument(); + Node rootNode = this.createRootNode(document); + + Element typeNode = this.createArtifactElement(document, "type"); + typeNode.setAttribute("name", "describe"); + rootNode.appendChild(typeNode); + + Element uuidNode = this.createArtifactElement(document, "uuid"); + uuidNode.setAttribute("value", currentArtifact.getId()); + rootNode.appendChild(uuidNode); + + Element hashNode = this.createArtifactElement(document, "hash"); + hashNode.setAttribute("value", currentArtifact.getHash()); + rootNode.appendChild(hashNode); + Element includeUINode = this.createArtifactElement(document, "include-ui"); + includeUINode.appendChild(document.createTextNode(""+includeUI)); + rootNode.appendChild(includeUINode); + return document; + } + + + private String getArtifactUrl(ArtifactObject artifactFactory, + ArtifactObject currentArtifact) { + String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl() + + "/artifact/" + currentArtifact.getId(); + return url; + } + + private ArtifactDescription readDescription(Document document, + ArtifactObject artifact) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + // Check if there was an Error or Exception reported from the + // ArtifactDatabase + this.check4ExceptionReport(document); + if (artifact instanceof ArtifactDescription) { + ArtifactDescription ad = (ArtifactDescription) artifact; + Node uiNode = XMLUtils.getNodeXPath(document, "/art:result/art:ui"); + Node outputNode = XMLUtils + .getNodeXPath(document, "/art:result/art:outputs"); + + Map outputModes = null; + if (outputNode != null) { + NodeList outputModesNodes = XMLUtils.getNodeSetXPath( + outputNode, "art:output"); + if (outputModesNodes != null) { + outputModes = new HashMap( + outputModesNodes.getLength()); + for (int i = 0; i < outputModesNodes.getLength(); i++) { + Node outputModeNode = outputModesNodes.item(i); + String name = XMLUtils.getStringXPath(outputModeNode, + "@name"); + String mimeType = XMLUtils.getStringXPath( + outputModeNode, "@mime-type"); + + NodeList parameterNodes = XMLUtils.getNodeSetXPath( + outputModeNode, "art:parameter/art:parameter"); + Collection parameter = null; + if (parameterNodes != null) { + parameter = new ArrayList( + parameterNodes.getLength()); + for (int j = 0; j < parameterNodes.getLength(); j++) { + Node outputParameterNode = parameterNodes + .item(j); + parameter.add(new DefaultOutputParameter( + XMLUtils.getStringXPath( + outputParameterNode, "@name"), + XMLUtils.getStringXPath( + outputParameterNode, "@value"), + XMLUtils.getStringXPath( + outputParameterNode, "@name"), + XMLUtils.getStringXPath( + outputParameterNode, "@type"))); + } + } + + NodeList exportNodes = XMLUtils.getNodeSetXPath( + outputModeNode, "art:exports/art:export"); + Map exports = null; + + if (exportNodes != null) { + int size = exportNodes.getLength(); + exports = new HashMap(size); + + for (int k = 0; k < size; k++) { + Node export = exportNodes.item(k); + String expName = XMLUtils.getStringXPath( + export, "@name"); + exports.put(expName, new DefaultExportMode( + expName, + XMLUtils.getStringXPath(export, "@description"), + XMLUtils.getStringXPath(export, "@mime-type"))); + } + } + + outputModes.put(name, new DefaultOutputMode(name, + mimeType, parameter, exports)); + } + + } + } + + String currentState = XMLUtils.getStringXPath(document, + "/art:result/art:state/@name"); + NodeList statesList = XMLUtils.getNodeSetXPath(document, + "/art:result/art:reachable-states/art:state/@name"); + Collection reachableStates = new ArrayList( + statesList.getLength()); + for (int i = 0; i < statesList.getLength(); i++) { + reachableStates.add(statesList.item(i).getNodeValue()); + } + + NodeList inputNodes = XMLUtils.getNodeSetXPath(document, + "/art:result/art:model/art:input"); + if (inputNodes != null) { + Collection inputParameter = new ArrayList( + inputNodes.getLength()); + for (int i = 0; i < inputNodes.getLength(); i++) { + Node inputNode = inputNodes.item(i); + String name = XMLUtils.getStringXPath(inputNode, "@name"); + inputParameter.add(name); + } + ad.setInputParameter(inputParameter); + } + + ad.setOutputModes(outputModes); + ad.setCurrentOut(outputNode); + ad.setCurrentUI(uiNode); + ad.setCurrentState(currentState); + ad.setReachableStates(reachableStates); + return ad; + } else { + log.error("Artifact must be Instance of ArtifactDescription"); + throw new ArtifactDatabaseClientException( + "Artifact must be Instance of ArtifactDescription"); + } + + } + + + /** + * Feed, advance and describe in one single method. + * + * @param artifactFactory The factory which created the current artifact. + * @param currentArtifact The current artifact. + * @param target The target state for advance. + * @param inputParameter Input data for feed. + * @return the artifact description after calling feed and advance. + * @throws ArtifactDatabaseClientException if a general error occured in + * the artifact server. + * @throws ArtifactDatabaseInputException if the input data was invalid used + * for feed. + */ + public ArtifactDescription doNextStep( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + String target, + Collection inputParameter) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + + try { + // 1 Feed + this.doFeed(artifactFactory, currentArtifact, inputParameter); + + // 2. Noch einmal Describe um das jetzt zu erreichende Ziel zu ermitteln + ArtifactDescription ad = getCurrentStepDescription( + artifactFactory, + new Artifact(currentArtifact.getId(), + currentArtifact.getHash()), + false + ); + + target = ad.getReachableStates().iterator().next(); + + // 3 Advance + doAdvance(artifactFactory, currentArtifact, target); + + // 3 Describe + return this.getCurrentStepDescription(artifactFactory, + currentArtifact,true); + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + } + + + /** + * Call the advance operation of the artifact server to step to the next + * step of the parameterization. + * + * @param factory The artifact factory which created the current artifact. + * @param artifact The current artifact. + * @param target The target state. + * @throws IOException if an error occured while reading/writing from/to + * stream. + * @throws ArtifactDatabaseClientException if a general error occured in + * the artifact server. + * @throws ArtifactDatabaseInputException if the input data was invalid. + */ + public void doAdvance( + ArtifactObject factory, + ArtifactObject artifact, + String target) + throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException { + String url = getArtifactUrl(factory, artifact); + Document advanceDocument = createAdvanceRequestBody(artifact, target); + InputStream advanceResult = doPostRequest(url, advanceDocument); + check4ExceptionReport(XMLUtils.readDocument(advanceResult)); + } + + private Document createFeedRequestBody( + ArtifactObject currentArtifact, + Collection inputParameter) { + Document document = XMLUtils.newDocument(); + Node rootNode = this.createRootNode(document); + + Element typeNode = this.createArtifactElement(document, "type"); + typeNode.setAttribute("name", "feed"); + rootNode.appendChild(typeNode); + + Element uuidNode = this.createArtifactElement(document, "uuid"); + uuidNode.setAttribute("value", currentArtifact.getId()); + rootNode.appendChild(uuidNode); + + Element hashNode = this.createArtifactElement(document, "hash"); + hashNode.setAttribute("value", currentArtifact.getHash()); + rootNode.appendChild(hashNode); + + Node dataNode = this.createParameterNodes(inputParameter, document, + "data"); + rootNode.appendChild(dataNode); + + return document; + } + + + private Node createParameterNodes( + Collection inputParameter, + Document document, String nodeName) { + Element dataNode = this.createArtifactElement(document, nodeName); + + if (inputParameter != null) { + Iterator it = inputParameter.iterator(); + while (it.hasNext()) { + InputParameter ip = it.next(); + String name = ip.getName(); + String[] values = ip.getValues(); + if (values != null) { + for (int i = 0; i < values.length; i++) { + String value = values[i]; + Element inputNode = this.createArtifactElement( + document, "input"); + inputNode.setAttribute("name", name); + inputNode.setAttribute("value", value); + dataNode.appendChild(inputNode); + } + } + } + } + return dataNode; + } + + + /** + * Creates the xml body for the advance request. + * + * @param currentArtifact + * @param target + * @return the advance xml document. + */ + private Document createAdvanceRequestBody(ArtifactObject currentArtifact, + String target) { + Document document = XMLUtils.newDocument(); + Node rootNode = this.createRootNode(document); + + Element typeNode = this.createArtifactElement(document, "type"); + typeNode.setAttribute("name", "advance"); + rootNode.appendChild(typeNode); + + Element uuidNode = this.createArtifactElement(document, "uuid"); + uuidNode.setAttribute("value", currentArtifact.getId()); + rootNode.appendChild(uuidNode); + + Element hashNode = this.createArtifactElement(document, "hash"); + hashNode.setAttribute("value", currentArtifact.getHash()); + rootNode.appendChild(hashNode); + Element targetNode = this.createArtifactElement(document, "target"); + targetNode.setAttribute("name", target); + rootNode.appendChild(targetNode); + return document; + } + + /** + * Call the out operation of the artifact server and writes the result to + * stream. + * + * @param exportMode + * @param inputParameter + */ + public void doOutput( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + OutputStream stream, + String targetName, + String exportMode, + String mimeType, + Collection inputParameter) + throws ArtifactDatabaseClientException + { + try { + Document requestBody = this.createOutRequestBody( + currentArtifact, + targetName, + exportMode, + mimeType, + inputParameter); + + String requestUrl = this.getArtifactUrl(artifactFactory, + currentArtifact) + + "/" + targetName; + InputStream is = this.doPostRequest(requestUrl, requestBody); + + byte[] b = new byte[4096]; + int i = -1; + while ((i = is.read(b)) > 0) { + stream.write(b, 0, i); + } + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + } + + + /** + * Call the out method of the artifact server with a specific export mode. + * + * @param artifactFactory + * @param currentArtifact + * @param out + * @throws ArtifactDatabaseClientException if an error occured while + * reading/writing from/to stream. + */ + public void doExport( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + OutputStream out) + throws ArtifactDatabaseClientException + { + InputStreamReader reader = null; + OutputStreamWriter writer = null; + + try { + String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl(); + url += "/export/" + currentArtifact.getId(); + + Representation response = doGetRequestInternal(url, null); + InputStream in = response.getStream(); + + reader = new InputStreamReader(in); + writer = new OutputStreamWriter(out); + + int c; + char[] buffer = new char[512]; + while ((c = reader.read(buffer)) > 0) { + writer.write(buffer, 0, c); + } + + } + catch (Exception e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + finally { + try { + reader.close(); + } catch (IOException ioe) {} + + try { + writer.flush(); + } catch (IOException ioe) {} + + try { + writer.close(); + } catch (IOException ioe) {} + } + } + + + /** + * Start to import an artifact from xml document. + * + * @param factory + * @param document The artifact as xml document. + * @return A status description of the operation (success or failure). + * @throws ArtifactDatabaseClientException + * @throws IOException + */ + public Document doImport( + ArtifactFactory factory, + Document document) + throws ArtifactDatabaseClientException, IOException + { + String url = factory.getDataBaseUrl() + "/import"; + InputStream response = doPostRequest(url, document); + + return XMLUtils.readDocument(response); + } + + + /** + * Creates the xml request body used for an out-call of the artifact server. + * + * @param currentArtifact + * @param target + * @param exportMode + * @param mimeType + * @param inputParameter + * @return the request body. + */ + private Document createOutRequestBody( + ArtifactObject currentArtifact, + String target, + String exportMode, + String mimeType, + Collection inputParameter) + { + Document document = XMLUtils.newDocument(); + Node rootNode = this.createRootNode(document); + + Element typeNode = this.createArtifactElement(document, "type"); + typeNode.setAttribute("name", "out"); + rootNode.appendChild(typeNode); + + Element uuidNode = this.createArtifactElement(document, "uuid"); + uuidNode.setAttribute("value", currentArtifact.getId()); + rootNode.appendChild(uuidNode); + + Element hashNode = this.createArtifactElement(document, "hash"); + hashNode.setAttribute("value", currentArtifact.getHash()); + rootNode.appendChild(hashNode); + + Element outNode = this.createArtifactElement(document, "out"); + outNode.setAttribute("name", target); + rootNode.appendChild(outNode); + + Element exportNode = this.createArtifactElement(document, "export"); + exportNode.setAttribute("name", exportMode); + outNode.appendChild(exportNode); + + Element mimeTypeNode = this.createArtifactElement(document, "mime-type"); + mimeTypeNode.setAttribute("value", mimeType); + outNode.appendChild(mimeTypeNode); + + Node parameterNode = this.createParameterNodes(inputParameter, + document, "params"); + outNode.appendChild(parameterNode); + + return document; + } + + + /** + * Calls the feed operation of the artifact server. + * + * @param artifactFactory The artifact factory which created the current + * artifact. + * @param currentArtifact The current artifact. + * @param inputParameter The user input. + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public void doFeed( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact, + Collection inputParameter) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + + try { + Document feedDocument = this.createFeedRequestBody(currentArtifact, + inputParameter); + String url = this.getArtifactUrl(artifactFactory, currentArtifact); + InputStream feedResult = this.doPostRequest(url, feedDocument); + Document feedResultDocument = XMLUtils + .readDocument(feedResult); + this.check4ExceptionReport(feedResultDocument); + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + } + + private void check4ExceptionReport(Document document) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + String message = XMLUtils.getStringXPath(document, + EXCEPTION_GENERAL); + if (message != null) { + throw new ArtifactDatabaseClientException(message); + } + + String input = XMLUtils.getStringXPath(document, EXCEPTION_USER_INPUT); + if (input != null) { + throw new ArtifactDatabaseInputException(input); + } + } + + + /** + * Call the specific wms export mode of the out operation of the artifact + * server. + * + * @param factory + * @param artifact + * @param inputParameter + * @return a document that contains information about the wms service and + * the created layer. + * @throws ArtifactDatabaseClientException + * @throws ArtifactDatabaseInputException + */ + public Document publishWMS( + ArtifactObject factory, + ArtifactObject artifact, + Collection inputParameter + ) throws ArtifactDatabaseClientException, ArtifactDatabaseInputException{ + log.debug("Start wms publishing..."); + + String target = "wms"; + String requestURL = getArtifactUrl(factory, artifact) + "/" + target; + Document request = createOutRequestBody( + artifact, target, "", "text/xml", inputParameter); + try { + InputStream input = doPostRequest(requestURL, request); + Document result = XMLUtils.readDocument(input); + this.check4ExceptionReport(result); + return result; + } + catch (IOException ioe) { + log.error(ioe, ioe); + throw new ArtifactDatabaseClientException(ioe); + } + } + + + public Collection calculateStatistics( + ArtifactObject artifactFactory, + ArtifactObject currentArtifact) + throws ArtifactDatabaseClientException + { + log.debug("DefaultArtifactDatabaseClient.calculateStatistics"); + Collection resultValues = null; + + try { + String targetName = "statistics"; + String requestUrl = this.getArtifactUrl(artifactFactory, + currentArtifact) + "/" + targetName; + Document requestBody = this.createOutRequestBody(currentArtifact, + targetName, "", "text/xml", null); + XMLUtils xmlUtils = new XMLUtils(); + InputStream is = this.doPostRequest(requestUrl, requestBody); + Document resultDocument = XMLUtils.readDocument(is); + if (resultDocument != null) { + + NodeList statisticSetNodes = XMLUtils.getNodeSetXPath(resultDocument, + "/art:statistics/art:statistic"); + resultValues = new ArrayList + (statisticSetNodes.getLength()); + for (int i = 0; i < statisticSetNodes.getLength(); i++) { + Element statisticSetNode = (Element)statisticSetNodes.item(i); + String name = statisticSetNode.getAttribute("name"); + ArtifactStatisticsSet set = + new DefaultArtifactStatisticsSet(name); + NodeList resultNodes = XMLUtils.getNodeSetXPath(statisticSetNode, + "art:statistic-value"); + if (resultNodes != null) { + for (int j = 0; j < resultNodes.getLength(); j++) { + Element statisticNode = (Element)resultNodes.item(j); + String statisticName = statisticNode. + getAttribute("name"); + String statisticValue = statisticNode. + getAttribute("value"); + set.addStatisticValues( + new DefaultArtifactStatisticValue + (statisticName,statisticValue)); + } + } + resultValues.add(set); + } + } + } catch (IOException e) { + log.error(e, e); + throw new ArtifactDatabaseClientException(e); + } + + return resultValues; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public Locale getLocale() { + return locale; + } + + + public Collection getArtifactFactoryMetaInformation( + Collection mapServices, + String geometry, + String srs) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + log.debug("DefaultArtifactDatabaseClient.getArtifactFactories"); + Collection resultValues = null; + try { + this.initialize(); + Iterator it = artifactDatabases.iterator(); + Document requestBody = this.createMetaDataRequestBody(mapServices, + geometry, + srs); + while (it.hasNext()) { + String server = it.next(); + String url = server + "/service/metadata/"; + log.debug(url); + + InputStream resultStream = this.doPostRequest(url, requestBody); + resultValues = this.parseMetaDataResult(resultStream, server,geometry); + } + } catch (IOException e) { + log.error(e,e); + } + return resultValues; + } + + private Collection parseMetaDataResult( + InputStream inputStream, + String server, + String geometry) + throws ArtifactDatabaseClientException, ArtifactDatabaseInputException { + XMLUtils xmlUtils = new XMLUtils(); + Document document = XMLUtils.readDocument(inputStream); + this.check4ExceptionReport(document); + return this.getArtifactFactories(document, server,geometry); + } + + private Document createMetaDataRequestBody(Collection mapServices, + String geometry, + String srs){ + log.debug("DefaultArtifactDatabaseClient.createMetaDataRequestBody"); + Document document = XMLUtils.newDocument(); + Node rootNode = this.createArtifactElement(document, "GetMetaData"); + document.appendChild(rootNode); + + Element locationNode = this.createArtifactElement(document, "location"); + locationNode.setAttribute("srs", srs); + locationNode.appendChild(document.createTextNode(geometry)); + rootNode.appendChild(locationNode); + + Element mapServicesNode = this.createArtifactElement(document, + "mapservices"); + Iterator it = mapServices.iterator(); + while (it.hasNext()){ + MapService mapService = it.next(); + Element mapServiceNode = this.createArtifactElement(document, + "mapservice"); + mapServiceNode.setAttribute("id", mapService.getID()); + mapServiceNode.setAttribute("type", mapService.getType()); + mapServiceNode.setAttribute("url", mapService.getURL()); + if (mapService.getLayer() != null){ + Iterator layer = mapService.getLayer().iterator(); + while (layer.hasNext()){ + Layer tmpLayer = layer.next(); + Element layerNode = this.createArtifactElement(document, + "layer"); + layerNode.setAttribute("id", tmpLayer.getID()); + layerNode.setAttribute("name", tmpLayer.getName()); + layerNode.setAttribute("isgrouplayer", + ""+tmpLayer.isGroupLayer()); + layerNode.setAttribute("parentid", tmpLayer.parentID()); + mapServiceNode.appendChild(layerNode); + } + } + mapServicesNode.appendChild(mapServiceNode); + } + rootNode.appendChild(mapServicesNode); + return document; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseClientException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseClientException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.gnv.artifactdatabase.client.exception; + +/** + * Exception used for general errors in the artifact server. + * + * @author Tim Englich + * + */ +public class ArtifactDatabaseClientException extends Exception { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -8979622024425251952L; + + /** + * Constructor + */ + public ArtifactDatabaseClientException() { + super(); + } + + /** + * Constructor + * + * @param arg0 + */ + public ArtifactDatabaseClientException(String arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + */ + public ArtifactDatabaseClientException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + * @param arg1 + */ + public ArtifactDatabaseClientException(String arg0, Throwable arg1) { + super(arg0, arg1); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,51 @@ +package de.intevation.gnv.artifactdatabase.client.exception; + +/** + * Exception used if an error occured caused by invalid input. + * + * @author Ingo Weinzierl + */ +public class ArtifactDatabaseInputException extends Exception { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = -8979622024425251952L; + + /** + * Constructor + */ + public ArtifactDatabaseInputException() { + super(); + } + + /** + * Constructor + * + * @param arg0 + */ + public ArtifactDatabaseInputException(String arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + */ + public ArtifactDatabaseInputException(Throwable arg0) { + super(arg0); + } + + /** + * Constructor + * + * @param arg0 + * @param arg1 + */ + public ArtifactDatabaseInputException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Exceptions that are thrown if server side errors occur. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,9 @@ + + + + + +The communication between this client and an artifact server is defined in the +classes and interfaces of this package. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/Artifact.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,141 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.util.Collection; +import java.util.Map; + +import org.w3c.dom.Node; + +/** + * An ArtifactObject representing an artifact. + * + * @author Tim Englich + * + */ +public class Artifact implements ArtifactObject, ArtifactDescription { + + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 8606869493141810364L; + + private String id = null; + private String hash = null; + private boolean selected = false; + + private Node currentUI = null; + private Node currentOut = null; + + private Collection reachableStates; + private Collection inputParameter; + private Map outputModes; + private String currentState = null; + + + public Node getCurrentUI() { + return currentUI; + } + + + public void setCurrentUI(Node currentUI) { + this.currentUI = currentUI; + } + + + public Node getCurrentOut() { + return currentOut; + } + + + public void setCurrentOut(Node currentOut) { + this.currentOut = currentOut; + } + + + public Collection getReachableStates() { + return reachableStates; + } + + + public void setReachableStates(Collection reachableStates) { + this.reachableStates = reachableStates; + } + + + public String getCurrentState() { + return currentState; + } + + + public void setCurrentState(String currentState) { + this.currentState = currentState; + } + + /** + * Constructor + */ + public Artifact(String uuid, String hash) { + + this.id = uuid; + this.hash = hash; + } + + + public String getHash() { + return this.hash; + } + + + public String getDescription() { + return this.id; + } + + + public String getId() { + return this.id; + } + + + public String getName() { + return this.id; + } + + + public boolean isSelected() { + return this.selected; + } + + + public void setSelected(boolean selected) { + this.selected = selected; + } + + + public Collection getInputParameter() { + return this.inputParameter; + } + + + public void setInputParameter(Collection inputParameter) { + this.inputParameter = inputParameter; + } + + + public Map getOutputModes() { + return this.outputModes; + } + + + public Collection getOutputModesAsCollection() { + if (this.outputModes != null) { + return this.outputModes.values(); + } + return null; + } + + + public void setOutputModes(Map outputModes) { + this.outputModes = outputModes; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactDescription.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,102 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +import java.util.Collection; +import java.util.Map; + +import org.w3c.dom.Node; + +/** + * This interface describes basic methods to describe the user interface of an + * artifact. + * + * @author Tim Englich + */ +public interface ArtifactDescription extends Serializable { + + /** + * Retrieves the xml node of the current user interface. + * + * @return the currentUI + */ + public Node getCurrentUI(); + + /** + * Set the xml node of the current user interface. + * + * @param currentUI the currentUI to set + */ + public void setCurrentUI(Node currentUI); + + /** + * Set the xml node of the possible output modes. + * + * @param currentOut the currentOut to set + */ + public void setCurrentOut(Node currentOut); + + /** + * Retrieves a collection of reachable states. + * + * @return the reachableStates + */ + public Collection getReachableStates(); + + /** + * Set the reachable states. + * + * @param reachableStates the reachableStates to set + */ + public void setReachableStates(Collection reachableStates); + + /** + * Retrieves the current state. + * + * @return the currentState + */ + public String getCurrentState(); + + /** + * Set the current state. + * + * @param currentState the currentState to set + */ + public void setCurrentState(String currentState); + + /** + * Get a collection of input parameters. + * + * @return the reachableStates + */ + public Collection getInputParameter(); + + /** + * Set a collection of input parameters. + * + * @param inputParameter + */ + public void setInputParameter(Collection inputParameter); + + /** + * Retrieves a map of available output modes. + * + * @return the available output modes. + */ + public Map getOutputModes(); + + /** + * Retrieves a collection of available output modes. + * + * @return the available output modes. + */ + public Collection getOutputModesAsCollection(); + + /** + * Set the available output modes. + * + * @param outputModes A map that contains output modes. + */ + public void setOutputModes(Map outputModes); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,92 @@ +package de.intevation.gnv.artifactdatabase.objects; + +/** + * @author Tim Englich + */ +public class ArtifactFactory implements ArtifactObject { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 5453748230625831527L; + + private String name = null; + + private String description = null; + + private boolean selected = false; + + private String dataBaseUrl = null; + + /** + * Returns the url of the artifact server. + * + * @return the dataBaseUrl + */ + public String getDataBaseUrl() { + return dataBaseUrl; + } + + /** + * Constructor + * @param name the name of the factory + * @param description the description of the Factory + * @param dataBaseUrl the URL where the Factory could be reached. + */ + public ArtifactFactory(String name, String description, String dataBaseUrl) { + super(); + this.name = name; + this.description = description; + this.dataBaseUrl = dataBaseUrl; + } + + + public String getId() { + return this.name; + } + + + public boolean isSelected() { + + return this.selected; + } + + + public void setSelected(boolean selected) { + this.selected = selected; + } + + + public String getName() { + return name; + } + + + public String getDescription() { + return description; + } + + + public String getHash() { + return null; + } + + /** + * Two ArtifactFactories are equal, if the name and the url to the artifact + * server are equal. + * + * @param obj + * @return true, if the factories are equal - otherwise false. + */ + @Override + public boolean equals(Object obj) { + boolean returnValue = false; + if (obj instanceof ArtifactFactory){ + ArtifactFactory af = (ArtifactFactory)obj; + returnValue = this.getName().equals(af.getName()) && + this.getDataBaseUrl().equals(af.getDataBaseUrl()); + } + return returnValue; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactObject.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,54 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +/** + * The ArtifactObject provides some information about an artifact. + * + * @author Tim Englich + */ +public interface ArtifactObject extends Serializable { + + /** + * Retrieves the id of this object. + * + * @return the id. + */ + public String getId(); + + /** + * Retrieves information about the selection state of this object. + * + * @return true, if this object is selected - otherwise false. + */ + public boolean isSelected(); + + /** + * Set the selection of this object. + * + * @param selected the new selection. + */ + public void setSelected(boolean selected); + + /** + * Retrieves the name of this object. + * + * @return the name. + */ + public String getName(); + + /** + * Retrieves the description of the object. + * + * @return the description. + */ + public String getDescription(); + + /** + * Retrieves the hash value of this object. + * + * @return the hash value. + */ + public String getHash(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticValue.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,25 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +/** + * This is the Interfacedefinition for Statistic values that belongs + * to an Artifact. + * @author Tim Englich + * + */ +public interface ArtifactStatisticValue extends Serializable { + + /** + * Returns the Key of the Object + * @return the Key of the Object + */ + String getKey(); + + /** + * Returns the stored Value + * @return the stored Value + */ + String getValue(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticsSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ArtifactStatisticsSet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,35 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +import java.util.Collection; + +/** + * An inteface description for a container storing statistics. + * + * @author Tim Englich + */ +public interface ArtifactStatisticsSet extends Serializable { + + /** + * Retrieves the name of this container. + * + * @return the name. + */ + String getName(); + + /** + * Retrieves the statistics as collection. + * + * @return the statistics. + */ + Collection getStatisticValues(); + + /** + * Add a new statistic to this container. + * + * @param value A statistic. + */ + void addStatisticValues(ArtifactStatisticValue value); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticValue.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,37 @@ +package de.intevation.gnv.artifactdatabase.objects; + +/** + * The Defaultimplementation of ArtifactStatisticValue + * @author Tim Englich + * + */ +public class DefaultArtifactStatisticValue implements ArtifactStatisticValue { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -8409111023127835398L; + + private String key = null; + + private String value = null; + + /** + * Constructor + * @param key the key of the new Value + * @param value the value of the Object. + */ + public DefaultArtifactStatisticValue(String key, String value) { + super(); + this.key = key; + this.value = value; + } + + public String getKey() { + return this.key; + } + + public String getValue() { + return this.value; + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticsSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultArtifactStatisticsSet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * The default implementation of ArtifactStatisticsSet. + * + * @author Tim Englich + * + */ +public class DefaultArtifactStatisticsSet implements ArtifactStatisticsSet{ + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 6738878381515708602L; + + private String name = null; + + private Collection statisticValues = + new ArrayList(); + /** + * Constructor + */ + public DefaultArtifactStatisticsSet(String name) { + this.name = name; + } + + + public void addStatisticValues(ArtifactStatisticValue value) { + this.statisticValues.add(value); + } + + + public String getName() { + return this.name; + } + + + public Collection getStatisticValues() { + return this.statisticValues; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultExportMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultExportMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,43 @@ +package de.intevation.gnv.artifactdatabase.objects; + +/** + * This is the default implementation of ExportMode which stores + * information about a specific output target (e.g. pdf, svg, image). + * + * @author Ingo Weinzierl + */ +public class DefaultExportMode +implements ExportMode +{ + protected String name; + protected String description; + protected String mimeType; + + /** + * Creates a new ExportMode. + * + * @param name The name of the mode. + * @param description A description of this mode. + * @param mimeType The mimetype used for this mode. + */ + public DefaultExportMode(String name, String description, String mimeType){ + this.name = name; + this.description = description; + this.mimeType = mimeType; + } + + + public String getName() { + return name; + } + + + public String getDescription() { + return description; + } + + public String getMimeType() { + return mimeType; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultInputParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultInputParameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,37 @@ +package de.intevation.gnv.artifactdatabase.objects; + +/** + * The default implementation of InputParameter. + * + * @author Tim Englich + * + */ +public class DefaultInputParameter implements InputParameter { + + private static final long serialVersionUID = 6597439837482244211L; + + private String name = null; + + private String[] values = null; + + /** + * Constructor + * + * @param name The name of this parameter. + * @param values The values of this parameter. + */ + public DefaultInputParameter(String name, String[] values) { + super(); + this.name = name; + this.values = values; + } + + public String getName() { + return this.name; + } + + public String[] getValues() { + return this.values; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.util.Collection; +import java.util.Map; + +/** + * The default implementation of an OutputMode. + * + * @author Tim Englich + */ +public class DefaultOutputMode implements OutputMode { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = 7487880486604174521L; + + private String name = null; + + private String mimeType = null; + + private Collection outputParameter = null; + + private Map exports; + + public DefaultOutputMode( + String name, + String mimeType, + Collection outputParameter, + Map exports) + { + super(); + this.name = name; + this.mimeType = mimeType; + this.outputParameter = outputParameter; + this.exports = exports; + } + + public String getMimeType() { + return this.mimeType; + } + + public String getName() { + return this.name; + } + + public Collection getOutputParameters() { + return this.outputParameter; + } + + public ExportMode getExportMode(String mode) { + return exports.get(mode); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/DefaultOutputParameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.artifactdatabase.objects; + +/** + * The default implementation of OutputParameter. + * + * @author Tim Englich + */ +public class DefaultOutputParameter implements OutputParameter { + + /** + * The UID of this Class. + */ + private static final long serialVersionUID = -8416057640116638152L; + + private String name = null; + + private String value = null; + + private String description = null; + + private String type = null; + + /** + * Constructor + * + * @param name + * @param value + * @param description + */ + public DefaultOutputParameter(String name, String value, + String description, String type) { + super(); + this.name = name; + this.value = value; + this.description = description; + this.type = type; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + public String getDescription() { + return this.description; + } + + public String getType() { + return this.type; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ExportMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ExportMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,35 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +/** + * An ExportMode describes a specific format of an output mode + * (e.g. pdf, svg, image). + * + * @author Ingo Weinzierl + */ +public interface ExportMode +extends Serializable +{ + /** + * Returns the name of this export mode. + * + * @return the name. + */ + public String getName(); + + /** + * Returns the description of this export mode. + * + * @return the description. + */ + public String getDescription(); + + /** + * Returns the mimetype used for this export mode. + * + * @return the mimetype. + */ + public String getMimeType(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/InputParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/InputParameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,27 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +/** + * InputParameter objects are used to store multiple values for a + * single key. + * + * @author Tim Englich + */ +public interface InputParameter extends Serializable { + + /** + * Returns the name of the input parameter. + * + * @return the name. + */ + public String getName(); + + /** + * Returns the values of this input parameter as array. + * + * @return the values as array. + */ + public String[] getValues(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputMode.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,46 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +import java.util.Collection; + +/** + * OutputMode objects give information possible types of exports + * for an artifact (e.g. chart, histogram, csv, odv, statistic). + * + * @author Tim Englich + * + */ +public interface OutputMode extends Serializable{ + + /** + * Retrieve the name of an output mode. + * + * @return the name. + */ + public String getName(); + + /** + * Retrieve the mimetype of an output mode. + * + * @return the mimetype. + */ + public String getMimeType(); + + /** + * Retrieve the output parameters available to adjust the output. + * + * @return the output parameters. + */ + public Collection getOutputParameters(); + + /** + * Retrieve possible export modes which describe specific output modes + * (e.g. pdf, svg, image). + * + * @param mode The export mode's name. + * @return the export mode. + */ + public ExportMode getExportMode(String mode); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/OutputParameter.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,41 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.io.Serializable; + +/** + * An OutputParameter describes the input for an export mode and + * stores the value inserted by the user. + * + * @author Tim Englich + */ +public interface OutputParameter extends Serializable{ + + /** + * Retrieves the name of the parameter. + * + * @return the name. + */ + String getName(); + + /** + * Retrieves the value of this parameters. + * + * @return the value. + */ + String getValue(); + + /** + * Retrieves the description of this parameter. + * + * @return the description. + */ + String getDescription(); + + /** + * Retrieves the type of this parameter (e.g. String, Integer, Double, Date). + * + * @return the type. + */ + String getType(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,47 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * This Class is an Extention of the Class ArtifactFactory. + * Its only job is to store optional Parameters that might be + * used to instantiate a new Artifact. + * @author Tim Englich + */ +public class ParametrizedArtifactFactory +extends ArtifactFactory implements ParametrizedArtifactObject { + + /** + * The UID of this Class + */ + private static final long serialVersionUID = 4516368434861819032L; + + /** + * The Parameters that belongs to the Artifactfactory and might be used + * during the Initializationprocess of an Artifact. + */ + private Map> parameters = null; + + /** + * Constructor + * @param name the name of the factory + * @param description the description of the Factory + * @param dataBaseUrl the URL where the Factory could be reached. + */ + public ParametrizedArtifactFactory(String name, String description, + String dataBaseUrl) { + super(name, description, dataBaseUrl); + this.parameters = new HashMap>(); + } + + public Map> getParameters() { + return parameters; + } + + public void addParameters(String key, Collection values) { + this.parameters.put(key, values); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/ParametrizedArtifactObject.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,29 @@ +package de.intevation.gnv.artifactdatabase.objects; + +import java.util.Collection; +import java.util.Map; + +/** + * Interface which extends the funtionality of the Interface + * ArtifactObject with methods for storing and retrieving + * optional Parameters. + * @author Tim Englich + */ +public interface ParametrizedArtifactObject extends ArtifactObject { + + /** + * Returns the Parameters which could be used to manage (e.g. create) an + * ArtifactObject. + * @return a map storing parameters. + */ + Map> getParameters(); + + /** + * Add a further parameter to the parameter map. + * + * @param key the Key of the Parameter (unique) + * @param values the Values of the Parameter + */ + void addParameters(String key, Collection values); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultLayer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultLayer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,57 @@ +package de.intevation.gnv.artifactdatabase.objects.map; + +/** + * The default implementation of Layer. + * + * @author Tim Englich + */ +public class DefaultLayer implements Layer { + + + private String id = null; + + private String name = null; + + private boolean groupLayer = false; + + private String parentId = null; + + /** + * Constructor + */ + public DefaultLayer(String id,String name, + boolean groupLayer,String parentId) { + this.id = id; + this.name = name; + this.groupLayer = groupLayer; + this.parentId = parentId; + } + + + public String getID() { + return this.id; + } + + + public String getName() { + return this.name; + } + + + public boolean isGroupLayer() { + return this.groupLayer; + } + + + public String parentID() { + return this.parentId; + } + + @Override + public String toString() { + return "ID: "+ this.id + " Name: "+this.name+ + " IsGroupLayer: "+this.groupLayer+ + " ParentID: "+this.parentId; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultMapService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/DefaultMapService.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +package de.intevation.gnv.artifactdatabase.objects.map; + +import java.util.Collection; + +/** + * The default implementation of MapService. + * + * @author Tim Englich + */ +public class DefaultMapService implements MapService { + + private String id = null; + + private Collection layer = null; + + private String type = null; + + private String url = null; + + /** + * Constructor + */ + public DefaultMapService(String id, Collection layer, + String type, String url) { + super(); + this.id = id; + this.layer = layer; + this.type = type; + this.url = url; + } + + + public String getID() { + return this.id; + } + + + public Collection getLayer() { + return this.layer; + } + + + public String getType() { + return this.type; + } + + + public String getURL() { + return this.url; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/Layer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/Layer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,39 @@ +package de.intevation.gnv.artifactdatabase.objects.map; + +/** + * This interface defines some basic methods providing information about a map + * layer. + * + * @author Tim Englich + */ +public interface Layer { + + /** + * Retrieves the name of a layer. + * + * @return the name of a layer. + */ + String getName(); + + /** + * Retrieves the id of a layer. + * + * @return the id of a layer. + */ + String getID(); + + /** + * Retrieves true, if this layer is a group layer - otherwise false. + * + * @return true, if this layer is a group layer - otherwise false. + */ + boolean isGroupLayer(); + + /** + * Retrieves the id of the parent layer. + * + * @return the id of the parent layer. + */ + String parentID(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/MapService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/MapService.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,43 @@ +package de.intevation.gnv.artifactdatabase.objects.map; + +import java.util.Collection; + +/** + * This interface defines some basic methods to provide information about a map + * service. + * + * @author Tim Englich + */ +public interface MapService { + + /** + * Retrieves the id of a map service. + * + * @return the id of a map service. + */ + String getID(); + + + /** + * Retrieves the URL of a map service. + * + * @return the URL of a map service. + */ + String getURL(); + + + /** + * Retrieves the type of a map service. + * + * @return the type of a map service. + */ + String getType(); + + /** + * Retrieves the layers served by a map service. + * + * @return the layers served by a map service. + */ + Collection getLayer(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/map/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Objects used to store information about map services and provided layers. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/objects/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Objects used to represent an artifact in this client. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/artifactdatabase/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/propertiesreader/MapPropertiesReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/propertiesreader/MapPropertiesReader.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,35 @@ +package de.intevation.gnv.propertiesreader; + +import java.util.Map; + +import org.apache.log4j.Logger; + +/** + * A PropertiesReader storing properties in a Map. + * + * @author Tim Englich + * + */ +public class MapPropertiesReader implements PropertiesReader { + + private static Logger log = Logger.getLogger(MapPropertiesReader.class); + + private Map properties = null; + + /** + * Constructs a new MapPropertiesReader with an initial map. + */ + public MapPropertiesReader(Map properties) { + super(); + this.properties = properties; + } + + public String getPropertieValue(String key, String defaultValue) { + String value = this.properties.get(key); + if (value == null) { + value = defaultValue; + } + return value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/propertiesreader/PropertiesReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/propertiesreader/PropertiesReader.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,21 @@ +package de.intevation.gnv.propertiesreader; + +/** + * An interface that defines a single method to retrieve properties specified by + * a key. + * + * @author Tim Englich + */ +public interface PropertiesReader { + + /** + * Retrieves a property by the given ke<. + * + * @param key The key of a property. + * @param defaultValue The default value which is returned if no property + * is found by key. + * @return the value of a property. + */ + public String getPropertieValue(String key, String defaultValue); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/propertiesreader/PropertiesReaderFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/propertiesreader/PropertiesReaderFactory.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,77 @@ +package de.intevation.gnv.propertiesreader; + +import java.util.Map; + +import javax.servlet.ServletConfig; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class PropertiesReaderFactory { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(PropertiesReaderFactory.class); + + /** + * The singleton Instance of this Factory. + */ + private static PropertiesReaderFactory instance = null; + + /** + * The ConnectionPool providing the Connections to the DatabaseBackends + */ + private PropertiesReader propertiesReader = null; + + /** + * Constructor + */ + private PropertiesReaderFactory() { + super(); + } + + /** + * This Method provides an singleton Instance of this Class. + * + * @return an singleton Instance of this Class + */ + public static PropertiesReaderFactory getInstance() { + if (instance == null) { + instance = new PropertiesReaderFactory(); + } + return instance; + } + + /** + * Getting the ConnectionPool + * + * @return the ConnectionPool + */ + public PropertiesReader getPropertiesReader() { + return this.propertiesReader; + } + + /** + * Getting the ConnectionPool + * + * @param config The Config that should be read + */ + public void initPropertiesReader(Object config) { + if (config instanceof ServletConfig) { + this.propertiesReader = new ServletPropertiesReader( + (ServletConfig) config); + } else if (config instanceof Map) { + this.propertiesReader = new MapPropertiesReader( + (Map) config); + } else { + log.error("No PropertiesReader for Instance " + + config.getClass().getName()); + } + + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/propertiesreader/ServletPropertiesReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/propertiesreader/ServletPropertiesReader.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,52 @@ +package de.intevation.gnv.propertiesreader; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletConfig; + +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class ServletPropertiesReader implements PropertiesReader { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(ServletPropertiesReader.class); + + private Map properties = null; + + /** + * Constructor + */ + public ServletPropertiesReader(ServletConfig config) { + super(); + log.info("ServletPropertiesReader will be initialized"); + if (config != null) { + + Enumeration keys = config.getInitParameterNames(); + properties = new HashMap(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + String value = config.getInitParameter(key); + log.info("New ConbfigurationValue; " + key + " ==> " + value); + this.properties.put(key, value); + } + } + } + + + public String getPropertieValue(String key, String defaultValue) { + String value = this.properties.get(key); + if (value == null) { + value = defaultValue; + } + return value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/propertiesreader/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/propertiesreader/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/servlet/GNVActionServlet.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,49 @@ +package de.intevation.gnv.servlet; + +import de.intevation.gnv.propertiesreader.PropertiesReaderFactory; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +import org.apache.struts.action.ActionServlet; + +/** + * The GNV ActionServlet. + * + * @author Tim Englich + */ +public class GNVActionServlet extends ActionServlet { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + // BasicConfigurator.configure(); + } + + static String LOGGINIG_CONFIG_FILE_ID = "de.intevation.gnv.servlet.log4j.configuration"; + + private static final long serialVersionUID = 3597396283436383943L; + + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + try { + String path = config.getServletContext().getRealPath("/") + + config.getInitParameter(LOGGINIG_CONFIG_FILE_ID); + PropertyConfigurator.configure(path); + log = Logger.getLogger(GNVActionServlet.class); + } catch (Exception e) { + log.error(e, e); + } + log.info("PropertiesReader will be configured."); + PropertiesReaderFactory.getInstance().initPropertiesReader(config); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/servlet/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/servlet/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +DOCUMENT ME! + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/util/ArtifactNamespaceContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/util/ArtifactNamespaceContext.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,59 @@ +package de.intevation.gnv.util; + +import java.util.Iterator; + +import javax.xml.XMLConstants; + +import javax.xml.namespace.NamespaceContext; + +/** + * The namespacecontext object used in xml documents retrieved by the artifact + * server. + * + * @author Sascha L. Teichmann + */ +public class ArtifactNamespaceContext +implements NamespaceContext +{ + /** + * The URI of the namespace of the artifacts. + */ + public final static String NAMESPACE_URI = "http://www.intevation.de/2009/artifacts"; + + /** + * The XML prefix for the artifacts namespace. + */ + public final static String NAMESPACE_PREFIX = "art"; + + public static final ArtifactNamespaceContext INSTANCE = + new ArtifactNamespaceContext(); + + public ArtifactNamespaceContext() { + } + + public String getNamespaceURI(String prefix) { + + if (prefix == null) { + throw new NullPointerException("Null prefix"); + } + + if (NAMESPACE_PREFIX.equals(prefix)) { + return NAMESPACE_URI; + } + + if ("xml".equals(prefix)) { + return XMLConstants.XML_NS_URI; + } + + return XMLConstants.NULL_NS_URI; + } + + public String getPrefix(String uri) { + throw new UnsupportedOperationException(); + } + + public Iterator getPrefixes(String uri) { + throw new UnsupportedOperationException(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/util/XMLUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/util/XMLUtils.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,253 @@ +package de.intevation.gnv.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringBufferInputStream; +import java.io.StringWriter; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; + +import javax.xml.transform.dom.DOMSource; + +import javax.xml.transform.stream.StreamResult; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.SAXException; + +/** + * @author Sascha L. Teichmann + */ +public class XMLUtils { + private static Logger logger = Logger.getLogger(XMLUtils.class); + + public XMLUtils() { + } + + public static class ElementCreator { + protected Document document; + protected String ns; + protected String prefix; + + public ElementCreator(Document document, String ns, String prefix) { + this.document = document; + this.ns = ns; + this.prefix = prefix; + } + + public Element create(String name) { + Element element = document.createElementNS(ns, name); + element.setPrefix(prefix); + return element; + } + + public void addAttr(Element element, String name, String value) { + Attr attr = document.createAttributeNS(ns, name); + attr.setValue(value); + attr.setPrefix(prefix); + element.setAttributeNode(attr); + } + } // class ElementCreator + + public static Document newDocument() { + try { + return DocumentBuilderFactory.newInstance().newDocumentBuilder() + .newDocument(); + } catch (ParserConfigurationException pce) { + logger.error(pce.getLocalizedMessage(), pce); + } + return null; + } + + public static XPath newXPath() { + return newXPath(null); + } + + public static XPath newXPath(NamespaceContext namespaceContext) { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + if (namespaceContext != null) { + xpath.setNamespaceContext(namespaceContext); + } + return xpath; + } + + public static Object xpath(Object root, String query, QName returnTyp) { + return xpath(root, query, returnTyp, null); + } + + public static final String xpathString(Object root, String query, + NamespaceContext namespaceContext) { + return (String) xpath(root, query, XPathConstants.STRING, + namespaceContext); + } + + public static final Object xpath(Object root, String query, + QName returnType, + NamespaceContext namespaceContext) { + if (root == null) { + return null; + } + + try { + XPath xpath = new XMLUtils().newXPath(namespaceContext); + if (xpath != null) { + return xpath.evaluate(query, root, returnType); + } + } catch (XPathExpressionException xpee) { + logger.error(xpee.getLocalizedMessage(), xpee); + } + + return null; + } + + public static Object getXPath(Object root, String query, QName returnType) { + return getXPath(root,query,returnType,ArtifactNamespaceContext.INSTANCE); + } + + public static Object getXPath( + Object root, String query, QName returnType, NamespaceContext context + ) { + return xpath(root, query, returnType, context); + } + + public static String getStringXPath(String xpath) { + return getStringXPath(xpath, null); + } + + public static NodeList getNodeSetXPath(Object root, String query) { + return (NodeList) getXPath(root, query, XPathConstants.NODESET); + } + + public static Node getNodeXPath(Object root, String query) { + return (Node) getXPath(root, query, XPathConstants.NODE); + } + + public static String getStringXPath(Object root, String xpath) { + return getStringXPath(root, xpath, null); + } + + public static String getStringXPath(Object root, String query, String def) { + String s = (String) getXPath(root, query, XPathConstants.STRING); + return s == null || s.length() == 0 ? def : s; + } + + public static Document readDocument(InputStream inputStream) { + Document returnValue = null; + try { + DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory + .newInstance(); + docBuilderFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); + returnValue = docBuilder.parse(inputStream); + } catch (ParserConfigurationException e) { + logger.error(e, e); + } catch (SAXException e) { + logger.error(e, e); + } catch (IOException e) { + logger.error(e, e); + } + return returnValue; + } + + public static String writeNode2String(Node node) { + try { + DOMSource source = new DOMSource(node); + return writeDOMSource2String(source); + } catch (TransformerConfigurationException e) { + logger.error(e, e); + } catch (TransformerFactoryConfigurationError e) { + logger.error(e, e); + } catch (TransformerException e) { + logger.error(e, e); + } + return null; + } + + public static Document reInitDocument(Document document) { + + StringBufferInputStream inputStream = new StringBufferInputStream( + writeDocument2String(document)); + return readDocument(inputStream); + } + + public static String writeDocument2String(Document document) { + try { + DOMSource source = new DOMSource(document); + return writeDOMSource2String(source); + } catch (TransformerConfigurationException e) { + logger.error(e, e); + } catch (TransformerFactoryConfigurationError e) { + logger.error(e, e); + } catch (TransformerException e) { + logger.error(e, e); + } + return null; + } + + /** + * @param source + * @return + * @throws TransformerFactoryConfigurationError + * @throws TransformerConfigurationException + * @throws TransformerException + */ + private static String writeDOMSource2String(DOMSource source) + throws TransformerFactoryConfigurationError, + TransformerConfigurationException, + TransformerException { + TransformerFactory transformerFactory = TransformerFactory + .newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult result = new StreamResult(sw); + transformer.transform(source, result); + return sw.getBuffer().toString(); + } + + public static boolean toStream(Document document, OutputStream out) { + try { + Transformer transformer = + TransformerFactory.newInstance().newTransformer(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(out); + transformer.transform(source, result); + return true; + } + catch (TransformerConfigurationException tce) { + logger.error(tce.getLocalizedMessage(), tce); + } + catch (TransformerFactoryConfigurationError tfce) { + logger.error(tfce.getLocalizedMessage(), tfce); + } + catch (TransformerException te) { + logger.error(te.getLocalizedMessage(), te); + } + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/util/XSLTransformer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/util/XSLTransformer.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,109 @@ +package de.intevation.gnv.util; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.UnsupportedEncodingException; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; + +import javax.xml.transform.dom.DOMSource; + +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + +/** + * This xsl transformer is used to transform incoming xml documents with the + * help of templates into a html representation. + * + * @author Tim Englich + */ +public class XSLTransformer { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(XSLTransformer.class); + + + private Map params; + + /** + * Constructor + */ + public XSLTransformer() { + super(); + } + + /** + * Turns toTransform into another format using the template + * templateFileName with the encoding. The parameters added in + * {@link #addParameter(java.lang.String, java.lang.String)} are available + * in the transformer. + * + * @param toTransform The node to be transformed. + * @param encoding The encoding to be used. + * @param templateFileName The template used for transformation. + * @return the transformed document as string. + */ + public String transform(Node toTransform, String encoding, + String templateFileName) { + String resultValue = null; + try { + //XMLUtils xmlUtils = new XMLUtils(); + Source templateSource = new StreamSource(new File(templateFileName)); + TransformerFactory xformFactory = TransformerFactory.newInstance(); + Transformer transformer = xformFactory + .newTransformer(templateSource); + + if (params != null) { + for(Map.Entry entry: params.entrySet()) { + transformer.setParameter(entry.getKey(), entry.getValue()); + } + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + StreamResult scrResult = new StreamResult(baos); + // log.debug(xmlUtils.writeNode2String(toTransform)); + DOMSource source = new DOMSource(toTransform); + transformer.transform(source, scrResult); + resultValue = new String(baos.toByteArray(), encoding); + } catch (TransformerConfigurationException e) { + log.error(e, e); + } catch (UnsupportedEncodingException e) { + log.error(e, e); + } catch (TransformerFactoryConfigurationError e) { + log.error(e, e); + } catch (TransformerException e) { + log.error(e, e); + } + + return resultValue; + } + + + /** + * Add a parameter that is required in the XSL sheet. + * + * @param name The name of the parameter. + * @param value The value of the parameter. + */ + public void addParameter(String name, String value) { + if (params == null) { + params = new HashMap(3); + } + + params.put(name, value); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/java/de/intevation/gnv/util/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/java/de/intevation/gnv/util/package.html Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,8 @@ + + + + + +Some helper classes mainly used to work with XML documents. + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/resources/applicationMessages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/resources/applicationMessages.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,125 @@ +# application.properties +application.name=${pom.name} +application.version=${pom.version} +application.releasedate=${timestamp} +application.reload=Klicken Sie hier, um es erneut zu versuchen. + +gnviewer.footer.home = Home +gnviewer.footer.contact = Kontakt +gnviewer.footer.about = Impressum + +gnviewer.header.restart = Neustart +gnviewer.header.language = Englisch +gnviewer.header.info = Info + +gnviewer.app.title = BSH-GDI genericViewer + +gnviewer.project.save = Projekt speichern +gnviewer.project.load = Projekt laden +gnviewer.project.load.button.src = ./images/laden.png + +gnviewer.history.title=\u00dcberblick +gnviewer.history.back.button=Bearbeiten + +gnviewer.fis.fis_marnet = Marnet +gnviewer.fis.fis_imis = IMIS +gnviewer.fis.fis_staun = STAUN +gnviewer.fis.fis_modeldata = Modelldaten +gnviewer.fis.fis_delphin = Delphin +gnviewer.fis.fis_thermosalinograph = Thermosalinograph +gnviewer.fis.fis_chemusurvey = Chemusurvey +gnviewer.fis.fis_gts = GTS +gnviewer.fis.fis_bsh_ctd = CTD +gnviewer.fis.fis_bsh_xbt = XBT +gnviewer.fis.fis_eisklimatologie = Eisklimatologie +gnviewer.fis.fis_sst = SST +gnviewer.fis.fis_seastate = Seegangsarchiv +gnviewer.fis.fis_seacat = SeaCat +gnviewer.fis.fis_currentmeter = Strommesser +gnviewer.fis.fis_icestations = Eismeldungen +gnviewer.fis.fis_nauthis = Nauthis +gnviewer.fis.fis_contis=Contis +gnviewer.fis.fis_marinefeatures = Marine Basisdaten + +gnviewer.select.button = Ausw\u00e4hlen +gnviewer.select.button.src = ./images/auswaehlen.png +gnviewer.draw.button = Aktualisieren + +gnviewer.productselection.overlay.title = Die Anfrage wird bearbeitet. Bitte gedulden Sie sich einen Moment. +gnviewer.productselection.fisselection.title = Fachinformationssystem + +# Statistik +gnviewer.statistics.header.title=Datenstatistik +gnviewer.statistics.table.header.param=Parameter +gnviewer.statistics.table.header.value=Wert +gnviewer.statistics.series=Series +gnviewer.statistics.descriptive.arithmeticMean=Arithmetisches Mittel +gnviewer.statistics.descriptive.geometricMean=Geometrisches Mittel +gnviewer.statistics.descriptive.kurtosis=Kurtosis +gnviewer.statistics.descriptive.kurtosisClass=kurtosisClass +gnviewer.statistics.descriptive.max=Maximum +gnviewer.statistics.descriptive.min=Minimum +gnviewer.statistics.descriptive.n=Anzahl Werte +gnviewer.statistics.descriptive.percentile.90=Perzentil (90/10) +gnviewer.statistics.descriptive.percentile.75=Perzentil (75/25) +gnviewer.statistics.descriptive.percentile.50=Perzentil (50/50) +gnviewer.statistics.descriptive.percentile.10=Perzentil (10/90) +gnviewer.statistics.descriptive.deviation=Standardabweichung +gnviewer.statistics.descriptive.variance=Varianz +gnviewer.statistics.descriptive.intercept=Intercept +gnviewer.statistics.descriptive.slope=Steigung +gnviewer.statistic.button = Statistik + +# Histogramm +gnviewer.histogram.button=Histogramm +gnviewer.histogram.options.header.title=Histogrammoptionen +bincount=Anzahl der Klassen +binwidth=Breite einer Klasse + +# diagram options dialog +gnviewer.diagram.button=Diagramm +gnviewer.diagram.options.header.title=Diagrammoptionen + +# wms +gnviewer.wms.server.path=URL des WMS +gnviewer.wms.server.layer=Name des Layers +gnviewer.wms.layer.ttl=Layer ist g\u00fcltig bis +gnviewer.wms.options.header.title=WMS Optionen + +# attachedOutputOptions +gnviewer.output.options.diagramm.alt=Diagramm +gnviewer.output.options.histogram.alt=Histogramm +gnviewer.output.options.save.title=Diagramm speichern +gnviewer.output.options.export.csv.title=Daten als CSV exportieren +gnviewer.output.options.export.odv.title=Daten als ODV exportieren +gnviewer.output.options.export.pdf.title=Diagramm als PDF exportieren +gnviewer.output.options.export.svg.title=Diagramm als SVG exportieren +gnviewer.output.options.export.zip.title=ZIP-Archiv exportieren +gnviewer.output.options.export.wms.title=WMS-Layer bereitstellen + +# export options +gnviewer.export.fieldset.title=Aktionen + +height=H\u00f6he +width=Breite +points=Zeichne Datenpunkte +title=Titel + +# Fehlermeldungen: + +java.io.ioexception..connection.refused=Die Verbindung zur Artifaktdatenbank ist unterbrochen. Bitte probieren Sie es zu einem sp\u00e4teren Zeitpunkt erneut. +java.io.ioexception..connection.reset=Die Verbindung zur Artifaktdatenbank ist unterbrochen. Bitte probieren Sie es zu einem sp\u00e4teren Zeitpunkt erneut. +java.io.ioexception..unable.to.parse.the.response.http.version..end.of.stream.reached.too.early=Die Verbindung zur Artifaktdatenbank wurde unerwartet unterbrochen. +no.inputdata.given..please.select.at.least.one.entry=Es wurde kein Eintrag ausgew\u00e4hlt. Bitte w\u00e4hlen sie mindestens einen Eintrag aus. +de.intevation.gnv.geobackend.base.query.exception.queryexception..java.sql.sqlexception =Es ist ein interner Serverfehler aufgetreten. Bitte benachrichtigen Sie den Support. +java.io.ioexception..the.server.encountered.an.unexpected.condition.which.prevented.it.from.fulfilling.the.request=Es ist ein interner Serverfehler aufgetreten. Bitte benachrichtigen Sie den Support. +java.lang.illegalargumentexception..inputstream.cannot.be.null=Es ist ein interner Serverfehler aufgetreten. Bitte benachrichtigen Sie den Support. +input.is.not.valid.for.this.state=Der von Ihnen eingegebene Wert ist ung\u00fcltig. Bitte versuchen Sie es erneut. +input.not.a.integer= ist keine g\u00fcltige Ganzzahl. Bitte versuchen Sie es erneut. +input.not.a.double= ist keine g\u00fcltige Flie\u00dfkommazahl. Bitte versuchen Sie es erneut. +upload.failure=Beim Hochladen der Datei ist ein Fehler aufgetreten. +no.artifact.chosen=Es ist noch kein FIS gew\u00e4hlt. +invalid.artifact=Ung\u00fcltiges Artefakt Dokument gefunden. +mismatching.checksum=Ung\u00fcltiges Artefakt Dokument gefunden. +no.such.factory=Ung\u00fcltiges Artefakt Dokument gefunden. +java.io.ioexception..no.such.artifact=Ihr Artefakt ist ung\u00fcltig oder bereits abgelaufen. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/resources/applicationMessages_en.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/resources/applicationMessages_en.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,123 @@ +# application.properties +application.name=${pom.name} +application.version=${pom.version} +application.releasedate=${timestamp} +application.reload=Click here to try again + +gnviewer.footer.home = Home +gnviewer.footer.contact = Contact +gnviewer.footer.about = Imprint + +gnviewer.header.restart = Restart +gnviewer.header.language = German +gnviewer.header.info = Info + +gnviewer.app.title = BSH-GDI genericViewer + +gnviewer.history.title=Summary +gnviewer.history.back.button=Change + +gnviewer.project.save = Save Project +gnviewer.project.load = Load Project +gnviewer.project.load.button.src = ./images/load.png + +gnviewer.fis.fis_marnet = Marnet +gnviewer.fis.fis_imis = IMIS +gnviewer.fis.fis_staun = STAUN +gnviewer.fis.fis_modeldata = Modeldata +gnviewer.fis.fis_delphin = Delphin +gnviewer.fis.fis_thermosalinograph = Thermosalinograph +gnviewer.fis.fis_chemusurvey = Chemusurvey +gnviewer.fis.fis_gts = GTS +gnviewer.fis.fis_bsh_ctd = CTD +gnviewer.fis.fis_bsh_xbt = XBT +gnviewer.fis.fis_eisklimatologie = Iceclimatology +gnviewer.fis.fis_sst = SST +gnviewer.fis.fis_seastate = Sea State +gnviewer.fis.fis_seacat = SeaCat +gnviewer.fis.fis_currentmeter = Current Meter +gnviewer.fis.fis_icestations = Ice Station Report +gnviewer.fis.fis_nauthis = Nauthis +gnviewer.fis.fis_contis=Contis +gnviewer.fis.fis_marinefeatures = Marine Features + +gnviewer.select.button = Choose +gnviewer.select.button.src = ./images/choose.png +gnviewer.draw.button = Update + +gnviewer.productselection.overlay.title = Your request will be processed. Please wait... +gnviewer.productselection.fisselection.title = Data set + +# Statistik +gnviewer.statistics.header.title=Statistics +gnviewer.statistics.table.header.param=Parameter +gnviewer.statistics.table.header.value=Value +gnviewer.statistics.series=Series +gnviewer.statistics.descriptive.arithmeticMean=Arithmetic mean +gnviewer.statistics.descriptive.geometricMean=Geometric Mean +gnviewer.statistics.descriptive.kurtosis=Kurtosis +gnviewer.statistics.descriptive.kurtosisClass=kurtosisClass +gnviewer.statistics.descriptive.max=Maximum +gnviewer.statistics.descriptive.min=Minimum +gnviewer.statistics.descriptive.n=Number of Values +gnviewer.statistics.descriptive.percentile.90=Percentile (90/10) +gnviewer.statistics.descriptive.percentile.75=Percentile (75/25) +gnviewer.statistics.descriptive.percentile.50=Percentile (50/50) +gnviewer.statistics.descriptive.percentile.10=Percentile (90/10) +gnviewer.statistics.descriptive.deviation=Standard deviation +gnviewer.statistics.descriptive.variance=Variance +gnviewer.statistics.descriptive.intercept=Intercept +gnviewer.statistics.descriptive.slope=Increase +gnviewer.statistic.button = Statistic + +# Histogramm +gnviewer.histogram.button=Histogram +gnviewer.histogram.options.header.title=Histogram Options +bincount=Number of classes +binwidth=Class width + +# diagram options dialog +gnviewer.diagram.button=Diagram +gnviewer.diagram.options.header.title=Diagram options + +# wms +gnviewer.wms.server.path=WMS URL +gnviewer.wms.server.layer=Layername +gnviewer.wms.layer.ttl=Layer is valid to +gnviewer.wms.options.header.title=WMS Optionen + +# attachedOutputOptions +gnviewer.output.options.diagramm.alt=Diagram +gnviewer.output.options.histogram.alt=Histogram +gnviewer.output.options.save.title=Save Diagram +gnviewer.output.options.export.csv.title=Export Data as CSV +gnviewer.output.options.export.odv.title=Export Data as ODV +gnviewer.output.options.export.pdf.title=Export chart as PDF +gnviewer.output.options.export.svg.title=Export chart as SVG +gnviewer.output.options.export.zip.title=Export as ZIP archive +gnviewer.output.options.export.wms.title=Serve as WMS layer + +# export options +gnviewer.export.fieldset.title=Actions + +height=Height +width=Width +points=Draw data points +title=Title + +java.io.ioexception..connection.refused = The Connection to the ArtifactDatabase is interrupted. Please try again later. +java.io.ioexception..connection.reset = The Connection to the ArtifactDatabase is interrupted. Please try again later. +java.io.ioexception..unable.to.parse.the.response.http.version..end.of.stream.reached.too.early= The Connection to the ArtifactDatabase was interrupted unexpected. +no.inputdata.given..please.select.at.least.one.entry = No Entry was chosen. Please select at least one entry. +de.intevation.gnv.geobackend.base.query.exception.queryexception..java.sql.sqlexception: A internal Server error has occurred. Please contact the Support. +java.io.ioexception..the.server.encountered.an.unexpected.condition.which.prevented.it.from.fulfilling.the.request = A internal Server error has occurred. Please contact the Support. +java.lang.illegalargumentexception..inputstream.cannot.be.null = A internal Server error has occurred. Please contact the Support. +input.is.not.valid.for.this.state=You entered an invalid value. Please try again. +input.not.a.integer= is not a valid integer. Please try again. +input.not.a.double= is not a valid floating-point number. Please try again. +upload.failure=An error occured while uploading file. +no.artifact.chosen=No fis selected yet. +invalid.artifact=Invalid artifact found. +mismatching.checksum=Invalid artifact found. +no.such.factory=Invalid artifact found. +java.io.ioexception..no.such.artifact=Your artifact is invalid or out of date. diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/META-INF/context.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/META-INF/context.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,2 @@ + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/classes/log4j.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/classes/log4j.properties Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,21 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=DEBUG, A1 +log4j.rootLogger=DEBUG, BSH + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.appender.BSH=org.apache.log4j.RollingFileAppender +log4j.appender.BSH.File=${catalina.base}/logs/gnv.log +log4j.appender.BSH.layout=org.apache.log4j.PatternLayout +log4j.appender.BSH.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +# Abschalten des geschwätzigen Loggings in dre Klasse JspServlet +log4j.category.org.apache.jasper=WARN +log4j.category.org.apache.catalina=WARN +log4j.category.org.apache.commons=WARN +log4j.category.org.apache.struts=WARN diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/config/struts-config.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/config/struts-config.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/config/templates/describe-ui-static.xsl Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + {$edit} + + + + + {$edit} + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + +   + + + +
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/config/templates/describe-ui.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/config/templates/describe-ui.xsl Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Beispiel WKT-Linestring einfügen:
+
+ + Beispiel WKT-Polygon einfügen:
+
+
+ + + + + : + + + + +
+ + +
+ + + + + + +
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/footer.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/footer.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,29 @@ +<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" language="java" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> + + + + + + + + + +
© 2010 Bundesamt für Seeschifffahrt und Hydrographie
+ + + + + + +
+ +<%--div style="clear: left; margin-top: 40px;"/--%> diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/header.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/header.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,25 @@ +<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" language="java"%> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles"%> + +
+

BSH Generischer Viewer

+
+ +
+ + + + + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/imprint.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/imprint.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,41 @@ + +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> + + + + + <bean:message key="gnviewer.app.title"/> + + + + + +
+
+

BSH Generischer Viewer

+
+ +
+ +
+ + + + + + +
+
+ TODO: Impressum. +
+
+ +
+
+ + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,38 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<%@page import="java.net.URLEncoder"%> +<% + // fetch diagramm parameter from request if the user clicked 'draw' + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + + String target = "chart"; + String mimeType = null; + String parameterString = ""; + + boolean supportChart = sm.getOutputMode(target) != null; + + if (supportChart){ + mimeType = sm.getOutputMode(target).getMimeType(); + DiagrammOptions diagrammOptions = sm.getDiagrammOptions(); + Collection op = sm.getOutputMode(target).getOutputParameters(); + + if (op != null){ + Iterator it = op.iterator(); + while (it.hasNext()){ + OutputParameter parameter = it.next(); + parameterString = parameterString +"&"+parameter.getName()+"="+(diagrammOptions != null ? diagrammOptions.getValue(parameter.getName()): parameter.getValue()); + } + } + } +%> + +<%-- diagramm is not null if the user clicked the 'draw' button --%> +
+ <bean:message key="gnviewer.output.options.diagramm.alt"/> +
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_options_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,110 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.CommunicationKeys"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputMode"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ExportMode"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<%@page import="java.net.URLEncoder"%> +<% + String exceptionMsg = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_MESSAGE); + String exceptionValue = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_VALUE); + String target = "chart"; + String targetPDF = "pdf"; + String targetSVG = "svg"; + String targetIMG = "img"; + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + OutputMode outputMode = sm.getOutputMode(target); + DiagrammOptions diagrammOptions = sm.getDiagrammOptions(); + + boolean useDiagrammOptions = diagrammOptions != null; + ExportMode supportIMG = outputMode.getExportMode(targetIMG); + ExportMode supportPDF = outputMode.getExportMode(targetPDF); + ExportMode supportSVG = outputMode.getExportMode(targetSVG); + + String mimeType = outputMode.getMimeType(); + String parameterString = ""; + Collection op = outputMode.getOutputParameters(); + + if (op != null){ + Iterator it = op.iterator(); + while (it.hasNext()){ + OutputParameter parameter = it.next(); + parameterString = parameterString +"&"+parameter.getName()+"="+(diagrammOptions != null ? diagrammOptions.getValue(parameter.getName()): parameter.getValue()); + } + } + + + String mimeTypeIMG = null; + if (supportIMG != null) { + mimeTypeIMG = supportIMG.getMimeType(); + } + String mimeTypePDF = null; + if (supportPDF != null) { + mimeTypePDF = supportPDF.getMimeType(); + } + String mimeTypeSVG = null; + if (supportSVG != null) { + mimeTypeSVG = supportSVG.getMimeType(); + mimeTypeSVG = URLEncoder.encode(mimeTypeSVG, "UTF-8"); + } +%> +
+
+ + + + + <% if (exceptionMsg != null) {%> +
+ '<%=exceptionValue%>' +
+ <%}%> + +
+ + <%if (outputMode != null && outputMode.getOutputParameters() != null && !outputMode.getOutputParameters().isEmpty()){ + Iterator it = outputMode.getOutputParameters().iterator(); + while (it.hasNext()){ + OutputParameter om = it.next(); %> + + + + + <%}%> +
+ + + <%if (om.getType().equalsIgnoreCase("boolean")){ + boolean checked = useDiagrammOptions ? "true".equalsIgnoreCase(diagrammOptions.getValue(om.getName())) : om.getValue().equalsIgnoreCase("true"); + %> + /> + <%}else{%> + + <%}%> +
+
+ "/> + <%}%> + <%if (supportIMG != null) { %> + "> + + <%}%> + <%if (supportPDF != null) { %> + "> + + <%}%> + <%if (supportSVG != null) { %> + "> + + <%}%> +
+
+
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_diagramm_statistics_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,43 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="java.util.Collection"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticValue"%> +<%@page import="java.util.Iterator"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet"%> +
+<% + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + Collection statistics = sm.getStatistics(); +%> +
+ + + + <%if (statistics != null){ + Iterator it = statistics.iterator(); + while (it.hasNext()){ + ArtifactStatisticsSet set = it.next(); + %> +

<%=set.getName()%>

+ + + + + + <% + Iterator sit = set.getStatisticValues().iterator(); + while (sit.hasNext()){ + ArtifactStatisticValue asv = sit.next(); + %> + + + + + <%}%> +
<%=asv.getValue()%>
+ <%} %> + <%}%> +
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_export_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,106 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactObject"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<%@page import="java.net.URLEncoder"%> +<% + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + ArtifactObject artifact = sm.getCurrentArtifact(); + String mimeType = null; + String wmslayer = null; + String parameterString = ""; + + String target = "chart"; + String targetCSV = "csv"; + String targetODV = "odv"; + String targetZIP = "zip"; + String targetWMS = "wms"; + String targetSta = "statistics"; + String targetHis = "histogram"; + + boolean supportChart = sm.getOutputMode(target) != null; + boolean supportCSV = sm.getOutputMode(targetCSV) != null; + boolean supportODV = sm.getOutputMode(targetODV) != null; + boolean supportZIP = sm.getOutputMode(targetZIP) != null; + boolean supportWMS = sm.getOutputMode(targetWMS) != null; + boolean supportSta = sm.getOutputMode(targetSta) != null; + boolean supportHis = sm.getOutputMode(targetHis) != null; + + if (supportChart){ + mimeType = sm.getOutputMode(target).getMimeType(); + DiagrammOptions diagrammOptions = sm.getDiagrammOptions(); + Collection op = sm.getOutputMode(target).getOutputParameters(); + + if (op != null){ + Iterator it = op.iterator(); + while (it.hasNext()){ + OutputParameter parameter = it.next(); + parameterString = parameterString +"&"+parameter.getName()+"="+(diagrammOptions != null ? diagrammOptions.getValue(parameter.getName()): parameter.getValue()); + } + } + } + + String mimeTypeCSV = null; + if (supportCSV){ + mimeTypeCSV = sm.getOutputMode(targetCSV).getMimeType(); + } + + String mimeTypeODV = null; + if (supportODV){ + mimeTypeODV = sm.getOutputMode(targetODV).getMimeType(); + } + + String mimeTypeZIP = null; + if (supportZIP) { + mimeTypeZIP = sm.getOutputMode(targetZIP).getMimeType(); + } + + String mimeTypeWMS = null; + if (supportWMS) { + mimeTypeWMS = sm.getOutputMode(targetWMS).getMimeType(); + wmslayer = artifact.getId(); + } +%> + +<%-- display export options if one is supported in this state --%> +<% if (supportChart || supportCSV || supportODV || supportWMS || supportZIP) { %> +
+
+ + <%if (supportChart) { %> + " title=""> + + <%}%> + <%if (supportWMS) { %> + "> + + <%}%> + <%if (supportZIP) { %> + "> + + <%}%> + + <%if (supportSta) { %> + " title=""> + + <%}%> + + <%if (supportHis) { %> + " title=""> + + <%}%> + <%if (supportCSV) { %> + "> + + <%}%> + <%if (supportODV) { %> + "> + + <%}%> +
+
+<%}%> diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_fis_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,31 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="java.util.Collection"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactObject"%> +<%@page import="java.util.Iterator"%> +<% + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + Collection artifactFactories = sm.getArtifactFactories(); + String prefix = "gnviewer.fis."; +%> +
+
" method="post"> +
+ + <%if (artifactFactories != null){%> + + + <%}%> +
+ "/> +
+
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_histogram_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,32 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<% + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + + String parameterString = ""; + String target = "histogram"; + String mimeType = sm.getOutputMode(target).getMimeType(); + + DiagrammOptions diagrammOptions = sm.getDiagrammOptions(); + Collection op = sm.getOutputMode(target).getOutputParameters(); + + if (op != null){ + Iterator it = op.iterator(); + while (it.hasNext()){ + OutputParameter parameter = it.next(); + parameterString = parameterString +"&"+parameter.getName()+"="+(diagrammOptions != null ? diagrammOptions.getValue(parameter.getName()): parameter.getValue()); + } + + parameterString += "&bintype="+request.getAttribute("bintype"); + } +%> + +
+ <bean:message key="gnviewer.output.options.histogram.alt"/> +
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_histogram_options_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,133 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.CommunicationKeys"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputMode"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ExportMode"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<%@page import="java.net.URLEncoder"%> +<% + String exceptionMsg = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_MESSAGE); + String exceptionValue = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_VALUE); + String target = "histogram"; + String targetPDF = "pdf"; + String targetSVG = "svg"; + String targetIMG = "img"; + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + OutputMode outputMode = sm.getOutputMode(target); + DiagrammOptions diagrammOptions = sm.getDiagrammOptions(); + + boolean useDiagrammOptions = diagrammOptions != null; + ExportMode supportIMG = outputMode.getExportMode(targetIMG); + ExportMode supportPDF = outputMode.getExportMode(targetPDF); + ExportMode supportSVG = outputMode.getExportMode(targetSVG); + + String mimeType = outputMode.getMimeType(); + String parameterString = ""; + Collection op = outputMode.getOutputParameters(); + + if (op != null){ + Iterator it = op.iterator(); + while (it.hasNext()){ + OutputParameter parameter = it.next(); + parameterString = parameterString +"&"+parameter.getName()+"="+(diagrammOptions != null ? diagrammOptions.getValue(parameter.getName()): parameter.getValue()); + } + } + + String mimeTypeIMG = null; + if (supportIMG != null) { + mimeTypeIMG = supportIMG.getMimeType(); + } + String mimeTypePDF = null; + if (supportPDF != null) { + mimeTypePDF = supportPDF.getMimeType(); + } + String mimeTypeSVG = null; + if (supportSVG != null) { + mimeTypeSVG = supportSVG.getMimeType(); + mimeTypeSVG = URLEncoder.encode(mimeTypeSVG, "UTF-8"); + } +%> +
+
+ + + + + <% if (exceptionMsg != null) {%> +
+ '<%=exceptionValue%>' +
+ <%}%> + +
+ + <%if (outputMode != null && outputMode.getOutputParameters() != null && !outputMode.getOutputParameters().isEmpty()){ + Iterator it = outputMode.getOutputParameters().iterator(); + while (it.hasNext()){ + OutputParameter om = it.next(); + String diaOpts = null; + if (diagrammOptions != null) { + diaOpts = request.getParameter("bintype"); + }%> + + + + + + <%}%> +
+ <%if (om.getName().equals("bincount")) { + String check = ""; + if (diaOpts != null && diaOpts.equalsIgnoreCase("binwidth")) { + check = ""; + } + else { + check = "checked=\"checked\""; + }%> + name="bintype" value="bincount" id="checkCount" onClick="toggleBinType('checkWidth')">  + <%}%> + <%if (om.getName().equals("binwidth")) { + String check = ""; + if (diaOpts != null && diaOpts.equalsIgnoreCase("binwidth")) { + check = "checked=\"checked\""; + } + else if (diaOpts == null) { + check = ""; + }%> + name="bintype" value="binwidth" id="checkWidth" onClick="toggleBinType('checkCount')">  + <%}%> + + + + <%if (om.getType().equalsIgnoreCase("boolean")){ + boolean checked = useDiagrammOptions ? "true".equalsIgnoreCase(diagrammOptions.getValue(om.getName())) : om.getValue().equalsIgnoreCase("true"); + %> + /> + <%}else{%> + + <%}%> +
+ "/> + <%}%> + <%if (supportIMG != null) { %> + "> + + <%}%> + <%if (supportPDF != null) { %> + "> + + <%}%> + <%if (supportSVG != null) { %> + "> + + <%}%> +
+
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_mapviewercall_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,66 @@ +<% +String geometry = "POINT (6.3333 56.5)"; +String geometrytype = request.getParameter("gt"); +if(geometrytype != null){ + if (geometrytype.equals("POINT")){ + geometry = "POINT (6.3333 56.5)"; + }else if (geometrytype.equals("LINESTRING")){ + geometry = "LINESTRING (0.4911 56.2489,10.4464 58.1608,12.2321 56.4127,13.1250 54.8832,15.4018 54.5008,19.6875 56.4127,20.6250 59.0349,28.1250 60.2640)"; + }else if (geometrytype.equals("POLYGON")){ + geometry = "POLYGON ((-1.5763 58.3616, 0.7526 53.8428, 4.2686 53.1972, 7.9217 54.1441, 7.6020 56.2959, 11.5747 57.2857, 0.4788 58.4908, 4.2686 58.8996, 0.0219 58.5768, -1.5763 58.3616))"; + } +} +%> + +
+
" method="post"> +
+ Kartenviewer Request + + +
+
+
\ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/includes/display_wms_options_inc.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/includes/display_wms_options_inc.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,66 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="de.intevation.gnv.action.CommunicationKeys"%> +<%@page import="de.intevation.gnv.action.sessionmodel.DiagrammOptions"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputMode"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.OutputParameter"%> +<%@page import="java.util.Collection"%> +<%@page import="java.util.Iterator"%> +<%@page import="java.net.URLEncoder"%> +<% + String exceptionMsg = (String) request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_MESSAGE); + String exceptionValue= (String) request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_VALUE); + String layer = (String) request.getAttribute("layer"); + String target = "wms"; + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + OutputMode om = sm.getOutputMode(target); + DiagrammOptions opts = sm.getDiagrammOptions(); + String uuid = sm.getCurrentArtifact().getId(); +%> + +
+
+ + + + + <% if (exceptionMsg != null) {%> +
+ '<%=exceptionValue%>' +
+ <%}%> + +
"> + + <% Collection params = om.getOutputParameters(); + if (om != null && params != null && !params.isEmpty()) { + Iterator iter = params.iterator(); + while (iter.hasNext()) { + OutputParameter param = iter.next(); %> + + + + + + <%} + }%> + + + +
+ <%if (param.getType().equalsIgnoreCase("boolean")) { + boolean checked = (opts != null) ? "true".equalsIgnoreCase(opts.getValue(param.getName())) : param.getValue().equalsIgnoreCase("true"); + %> + /> + <%} + else {%> + + <%}%> +
+ "/> +
+
+
+
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/index.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/index.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,186 @@ +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %> +<%@page import="java.util.Collection"%> +<%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactObject"%> +<%@page import="de.intevation.gnv.action.CommunicationKeys"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%> +<%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%> +<%@page import="java.util.Iterator"%> +<% + String exception = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID); + SessionModel sm = SessionModelFactory.getInstance().getSessionModel(request); + Object ui = request.getAttribute("ui"); + Object staticui = request.getAttribute("staticui"); + Object chart = request.getAttribute("chart"); + Object statistic = request.getAttribute("statistic"); + Object histogram = request.getAttribute("histogram"); + Object wms = request.getAttribute("wms"); + Object wms_published = request.getAttribute("wms_published"); + String serverPath = (String) request.getAttribute("mapserver"); + String mapfilePath = (String) request.getAttribute("mapfile"); + String layerName = (String) request.getAttribute("layer"); + String timeToLive = (String) request.getAttribute("ttl"); + boolean furthertargets = true; + + if (chart == null && statistic == null && histogram == null && wms == null) { + boolean supportChart = sm.getOutputMode("chart") != null; + if (supportChart) { + chart = "true"; + } + } + + Object furthertargetsObject = request.getAttribute("furthertargets"); + if (furthertargetsObject != null){ + furthertargets = ((Boolean)furthertargetsObject).booleanValue(); + } + + Object exceptionMessage = request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID); + exceptionMessage = (exceptionMessage != null ? exceptionMessage.toString().replaceAll(" ", ".").replaceAll(":",".").toLowerCase() : null); + exceptionMessage = (exceptionMessage != null && exceptionMessage.toString().endsWith(".") ? exceptionMessage.toString().substring(0,exceptionMessage.toString().length()-1) : exceptionMessage); + + boolean showmapviewercallBody = request.getAttribute("MAPVIEWERCALL") != null; + + String exceptionProject = (String) request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_PROJECT); + exceptionProject = exceptionProject != null ? exceptionProject.toLowerCase() : null; + exceptionProject = exceptionProject != null ? exceptionProject.replaceAll(" ", ".") : null; +%> + + <%-- div container for project loading/saving and error messages related to this --%> +
+ + + + + +
+ "> + | + + +
+
" method="post" enctype="multipart/form-data"> +
+
"/>
+
+
+
+ <%if (exceptionProject != null) {%> +
+ +
+ "> + + +
+ <%}%> + <%if (showmapviewercallBody){ %> + + <%}%> +
+ + + + + + +
+ <%-- the parameter panel is following --%> +
+ <%if (staticui == null){ %> + + <%} else {%> +
+
+ + <%=staticui.toString()%> +
+
+ <%}%> + + <%-- render the dynamic part to feed the state and advance to the next state --%> + <%if (ui != null){%> +
+
" method="post"> +
+ + <%-- error message, if user input was not valid --%> + <%if (exception != null) {%> +
<%=exception%>
+ <%}%> + <%=ui != null ? ui.toString().replaceAll(" ", "") : "" %> + + <%if(furthertargets){%> +
+ "/> + <%}%> +
+
+
+ <%}%> + + <%-- render export options if existing for this state --%> + + + <%if (chart != null) {%> + + <%}%> + + + <%if (histogram != null) {%> + + <%}%> + + <%-- render wms options --%> + <%if (wms != null) {%> + + <%}%> +
+
+ <%if (exceptionMessage != null){ %> +
+ +

+ "> + + +

+
+ <%}%> + <%if (chart != null) {%> + <%-- render chart options if existing for this state --%> + + <%}%> + + <%-- render statistic --%> + <%if (statistic != null) {%> + + <%}%> + + <%-- render histogram --%> + <%if (histogram != null) {%> + + <%}%> + + <%-- render wms layer --%> + <%if (wms_published != null) {%> +
+
+ + + + + + + + + + + + + +
:<%=serverPath%>?SERVICE=WMS&REQUEST=GetCapabilities
:<%=layerName%>
:<%=timeToLive%>
+
+
+
+ <%}%> +
diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/info.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/info.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,41 @@ + +<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> + + + + + <bean:message key="gnviewer.app.title"/> + + + + + +
+
+

BSH Generischer Viewer

+
+ +
+ +
+ + + + + + +
+
+ TODO: Info +
+
+ +
+
+ + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/mainlayout.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/mainlayout.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,94 @@ + +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> + + + + <bean:message key="gnviewer.app.title"/> + + + + + + + + + + + + + + +
+
+
+

+ +

+ "> + + +

+

+
+
+
+
+ +
+
+ +
+
+ +
+
+ + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/version.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/version.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,45 @@ + +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> + + + + <bean:message key="gnviewer.app.title"/> + + + + + + + + + + + + + +
+
+
+

+ +

+
+
+
+ +
+
+

Generischer Viewer

+ Name:
+ Version:
+ Date:
+

Artifaktdatenbank

+ Name: N/N
+ Version: N/N
+ Date: N/N
+
+ +
+ + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/jsp/wmslayout.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/jsp/wmslayout.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,103 @@ + +<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> +<% + String serverPath = (String) request.getAttribute("mapserver"); + String mapfilePath = (String) request.getAttribute("mapfile"); + String layerName = (String) request.getAttribute("layer"); + String timeToLive = (String) request.getAttribute("ttl"); +%> + + + + + <bean:message key="gnviewer.app.title"/> + + + + + + + + + + + + + + +
+
+
+

+ +

+
+
+
+
+ +
+
+ +
+
+
+ +
+
+ + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/WEB-INF/web.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/WEB-INF/web.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,54 @@ + + + + Archetype Created Web Application + + action + de.intevation.gnv.servlet.GNVActionServlet + + + + config + /WEB-INF/config/struts-config.xml + + + + + + + + de.intevation.gnv.artifactdatabase.client.ArtifactDatabase.count + 1 + + + + + de.intevation.gnv.artifactdatabase.client.ArtifactDatabase.url.1 + http://localhost:8181 + + + + 1 + + + + + action + *.do + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/arrow_refresh.png Binary file gnv/src/main/webapp/images/arrow_refresh.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/auswaehlen.png Binary file gnv/src/main/webapp/images/auswaehlen.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/back_button.png Binary file gnv/src/main/webapp/images/back_button.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/bsh_logo.gif Binary file gnv/src/main/webapp/images/bsh_logo.gif has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/chart_bar.png Binary file gnv/src/main/webapp/images/chart_bar.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/chart_curve.png Binary file gnv/src/main/webapp/images/chart_curve.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/choose.png Binary file gnv/src/main/webapp/images/choose.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/data_export.png Binary file gnv/src/main/webapp/images/data_export.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/delete.png Binary file gnv/src/main/webapp/images/delete.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/diagram_export.png Binary file gnv/src/main/webapp/images/diagram_export.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/disk.png Binary file gnv/src/main/webapp/images/disk.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/laden.png Binary file gnv/src/main/webapp/images/laden.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/load.png Binary file gnv/src/main/webapp/images/load.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/map_go.png Binary file gnv/src/main/webapp/images/map_go.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/pdf.png Binary file gnv/src/main/webapp/images/pdf.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/statistics.png Binary file gnv/src/main/webapp/images/statistics.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/svg.png Binary file gnv/src/main/webapp/images/svg.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/images/tick.png Binary file gnv/src/main/webapp/images/tick.png has changed diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/index.jsp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/index.jsp Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,2 @@ +<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/scripts/gnviewer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/scripts/gnviewer.js Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,17 @@ +function displayOverlay() { + adjustOverlaySize(); + showDiv("overlay"); + showDiv("overlayContent"); +} + +function adjustOverlaySize() { + var lHeight = document.getElementById("page").scrollHeight; + //alert(lHeight); + var lOverlay = document.getElementById("overlay"); + lOverlay.style.height = lHeight + 'px'; +} + +function showDiv(pName) { + var el = document.getElementById(pName); + el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible"; +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/styles/calendar-blue.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/styles/calendar-blue.css Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,232 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #556; + font-size: 11px; + color: #000; + cursor: default; + background: #eef; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #778 url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #fff; + color: #000; + padding: 2px; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ + background: #778; + color: #fff; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #bdf; +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #556; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #aaf; + color: #000; + border: 1px solid #04f; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #77c; + padding: 2px 0px 0px 2px; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #456; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #bdf; +} + +.calendar tbody .rowhilite td { + background: #def; +} + +.calendar tbody .rowhilite td.wn { + background: #eef; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #def; + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #cde; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fff; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { /* Cell showing selected date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #556; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #fff; + color: #445; + border-top: 1px solid #556; + padding: 1px; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #aaf; + border: 1px solid #04f; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #77c; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #def; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #acf; +} + +.calendar .combo .active { + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + background: #eef; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/styles/default.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/styles/default.css Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,600 @@ +@charset +"ISO-8859-1" +; + +body { + background-color: #FFFFFF; + font-family: verdana, arial, Helvetica, sans-serif; + + height: 100%; + margin: 0; + padding: 0; +} + +br { + padding: 0; + margin: 0; + font-size: 0; + clear: both; +} + +form { + margin: 0; + padding: 0; +} + +h1 { + font-weight: bold; + font-size: 0.9em; + color: #00416B; +} + +h2 { + font-weight: bold; + font-size: 0.8em; + color: #00416B; +} + +a { + color: #FF6600; + text-decoration: underline; +} + +legend { + border: 1px solid #003A66; + padding: 4px 5px; + margin: 0 0 0 0; + background-color: white; + font-weight: bolder; + color: #003A66; + clear: both; +} + +fieldset { + margin: 5px 0 0 10px; + padding-left: 10px; + padding-right: 10px; + border: 1px solid #003A66; + background-color: #F2F1F5; + background-repeat: repeat-x; + background-position: top left; + display: block; +} + +div { + margin: 0; + padding: 0; +} + +#browseDiv { + float: left; + margin-top: 1px; +} + +#loadDiv { + float: right; + margin-left: 5px; +} + +p, li, dl, input, select, address, legend, label, fieldset span { + font-size: 0.7em; +} + +legend.expandableFieldset { + cursor: pointer; +} + +select, textarea { + width: 250px; +} + +textarea.mapviewer { + width: 450px; +} + +input.textinput { + width: 250px; +} + + +textarea { + font-family: verdana, arial, Helvetica, sans-serif; + font-size: 0.7em; +} + +table.dynamic { + font-size: 1.2em; +} + +table.static { + margin: 0 0 0 0; + width: 293px; +} + +table.wms { + font-size: 0.8em; + margin: 0 0 0 0; +} + +table, th, td { + margin: 0; + padding: 0; + font-size: 0.8em; +} + +img { + border: 0px; +} + +/* styles used in footer.jsp */ +.footerTable { + width: 100%; + background-color: white; +} + +.footerLine { + color: #003A66; + font-family: Arial,Helvetica,sans-serif; + font-size: 0.95em; + line-height: 1.1em; + padding-left: 1px; +} + +.footerTableLinks { + width: 100%; + background-color: #003a66; +} + +.footerLineLinks { + color: #FFFFFF; + font-family: Arial,Helvetica,sans-serif; + font-size: 1.5em; + text-decoration:none; +} + +.headerTableLinks { + width: 100%; + background-color: #003a66; +} + +.headerLineLinks { + color: #FFFFFF; + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; + text-decoration:none; +} + +/* styles used content */ +#contentElement { + height: 80%; + position: absolute; + top: 85px; + width: 100%; + margin: 0px 0px 10px 0px; + overflow: auto; +} + +.bgblue2 { + background-color: #F7F7F9; +} + +#footerElement { + position: absolute; + bottom: 0px; + margin-top: 10px; + width: 100%; + height: 20px; +} + +.down { + padding-top: 15px; + width: 315px; +} + +.historyback { + padding-left: 10px; + vertical-align: top; + text-align: right; +} + +#parameterPanel { + position: absolute; + float: left; + left: 0px; + top: 5%; + width: 400px; + height: 95%; +} + +td.parameter { + font-size: 0.6em; +} + +.parameter { + color: #003A66; + font-size: 0.8em; + font-weight: bold; + padding-left: 5px; + text-align: left; + vertical-align: top; + width: 110px; +} + +.matrixHeader { + padding-left: 5px; + text-align: center; +} + +.matrixSelectableHeader { + padding-left: 5px; + text-align: left; +} + +.matrixContent { + text-align: center; +} + +.wmsvalue { +} + +.value { + font-size: 1.2em; +} + +.submitbutton{ + cursor:pointer; + border:outset 1px #ccc; + background:#ffffff; + color:#666; + font-weight:bold; + padding: 1px 2px; + +} + +.error { + color: #CD3426; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.errormsg { + color: red; + font-weight: bold; +} + +.chartException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.inputException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +/* ====================== Header ============================= */ +#head { + height: 25px; + margin: 0; + padding: 0; + background-color: #103D64; +} + +#headline { + color: #4C7594; + font-family: "Arial Black",Arial,Helvetica,sans-serif; + font-weight: bold; + line-height: 1.1em; + padding-left: 5px; + width: 533px; +} + +.headline { + border-top: 2px solid #CCe0f4; + border-bottom: 2px solid #CCe0f4; + color: #4C7594; + /*font-weight: bold;*/ + font-size: 1.2em; + padding: 10px; +} + +#logo { + float:right; + background-image: url( ../images/bsh_logo.gif ); + background-repeat: no-repeat; + + top:0px; + height: 170px; + width: 75px; + +} +#head a { + clear:left; +} + +.reload { + margin-top: 10px; +} + +#project { + padding: 0px; + text-align: left; + font-size: 1.2em; + background-color: #e9e8f0; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 5%; +} + +#projectload { + float: left; + padding-left: 5px; + visibility: hidden; +} + +.devide { + width: 100%; + height: 2px; +} + +.projectException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +#load_error { + position:absolute; + top:175px; + left:375px; + width: 400px; + text-align: left; + +} + +#project_load { + position:absolute; + top: 0px; + left: 250px; + width: 277px; + border: 1px solid lightgray; + visibility: hidden; + padding: 5px; +} + + +#head h1, #head h2 { + display: block; + color: white; + font-size: large; + padding-left: 300px; + margin: 0; + + +} + +div#headerElement { + height: 85px; + position: absolute; + width: 100%; +} + +div#header { + background-color: #143B62; + margin: 0; + padding: 0; + height: 50px; +} + +div#header img { + padding: 0; + margin: 0; + border-width: 0; +} + +div#page { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.showContent { + display: block; +} + +.hideContent { + display: none; +} + +div#selection { + float: left; + width: 300px; + margin-top: 30px; +} + +div#diagram { + float: left; + position: absolute; + top: 10%; + left: 330px; +} + +div.outerMap { + position: absolute; + top: 12%; + left: 350px; + width: 555px; + height: 436px; + margin: 0 0 0 0; + padding: 0 0 0 0; +} + +div.wms { + position: absolute; + top: 10%; + left: 0px; + height: 30px; + border: 1px solid red; +} + +div#map { + position: absolute; + top: 65px; + left: 0px; + width: 555px; + height: 381px; + border: 1px solid #CCD5DE; +} + +div.histogram { + float: left; + position: absolute; + top: 10%; + left: 330px; +} + +div#export { + width: 325px; +} + +/* this is a wrapper for diagramoptions and statistics*/ +div#diagrammAddOns { + position: absolute; + top: 600px; + left: 300px; +} + +div#diagramoptions { + position: relative; + width: 325px; +} + +div#diagramOptionsContent { + width : 325px; +} + +div.statistics { + float: left; + position: absolute; + top: 10%; + left: 330px; + width : 325px; +} + +div#statisticValues { + width: 100%; +} + +table#statistik_tab_0{ + position:relative; + top:0px; + left:0px; +} +table#statistik_tab_1{ + position:absolute; + top:30px; + left:230px; +} +table#statistik_tab_2{ + position:relative; + top:-210px; + left:410px; +} +table#statistik_tab_3{ + position:relative; + top:-195px; + left:0px; +} +table#statistik_tab_4{ + position:absolute; + top:260px; + left:230px; +} +table#statistik_tab_5{ + position:absolute; + top:260px; + left:410px; +} +table#statistik_tab_6{ + position:relative; + top:-180px; + left:0px; +} +table#statistik_tab_7{ + position:absolute; + top:485px; + left:230px; +} +table#statistik_tab_8{ + position:absolute; + top:485px; + left:410px; +} + +div#basefilter { + margin-top: 50px; + width: 325px; +} + +div#timeseriesfilter { + margin-top: 1px; + padding: 0px; + width: 325px; +} + +#timeRangeForm label { + float: left; + margin-right: 5px; + text-align: left; + width: 20px; +} + +/* ---------- OVERLAY ------------------------- */ +#overlay { + visibility: hidden; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + text-align: center; + z-index: 100; + background-color: white; + -moz-opacity: 0.5; + opacity: 0.5; +} + +#overlayContent { + visibility: hidden; + position: relative; + z-index: 101; + width: 300px; + margin: 150px auto; + background-color: #fff; + border: 1px solid #000; + padding: 75px; + text-align: right; + background-image: url( ../images/bsh_logo.gif ); + background-repeat: no-repeat; + +} + +/* ----------------------------------- */ diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/main/webapp/styles/gnv.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/main/webapp/styles/gnv.css Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,289 @@ +body { + background-color: #FFFFFF; + font-family: verdana, arial, Helvetica, sans-serif; + font-size: 0.7em; + height: 100%; + margin: 0; + padding: 0; +} + +fieldset { + margin: 5px 0 0 10px; + padding-left: 10px; + padding-right: 10px; + padding-bottom: 5px; + padding-top: 5px; + border: 1px solid #003A66; + background-color: #F2F1F5; + background-repeat: repeat-x; + background-position: top left; + display: block; +} + +legend { + border: 1px solid #003A66; + padding: 4px 5px; + margin: 0 0 0 0; + background-color: white; + font-weight: bolder; + color: #003A66; + clear: both; +} + +input { + font-family: verdana, arial, Helvetica, sans-serif; + font-size: 0.9em; +} + +select, textarea { + font-size: 0.9em; + width: 250px; +} + +img { + border: 0px; +} + +a { + color: #FF6600; + font-size: 1.2em; + text-decoration: underline; +} + +/* Some classes for the header */ +#headerElement { + float: left; + top: 0px; + width: 100%; +} + +#header { + background-color: #143B62; + margin: 0; + padding: 0; + height: 50px; +} + +#headline { + color: #4C7594; + font-family: "Arial Black",Arial,Helvetica,sans-serif; + font-weight: bold; + line-height: 1.1em; + padding-left: 5px; + width: 533px; +} + +.headline { + border-top: 2px solid #CCe0f4; + border-bottom: 2px solid #CCe0f4; + color: #4C7594; + padding: 10px; +} + +.headerTableLinks { + width: 100%; + background-color: #003a66; +} + +.headerLineLinks { + color: #FFFFFF; + font-family: Arial,Helvetica,sans-serif; + font-size: 0.9em; + text-decoration:none; +} + +/* Some classes for the project load/save bar */ +#project { + background-color: #e9e8f0; + height: 5%; + left: 0px; + padding: 0px; + text-align: left; + top: 0px; + width: 100%; +} + +#projectload { + visibility: hidden; +} + +#browseDiv { + float: left; +} + +#loadDiv { + float: left; + margin-left: 5px; +} + +/* Some classes for the content */ +#contentElement { + float: left; + height: 90%; + width: 100%; + margin: 0px 0px 10px 0px; +} + +#contentRow { + vertical-align: top; +} + +#parameterColumn { + width: 400px; +} + +#parameterPanel { + float: left; + width: 350px; +} + +.static { + background-color: #F2F1F5; + width: 300px; +} + +.parameter { + color: #003A66; + font-weight: bold; + padding-left: 5px; + text-align: left; + vertical-align: top; + width: 110px; +} + +.historyback { + padding-left: 10px; + vertical-align: top; + text-align: right; +} + +.statistics { + width: 350px; +} + +div.outerMap { + float: left; + width: 555px; + height: 436px; +} + +div.wms { + top: 10%; + left: 0px; + height: 30px; + border: 1px solid red; +} + +div#map { + top: 65px; + left: 0px; + width: 555px; + height: 381px; + border: 1px solid #CCD5DE; +} + + +/* Some classes for the footer */ +#footerElement { + clear: left; + bottom: 20px; + width: 100%; + height: 20px; +} + +.footerTable { + width: 100%; + background-color: white; +} + +.footerLine { + color: #003A66; + font-family: Arial,Helvetica,sans-serif; + line-height: 1.1em; + padding-left: 1px; +} + +.footerTableLinks { + width: 100%; + background-color: #003a66; +} + +.footerLineLinks { + color: #FFFFFF; + font-family: Arial,Helvetica,sans-serif; + font-size: 0.9em; + text-decoration:none; +} + + +/* ---------- OVERLAY ------------------------- */ +#overlay { + visibility: hidden; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + text-align: center; + z-index: 100; + background-color: white; + -moz-opacity: 0.5; + opacity: 0.5; +} + +#overlayContent { + visibility: hidden; + position: relative; + z-index: 101; + width: 300px; + margin: 150px auto; + background-color: #fff; + border: 1px solid #000; + padding: 75px; + text-align: right; + background-image: url( ../images/bsh_logo.gif ); + background-repeat: no-repeat; +} + + +/* warnings and errors */ +.projectException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.chartException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.inputException { + color: red; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.error { + color: #CD3426; + font-size: 10px; + font-weight: bold; + margin-bottom: 2px; + border: 2px solid red; + padding: 2px; +} + +.errormsg { + color: red; + font-weight: bold; +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/java/de/intevation/gnv/action/mapviewer/parser/ExternalCallParserTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,90 @@ +package de.intevation.gnv.action.mapviewer.parser; + +import de.intevation.gnv.artifactdatabase.objects.map.Layer; +import de.intevation.gnv.artifactdatabase.objects.map.MapService; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import java.util.Collection; +import java.util.Iterator; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +public class ExternalCallParserTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(ExternalCallParserTestCase.class); + } + + public ExternalCallParserTestCase() { + super(); + } + + public ExternalCallParserTestCase(String name) { + super(name); + } + + public void testParseExternalCall() { + log.debug("Execute testParseExternalCall"); + try { + InputStream inputStream = new FileInputStream( + new File("src/test/ressources/externalinterfacecall.xml")); + ExternalCallParser ecp = new XMLExternalCallParser(inputStream); + ecp.parse(); + String geometry = ecp.getGeometry(); + assertNotNull(geometry); + log.debug("Parsed Geometry: "+geometry); + String srs = ecp.getSRS(); + assertNotNull(srs); + log.debug("Parsed SRS: "+srs); + Collection mapServices = ecp.getMapServices(); + assertNotNull(mapServices); + log.debug(mapServices.size()+"Mapservices parsed"); + assertEquals(2, mapServices.size()); + Iterator it = mapServices.iterator(); + MapService mapService1 = it.next(); + MapService mapService2 = it.next(); + + log.debug("MapService 1"); + log.debug("ID: "+mapService1.getID()); + log.debug("URL: "+mapService1.getURL()); + log.debug("TYPE: "+mapService1.getType()); + Collection layer1 = mapService1.getLayer(); + log.debug("Layer parsed: "+layer1.size()); + assertEquals(5, layer1.size()); + Iterator layerIt1 = layer1.iterator(); + while(layerIt1.hasNext()){ + log.debug(layerIt1.next().toString()); + } + + log.debug("MapService 2"); + log.debug("ID: "+mapService2.getID()); + log.debug("URL: "+mapService2.getURL()); + log.debug("TYPE: "+mapService2.getType()); + Collection layer2 = mapService2.getLayer(); + log.debug("Layer parsed: "+layer2.size()); + assertEquals(2, layer2.size()); + Iterator layerIt2 = layer2.iterator(); + while(layerIt2.hasNext()){ + log.debug(layerIt2.next().toString()); + } + + } catch (Exception e) { + log.error(e,e); + fail(); + } + + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClientTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,99 @@ +package de.intevation.gnv.artifactdatabase.client; + +import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription; +import de.intevation.gnv.artifactdatabase.objects.ArtifactObject; +import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter; +import de.intevation.gnv.artifactdatabase.objects.InputParameter; + +import de.intevation.gnv.util.XSLTransformer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Locale; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +/** + * @author Tim Englich + * + */ +public class ArtifactDatabaseClientTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(DefaultArtifactDatabaseClient.class); + } + + /** + * Constructor + * + * @param namemessage + */ + public ArtifactDatabaseClientTestCase(String name) { + super(name); + } + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testArtifactDatabaseClient() { + + try { + ArtifactDatabaseClient artifactDatabaseClient = ArtifactDatabaseClientFactory + .getInstance().getArtifactDatabaseClient(Locale.GERMAN); + Collection factories = artifactDatabaseClient + .getArtifactFactories(); + if (factories != null && !factories.isEmpty()) { + Iterator it = factories.iterator(); + while (it.hasNext()) { + ArtifactObject aof = it.next(); + ArtifactObject artifact = artifactDatabaseClient + .createNewArtifact(aof); + ArtifactDescription ad = artifactDatabaseClient + .getCurrentStepDescription(aof, artifact,true); + log.debug("Artifact aktualisert."); + XSLTransformer transformer = new XSLTransformer(); + String transformedUI = transformer + .transform( + ad.getCurrentUI(), + "UTF-8", + ("src/main/webapp/WEB-INF/config/templates/describe-ui.xsl")); + log.debug(transformedUI); + + Collection inputParameter = new ArrayList( + 1); + inputParameter.add(new DefaultInputParameter("product", + new String[] { "timeSeries" })); + ad = artifactDatabaseClient.doNextStep(aof, artifact, + "timeSeries", inputParameter); + + transformedUI = transformer + .transform( + ad.getCurrentUI(), + "UTF-8", + ("src/main/webapp/WEB-INF/config/templates/describe-ui.xsl")); + log.debug(transformedUI); + } + } + + } catch (Exception e) { + log.error(e, e); + fail(); + } + } + +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/java/de/intevation/gnv/util/XSLTransformerTestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/java/de/intevation/gnv/util/XSLTransformerTestCase.java Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,55 @@ +package de.intevation.gnv.util; + +import de.intevation.gnv.artifactdatabase.client.DefaultArtifactDatabaseClient; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +import junit.framework.TestCase; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +/** + * @author Tim Englich + * + */ +public class XSLTransformerTestCase extends TestCase { + + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = null; + + static { + BasicConfigurator.configure(); + log = Logger.getLogger(DefaultArtifactDatabaseClient.class); + } + + public XSLTransformerTestCase() { + super(); + } + + public XSLTransformerTestCase(String name) { + super(name); + } + + public void testDescribeUI() { + + try { + // System.setProperty("javax.xml.transform.TransformerFactory","com.icl.saxon.TransformerFactoryImpl"); + Document document = new XMLUtils() + .readDocument(new FileInputStream(new File( + "src/test/ressources/describe-ui-test.xml"))); + XSLTransformer transformer = new XSLTransformer(); + String value = transformer.transform(document, "UTF-8", + "src/main/webapp/WEB-INF/config/templates/describe-ui.xsl"); + log.debug(value); + } catch (FileNotFoundException e) { + log.error(e, e); + } + } +} diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/ressources/describe-ui-test.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/ressources/describe-ui-test.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,10 @@ + + + product + + + timeSeries + timeSeries + + + diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/ressources/externalinterfacecall.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/ressources/externalinterfacecall.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + EPSG:4324 + POINT(8.6 56.0) + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/ressources/externalinterfacecall_curl.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/ressources/externalinterfacecall_curl.xml Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EPSG:4324 + POINT(8.6 56.0) + + \ No newline at end of file diff -r 975bb59bb136 -r 11d8cc2deb92 gnv/src/test/ressources/samplecall.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv/src/test/ressources/samplecall.txt Fri Sep 28 12:13:58 2012 +0200 @@ -0,0 +1,1 @@ +curl -v -X POST -H "Content-type: text/xml" http://localhost:8080/gnv/extcall.do -d @externalinterfacecall_curl.xml \ No newline at end of file