[Schmitzm-commits] r363 - in branches/1.0-gt2-2.6/src: gtmig/org/geotools gtmig/org/geotools/gce gtmig/org/geotools/gce/arcgrid schmitzm/geotools schmitzm/geotools/feature schmitzm/geotools/gui schmitzm/geotools/io
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Sep 2 22:29:01 CEST 2009
Author: mojays
Date: 2009-09-02 22:28:57 +0200 (Wed, 02 Sep 2009)
New Revision: 363
Added:
branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/
branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/arcgrid/
branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/arcgrid/ArcGridRaster.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/CQLFilterParser.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FilterParser.java
Modified:
branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeFilter.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeParser.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureFilterPanel.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java
Log:
ArcGridRaster from gt2-2.3.0-M0 integrated in SCHMITZM
Geo-Import via ArcGridRaster and ArcGridReader
new FilterParser and CQLFilterParser
FeatureOperationTreeParser implements FilterParser
FeatureOperationTreeFilter, FeatureFilterPanel converted to OpenGIS-Filter
FeatureFilterPanel, FeatureCollectionFilterPanel parameterized with FilterParser
Added: branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/arcgrid/ArcGridRaster.java
===================================================================
--- branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/arcgrid/ArcGridRaster.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/gtmig/org/geotools/gce/arcgrid/ArcGridRaster.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -0,0 +1,675 @@
+/*
+ * Geotools2 - OpenSource mapping toolkit
+ * http://geotools.org
+ * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+package gtmig.org.geotools.gce.arcgrid;
+
+import org.geotools.resources.NIOUtilities;
+
+import it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageMetadata;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import javax.media.jai.RasterFactory;
+
+/**
+ * <b>Martin Schmitz (2009-09-02):<br>
+ * This class is taken 1:1 from {@code gt2-2.3.0-M0} because of the following reasons:</b>
+ * <ul>
+ * <li>class not included in later GT versions</li>
+ * <li>using {@code ArcGridReader} from "standard" GT makes problems with
+ * raster colorization (no default style, so "everything green" without SLD;
+ * no data value specified in meta data not displayed transparent).</li>
+ * <li>XULU needs to read only the raster meta data (without reading the whole
+ * raster). Don't know how to realize this with {@link ArcGridFormat}.<br>
+ * Maybe: {@code ArcGridReader.getMetaDataValue(..)}
+ * </li>
+ * <li>...</li>
+ * </ul>
+ * Nevertheless we will try to avoid this class... but later.
+ * @deprecated
+ * <hr>
+ * Class user for parsing an ArcGrid header (.arc, .asc) file.
+ *
+ * @author <a href="mailto:ckl at dacelo.nl">Christiaan ten Klooster</a>
+ * @author <a href="mailto:aaime at users.sf.net">Andrea Aime</a>
+ * @author Simone Giannecchini (simboss)
+ * @source $URL: http://svn.geotools.org/geotools/tags/2.3.0-M0/plugin/arcgrid/src/org/geotools/gce/arcgrid/ArcGridRaster.java $
+ */
+public class ArcGridRaster {
+ /** Column number tag in the header file */
+ public static final String NCOLS = "NCOLS";
+
+ /** Row number tag in the header file */
+ public static final String NROWS = "NROWS";
+
+ /** x corner coordinate tag in the header file */
+ public static final String XLLCORNER = "XLLCORNER";
+
+ /** y corner coordinate tag in the header file */
+ public static final String YLLCORNER = "YLLCORNER";
+
+ /** cell size tag in the header file */
+ public static final String CELLSIZE = "CELLSIZE";
+
+ /** no data tag in the header file */
+ public static final String NODATA_VALUE = "NODATA_VALUE";
+
+ /** header or data file url */
+ private URL srcURL;
+
+ /** max value found in the file */
+ protected double maxValue = Float.MIN_VALUE;
+
+ /** min value found in the file */
+ protected double minValue = Float.MAX_VALUE;
+
+ protected double xllCorner = Double.NaN;
+
+ protected double yllCorner = Double.NaN;
+
+ protected double cellSize = Double.NaN;
+
+ protected double noData = -9999;
+
+ protected int nCols = -1;
+
+ protected int nRows = -1;
+
+ private Reader reader = null;
+
+ private PrintWriter writer = null;
+
+ private boolean compress;
+
+ /**
+ * Creates a new instance of ArcGridRaster.
+ *
+ * @param srcURL
+ * URL of a ArcGridRaster.
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ public ArcGridRaster(URL srcURL) {
+ this.srcURL = srcURL;
+
+ if (srcURL.getFile().endsWith(".gz")) {
+ compress = true;
+ }
+ }
+
+ /**
+ * Creates a new instance of ArcGridRaster. Used Exclusively by
+ * ArcGridReader.
+ *
+ * @param reader
+ * reader to be used for reading the Raster.
+ * @param compress
+ * DOCUMENT ME!
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ public ArcGridRaster(Reader reader, boolean compress) {
+ this.reader = reader;
+ this.compress = compress;
+ }
+
+ /**
+ * Creates a new instance of ArcGridRaster. Used Exclusively by
+ * ArcGridWriter.
+ *
+ * @param writer
+ * writer to be used for writing the Raster.
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ public ArcGridRaster(PrintWriter writer) {
+ this.writer = writer;
+ }
+
+ /**
+ * Max value.
+ *
+ * @return the max value contained in the data file
+ */
+ public double getMaxValue() {
+ return maxValue;
+ }
+
+ /**
+ * Min value.
+ *
+ * @return the min value contained in the data file
+ */
+ public final double getMinValue() {
+ return minValue;
+ }
+
+ /**
+ * Returns the number of rows contained in the file.
+ *
+ * @return number of rows
+ */
+ public final int getNRows() {
+ return nRows;
+ }
+
+ /**
+ * Returns the number of columns contained in the file.
+ *
+ * @return number of columns
+ */
+ public final int getNCols() {
+ return nCols;
+ }
+
+ /**
+ * Returns the x cordinate of the lower left corner.
+ *
+ * @return x cordinate of the lower left corner.
+ */
+ public final double getXlCorner() {
+ return xllCorner;
+ }
+
+ /**
+ * Returns the y cordinate of the lower left corner.
+ *
+ * @return y cordinate of the lower left corner.
+ */
+ public final double getYlCorner() {
+ return yllCorner;
+ }
+
+ /**
+ * Returns the cell size.
+ *
+ * @return cell size
+ */
+ public final double getCellSize() {
+ return cellSize;
+ }
+
+ /**
+ * Returns the no data (null) value.
+ *
+ * @return no data (null) value.
+ */
+ public final double getNoData() {
+ return noData;
+ }
+
+ /**
+ * Parses the reader for the known properties.
+ *
+ * @throws IOException
+ * for reading errors
+ */
+ public final void parseHeader() throws IOException {
+ parseHeader(new StreamTokenizer(openReader()));
+ }
+
+ /**
+ * Parse the header of an ascii grid file.
+ *
+ * @param st
+ * StringTokenizer to be used to parse this header.
+ * @throws IOException
+ */
+ protected void parseHeader(StreamTokenizer st) throws IOException {
+ // make sure tokenizer is set up right
+ st.resetSyntax();
+ st.eolIsSignificant(true);
+ st.whitespaceChars(0, ' ');
+ st.wordChars('a', 'z');
+ st.wordChars('A', 'Z');
+ st.wordChars('_', '_');
+ st.parseNumbers();
+ String key = null;
+ // read lines while the next token is not a number
+ while (st.nextToken() != StreamTokenizer.TT_NUMBER) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ key = st.sval;
+
+ if (st.nextToken() != StreamTokenizer.TT_NUMBER) {
+ throw new IOException("Expected number after " + key);
+ }
+
+ double val = st.nval;
+
+ if (NCOLS.equalsIgnoreCase(key)) {
+ nCols = (int) val;
+ } else if (NROWS.equalsIgnoreCase(key)) {
+ nRows = (int) val;
+ } else if (XLLCORNER.equalsIgnoreCase(key)) {
+ xllCorner = readHeaderDouble(st);
+ } else if (YLLCORNER.equalsIgnoreCase(key)) {
+ yllCorner = readHeaderDouble(st);
+ } else if (CELLSIZE.equalsIgnoreCase(key)) {
+ cellSize = readHeaderDouble(st);
+ } else if (NODATA_VALUE.equalsIgnoreCase(key)) {
+ noData = readHeaderDouble(st);
+ } else {
+ // ignore extra fields for now
+ // are there ever any?
+ }
+
+ if (st.nextToken() != StreamTokenizer.TT_EOL) {
+ throw new IOException("Expected new line, not " + st.sval);
+ }
+ } else {
+ throw new IOException("Expected word token");
+ }
+ }
+
+ st.pushBack();
+ }
+
+ protected double readHeaderDouble(StreamTokenizer st) throws IOException {
+ double val = st.nval;
+
+ if ((st.nextToken() == StreamTokenizer.TT_WORD)
+ && st.sval.startsWith("E")) {
+ val = val * Math.pow(10, Integer.parseInt(st.sval.substring(1)));
+ } else {
+ st.pushBack();
+ }
+
+ return val;
+ }
+
+ /**
+ * Obtain the best reader for the situation
+ *
+ * @return A reader to read this file.
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ protected Reader openReader() throws IOException {
+ if (reader != null) {
+ return reader;
+ }
+
+ // gzipped source, may be remote URL
+ if (compress) {
+ InputStream in = new java.util.zip.GZIPInputStream(srcURL
+ .openStream());
+
+ return new InputStreamReader(new java.io.BufferedInputStream(in));
+ }
+
+ // file based, non zipped - lets use memory-mapped reader
+ if (srcURL.getProtocol().equals("file")) {
+ return new MemoryMappedReader(new File(java.net.URLDecoder.decode(
+ srcURL.getPath(), "UTF-8")));
+ }
+
+ // default URL
+ return new InputStreamReader(srcURL.openStream());
+ }
+
+ /**
+ * Open the best writer for the situation.
+ *
+ * @param compress
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ protected PrintWriter openWriter(boolean compress) throws IOException {
+ if (writer != null) {
+ return writer;
+ }
+
+ java.io.OutputStream out;
+
+ if (srcURL.getProtocol().equals("file")) {
+ out = new java.io.BufferedOutputStream(
+ new java.io.FileOutputStream(new File(java.net.URLDecoder
+ .decode(srcURL.getPath(), "UTF-8"))));
+ } else {
+ out = srcURL.openConnection().getOutputStream();
+ }
+
+ if (compress) {
+ out = new java.util.zip.GZIPOutputStream(out);
+ }
+
+ return new PrintWriter(out);
+ }
+
+ /**
+ * Returns the WritableRaster of the raster. This method first parses the
+ * header then reads all the data.
+ *
+ * @return RenderedImage
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ public WritableRaster readRaster() throws IOException {
+ // open reader and make tokenizer
+ Reader reader = openReader();
+ StreamTokenizer st = new StreamTokenizer(reader);
+
+ // parse header
+ parseHeader(st);
+
+ // reconfigure tokenizer
+ st.resetSyntax();
+ st.parseNumbers();
+ st.whitespaceChars(' ', ' ');
+ st.whitespaceChars(' ', '\t');
+ st.whitespaceChars('\n', '\n');
+ st.whitespaceChars('\r', '\r'); // linefeed (on windows only?)
+ st.whitespaceChars('\f', '\f'); // form feed (on printers????)
+ st.eolIsSignificant(false);
+ st.ordinaryChars('E', 'E');
+
+ // allocate raster, for now this is done with floating point data,
+ // though eventually it should be configurable
+ WritableRaster raster = RasterFactory.createBandedRaster(
+ java.awt.image.DataBuffer.TYPE_FLOAT, getNCols(), getNRows(),
+ 1, null);
+
+ // Read values from grid and put into raster.
+ // Values must be numbers, which may be simple <num>, or expressed
+ // in scientific notation <num>E<exp>.
+ // The following loop can read both, even if mixed.
+ // The loop expects a token to be read already
+ st.nextToken();
+
+ for (int y = 0; y < getNRows(); y++) {
+ for (int x = 0; x < getNCols(); x++) {
+ // this call always reads the next token
+ double d = readCell(st, x, y);
+
+ // mask no data values with NaN
+ if (d == getNoData()) {
+ d = Double.NaN;
+ } else {
+ minValue = Math.min(minValue, d);
+ maxValue = Math.max(maxValue, d);
+ }
+
+ // set the value at x,y in band 0 to the parsed value
+ raster.setSample(x, y, 0, (float) d);
+ }
+ }
+
+ reader.close();
+
+ return raster;
+ }
+
+ /**
+ * Parse a number.
+ *
+ * @param st
+ * DOCUMENT ME!
+ * @param x
+ * DOCUMENT ME!
+ * @param y
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ private double readCell(StreamTokenizer st, int x, int y)
+ throws IOException {
+ double d = 0;
+
+ // read a token, expected: a number
+ switch (st.ttype) {
+ case StreamTokenizer.TT_NUMBER:
+ d = (float) st.nval;
+
+ break;
+
+ case StreamTokenizer.TT_EOF:
+ throw new IOException("Unexpected EOF at " + x + "," + y);
+
+ default:
+ throw new IOException("Unknown token " + st.ttype);
+ }
+
+ // read another. May be an exponent of this number.
+ // If its not an exponent, its the next number. Fall through
+ // and token is prefetched for next loop...
+ switch (st.nextToken()) {
+ case 'e':
+ case 'E':
+
+ // now read the exponent
+ st.nextToken();
+
+ if (st.ttype != StreamTokenizer.TT_NUMBER) {
+ throw new IOException("Expected exponent at " + x + "," + y);
+ }
+
+ // calculate
+ d = d * Math.pow(10.0, st.nval);
+
+ // prefetch for next loop
+ st.nextToken();
+
+ break;
+
+ case StreamTokenizer.TT_NUMBER:
+ case StreamTokenizer.TT_EOF:
+ break;
+
+ default:
+ throw new IOException("Expected Number or EOF");
+ }
+
+ return d;
+ }
+
+ /**
+ * Print n spaces to the PrintWriter
+ *
+ * @param p
+ * DOCUMENT ME!
+ * @param n
+ * DOCUMENT ME!
+ */
+ protected void spaces(PrintWriter p, int n) {
+ for (int i = 0; i < n; i++) {
+ p.print(' ');
+ }
+ }
+
+ /**
+ * Write out the given raster..
+ *
+ * @param raster
+ * DOCUMENT ME!
+ * @param xl
+ * DOCUMENT ME!
+ * @param yl
+ * DOCUMENT ME!
+ * @param cellsize
+ * DOCUMENT ME!
+ * @param compress
+ * DOCUMENT ME!
+ *
+ * @throws IOException
+ * DOCUMENT ME!
+ */
+ public void writeRaster(Raster raster, double xl, double yl,
+ double cellsize, boolean compress) throws IOException {
+ // open writer
+ PrintWriter out = openWriter(compress);
+
+ // output header and assign header fields
+ out.print(NCOLS);
+ spaces(out, 9);
+ out.println(nCols = raster.getWidth());
+ out.print(NROWS);
+ spaces(out, 9);
+ out.println(nRows = raster.getHeight());
+ out.print(XLLCORNER);
+ spaces(out, 5);
+ out.println(xllCorner = xl);
+ out.print(YLLCORNER);
+ spaces(out, 5);
+ out.println(yllCorner = yl);
+ out.print(CELLSIZE);
+ spaces(out, 6);
+ out.println(cellSize = cellsize);
+ out.print(NODATA_VALUE);
+ spaces(out, 2);
+ out.println(noData);
+
+ // reset min and max
+ minValue = Double.MIN_VALUE;
+ maxValue = Double.MAX_VALUE;
+
+ // a buffer to flush each line to
+ // this technique makes things a bit quicker because buffer.append()
+ // internally calls new FloatingDecimal(double).appendTo(StringBuffer)
+ // instead of creating a new String each time (as would be done with
+ // PrintWriter, ie. print(new FloatingDecimal(double).toString())
+ StringBuffer buffer = new StringBuffer(raster.getWidth() * 4);
+
+ for (int i = 0, ii = raster.getHeight(); i < ii; i++) {
+ // clear buffer
+ buffer.delete(0, buffer.length());
+
+ // write row to buffer
+ for (int j = 0, jj = raster.getWidth(); j < jj; j++) {
+ double v = raster.getSampleDouble(j, i, 0);
+
+ // no data masking
+ if (Double.isNaN(v)) {
+ v = noData;
+ }
+
+ // append value and possible spacer
+ buffer.append(v);
+
+ if ((j + 1) < jj) {
+ buffer.append(' ');
+ }
+ }
+
+ // flush out row
+ out.write(buffer.toString());
+ out.println();
+ }
+
+ out.flush();
+ out.close();
+ }
+
+ public String toString() {
+ java.lang.reflect.Field[] f = getClass().getDeclaredFields();
+ String s = "";
+
+ for (int i = 0, ii = f.length; i < ii; i++) {
+ if (!java.lang.reflect.Modifier.isStatic(f[i].getModifiers())) {
+ try {
+ s += (f[i].getName() + " : " + f[i].get(this));
+
+ if ((i + 1) < f.length) {
+ s += " ";
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return s;
+ }
+
+ /**
+ * This is a slight optimization over using a BufferedReader.
+ * StreamTokenizer makes single character read calls.
+ */
+ static class MemoryMappedReader extends java.io.Reader {
+ ByteBuffer map;
+
+ CharBuffer chars;
+
+ CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();
+
+ FileChannel channel;
+
+ public MemoryMappedReader(File f) throws IOException {
+ channel = new FileInputStream(f).getChannel();
+ map = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
+ chars = CharBuffer.allocate(16 * 1028);
+ fill();
+ }
+
+ public void close() throws IOException {
+ if (channel != null) {
+ channel.close();
+ }
+
+ NIOUtilities.clean(map);
+ channel = null;
+ map = null;
+ }
+
+ void fill() {
+ decoder.decode(map, chars, false);
+ chars.flip();
+ }
+
+ public int read() {
+ if (chars.remaining() == 0) {
+ chars.flip();
+ fill();
+
+ if (chars.remaining() == 0) {
+ return -1;
+ }
+ }
+
+ return chars.get();
+ }
+
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ throw new IOException("Expected single character read");
+ }
+ }
+}
+
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -63,7 +63,7 @@
// * @param filter
// * ein Filter
// *
-// * TODO GT 26 Das wird in Atlas und Schmitzm nichtbenötig. Wir
+// * TODO GT 26 Das wird in Atlas und Schmitzm nicht benötigt. Wir
// * können die Methode als theoretisch einfach mal entfernen..
// * Ansonsten habe ich auch eine Mail auf die gt-user geschickt.
// */
Added: branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/CQLFilterParser.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/CQLFilterParser.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/CQLFilterParser.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+
+package schmitzm.geotools.feature;
+
+import org.geotools.filter.text.cql2.CQL;
+import org.geotools.filter.text.cql2.CQLException;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+
+/**
+ * This parser creates a CQL-{@link Filter} from a rule string.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class CQLFilterParser implements FilterParser {
+ /** Factory used to create the {@link Filter}. */
+ protected FilterFactory filterFactory = null;
+
+ /**
+ * Creates a new parser.
+ */
+ public CQLFilterParser() {
+ this(null);
+ }
+
+ /**
+ * Creates a new parser.
+ * @param filterFactory factory used to create the {@link Filter} (can be {@code null})
+ */
+ public CQLFilterParser(FilterFactory filterFactory) {
+ this.filterFactory = filterFactory;
+ }
+
+ /**
+ * Creates a CQL-{@link Filter} for the rule string.
+ * @param rule a rule string
+ * @return TRUE filter, if rule is {@code null} or empty
+ */
+ @Override
+ public Filter parseFilter(String rule) {
+ if (rule == null || rule.trim().equals(""))
+ rule = "TRUE";
+ try {
+ return CQL.toFilter(rule);
+ } catch (CQLException err) {
+ throw new RuntimeException(err);
+ }
+ }
+
+}
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeFilter.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeFilter.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeFilter.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -29,7 +29,7 @@
******************************************************************************/
package schmitzm.geotools.feature;
-import org.geotools.filter.AbstractFilterImpl;
+import org.geotools.filter.FilterAbstract;
import org.geotools.filter.FilterFactoryImpl;
import org.opengis.feature.simple.SimpleFeature;
@@ -43,7 +43,7 @@
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
* @version 1.0
*/
-public class FeatureOperationTreeFilter extends AbstractFilterImpl {
+public class FeatureOperationTreeFilter extends FilterAbstract {//AbstractFilterImpl {
/** Formel, die auf dem SimpleFeature ausgewertet wird. */
protected String rule = null;
/** Operator-Baum zur Formel {@link #rule}. */
@@ -69,7 +69,7 @@
this.opTree = parser.parse(rule);
}
- /**
+ /**
* Prueft, ob ein {@link SimpleFeature} dem Filter entspricht. Dies ist der Fall,
* wenn das Formel-Ergebnis fuer das SimpleFeature ungleich 0 ist.
*
@@ -77,6 +77,7 @@
* zu ueberpruefendes SimpleFeature
* @return {@code true}, wenn das SimpleFeature dem Filter entspricht
*/
+ @Override
public boolean evaluate(SimpleFeature feature) {
// Exception sollte hier nicht ausgegeben werden, da bei allgemeinen Fehlern
// die Exception fuer JEDES SimpleFeature ausgegeben wuerde!
@@ -98,6 +99,7 @@
* @exception IllegalArgumentException wenn das uebergebene Objekt kein
* {@link SimpleFeature} ist
*/
+ @Override
public boolean evaluate(Object feature) {
if ( feature != null && !(feature instanceof SimpleFeature) )
throw new IllegalArgumentException("evaluate(Object) can only be applied to SimpleFeature objects: "+feature.getClass().getSimpleName());
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeParser.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeParser.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureOperationTreeParser.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -29,6 +29,10 @@
******************************************************************************/
package schmitzm.geotools.feature;
+import org.geotools.filter.text.cql2.CQL;
+import org.geotools.filter.text.cql2.CQLException;
+import org.opengis.filter.Filter;
+
import schmitzm.lang.tree.BinaryTreeNode;
import schmitzm.lang.tree.OperationTreeParser;
@@ -51,7 +55,7 @@
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
* @version 1.0
*/
-public class FeatureOperationTreeParser extends OperationTreeParser {
+public class FeatureOperationTreeParser extends OperationTreeParser implements FilterParser {
/**
* Erstellt einen SimpleFeature-Operator-Baum aus einem Formel-String.
* @param rule Formel
@@ -84,5 +88,18 @@
pushbackWithWSToken();
return super.parseLiteral();
}
+
+ /**
+ * Creates a {@link FeatureOperationTreeFilter} for the rule string.
+ * @param rule a rule string
+ * @return TRUE filter, if rule is {@code null} or empty
+ */
+ @Override
+ public Filter parseFilter(String rule) {
+ if (rule == null || rule.trim().equals(""))
+ rule = "1";
+ return new FeatureOperationTreeFilter(rule);
+ }
+
}
Added: branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FilterParser.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FilterParser.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FilterParser.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+
+package schmitzm.geotools.feature;
+
+import org.opengis.filter.Filter;
+
+/**
+ * This interface defines a parser which creates a {@link Filter}
+ * from a rule string.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public interface FilterParser {
+ /**
+ * Creates a {@link Filter} by parsing a rule string-
+ * @param rule rule string
+ */
+ public Filter parseFilter(String rule);
+
+}
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureCollectionFilterPanel.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -63,17 +63,19 @@
import schmitzm.geotools.feature.FeatureOperationTree;
import schmitzm.geotools.feature.FeatureOperationTreeFilter;
import schmitzm.geotools.feature.FeatureOperationTreeParser;
+import schmitzm.geotools.feature.FilterParser;
import schmitzm.geotools.styling.StylingUtil;
import schmitzm.swing.ExceptionDialog;
import schmitzm.swing.SwingUtil;
/**
* Diese Klasse stellt ein Panel zur Verfuegung, mit der ein
- * {@link FeatureOperationTreeFilter} in Form einer arithmetischen (und
- * boolschen) Formel erstellt werden kann. Neben den Komponenten zur
- * Definition/Eingabe des Filters enthaelt das Panel einen Vorschau-Bereich, in
- * dem eine {@link FeatureCollection} angezeigt wird, auf der der Filter
- * angewandt wird.
+ * {@link Filter} in Form einer arithmetischen (und boolschen) Formel
+ * erstellt werden kann. Wie der String geparst wird (z.B. CQL), wird durch einen
+ * {@link FilterParser} bestimmt.<br>
+ * Neben den Komponenten zur Definition/Eingabe des Filters enthaelt das Panel
+ * einen Vorschau-Bereich, in dem eine {@link FeatureCollection} angezeigt wird,
+ * auf der der Filter angewandt wird.
*
* @see FeatureOperationTree
* @see FeatureOperationTreeParser
@@ -175,7 +177,9 @@
/**
* Erzeugt ein neues Panel.
- *
+ * @param parser
+ * Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen.
* @param fc
* definiert die zur Verfuegung gestellten SimpleFeature-Attribute
* @param geomPrev
@@ -183,13 +187,15 @@
* oder nicht ({@code false})
* @see FeatureCollection#getSchema()
*/
- public FeatureCollectionFilterPanel(FeatureCollection<SimpleFeatureType,SimpleFeature> fc, boolean geomPrev) {
- this(fc, geomPrev, true);
+ public FeatureCollectionFilterPanel(FilterParser parser, FeatureCollection<SimpleFeatureType,SimpleFeature> fc, boolean geomPrev) {
+ this(parser, fc, geomPrev, true);
}
/**
* Erzeugt ein neues Panel
- *
+ * @param parser
+ * Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen.
* @param fc
* definiert die zur Verfuegung gestellten SimpleFeature-Attribute
* @param initGUI
@@ -197,9 +203,9 @@
* werden soll (wenn {@code false} muss die explizit durch die
* Unterklasse erfolgen!)
*/
- protected FeatureCollectionFilterPanel(FeatureCollection<SimpleFeatureType,SimpleFeature> fc,
+ protected FeatureCollectionFilterPanel(FilterParser parser, FeatureCollection<SimpleFeatureType,SimpleFeature> fc,
boolean geomPrev, boolean initGUI) {
- super(fc.getSchema(), false);
+ super(parser,fc.getSchema(), false);
this.geomPrev = geomPrev;
// Layout-Anordnung fuer GUI
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureFilterPanel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureFilterPanel.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureFilterPanel.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -42,26 +42,21 @@
import javax.swing.ListSelectionModel;
import org.geotools.feature.FeatureCollection;
-import org.geotools.filter.Filter;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
import schmitzm.geotools.feature.AttributeTypeFilter;
-import schmitzm.geotools.feature.FeatureOperationTree;
-import schmitzm.geotools.feature.FeatureOperationTreeFilter;
-import schmitzm.geotools.feature.FeatureOperationTreeParser;
import schmitzm.geotools.feature.FeatureTypeTableModel;
+import schmitzm.geotools.feature.FilterParser;
import schmitzm.swing.OperationTreePanel;
import schmitzm.swing.SwingUtil;
/**
- * Diese Klasse stellt ein Panel zur Vefuegung, mit der ein
- * {@link FeatureOperationTreeFilter} in Form einer arithmetischen (und
- * boolschen) Formel erstellt werden kann.
- *
- * @see FeatureOperationTree
- * @see FeatureOperationTreeParser
- * @see FeatureOperationTreeFilter
+ * Diese Klasse stellt ein Panel zur Verfuegung, mit der ein
+ * {@link Filter} in Form einer arithmetischen (und boolschen) Formel
+ * erstellt werden kann. Wie der String geparst wird (z.B. CQL), wird durch
+ * einen {@link FilterParser} bestimmt.
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
* (University of Bonn/Germany)
* @version 1.0
@@ -92,41 +87,51 @@
/** Tabellen-Modell, das den Inhalt der SimpleFeature-Attribut-Tabelle bestimmt */
protected FeatureTypeTableModel attributeTableModel = null;
private JScrollPane attributeScrollPane = null;
-
+ /** Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen. */
+ protected FilterParser filterParser = null;
+
/**
* Erzeugt ein neues Panel.
- *
+ * @param parser
+ * Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen.
* @param ftype
- * definiert die zur Verfuegung gestellten SimpleFeature-Attribute
+ * definiert die zur Verfuegung gestellten Feature-Attribute
* @see FeatureCollection#getSchema()
*/
- public FeatureFilterPanel(SimpleFeatureType ftype) {
- this(ftype, true);
+ public FeatureFilterPanel(FilterParser parser, SimpleFeatureType ftype) {
+ this(parser,ftype, true);
}
/**
* Erzeugt ein neues Panel.
- *
+ * @param parser
+ * Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen.
* @param fc
- * definiert die zur Verfuegung gestellten SimpleFeature-Attribute
+ * definiert die zur Verfuegung gestellten Feature-Attribute
* @see FeatureCollection#getSchema()
*/
- public FeatureFilterPanel(FeatureCollection<SimpleFeatureType,SimpleFeature> fc) {
- this(fc.getSchema());
+ public FeatureFilterPanel(FilterParser parser, FeatureCollection<SimpleFeatureType,SimpleFeature> fc) {
+ this(parser,fc.getSchema());
}
/**
* Erzeugt ein neues Panel
- *
+ * @param parser
+ * Parser um aus dem im Panel eingegebenen String einen {@link Filter}
+ * zu erstellen.
* @param ftype
- * definiert die zur Verfuegung gestellten SimpleFeature-Attribute
+ * definiert die zur Verfuegung gestellten Feature-Attribute
* @param initGUI
* Flag, ob {@link #initGUI()} am Ende des Konstruktor aufgerufen
* werden soll (wenn {@code false} muss die explizit durch die
* Unterklasse erfolgen!)
*/
- protected FeatureFilterPanel(SimpleFeatureType ftype, boolean initGUI) {
+ protected FeatureFilterPanel(FilterParser parser, SimpleFeatureType ftype, boolean initGUI) {
super(false);
+ setFilterParser(parser);
// Zusaetzliche Operatoren und Konstanten
// avOperators.add(...); avOperatorsDesc.put(..., ...);
@@ -272,14 +277,30 @@
}
/**
- * Liefert einen {@link Filter} zu der im Panel eingetragene Formel.
- *
- * @return TRUE-Regel, falls im Panel keine Formel eingetragen ist.
+ * Setzt den Parser, mit dem aus der im Panel eingegebenen
+ * Formel ein {@link Filter} erstellt wird.
+ * @param parser der Parser
*/
- public Filter createFilter() {
- String rule = getRule();
- if (rule == null || rule.trim().equals(""))
- rule = "1";
- return new FeatureOperationTreeFilter(rule);
+ public void setFilterParser(FilterParser parser) {
+ if ( parser == null )
+ throw new NullPointerException("FilterParser is not allowed to be NULL!");
+ this.filterParser = parser;
}
+
+ /**
+ * Liefert den Parser, mit dem aus der im Panel eingegebenen
+ * Formel ein {@link Filter} erstellt wird.
+ */
+ public FilterParser getFilterParser() {
+ return this.filterParser;
+ }
+
+ /**
+ * Liefert einen {@link Filter} zu der im Panel eingetragene Formel.
+ *
+ * @return TRUE-Regel, falls im Panel keine Formel eingetragen ist.
+ */
+ public Filter createFilter() {
+ return filterParser.parseFilter( getRule() );
+ }
}
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -43,12 +43,15 @@
import javax.swing.JPanel;
import org.geotools.feature.FeatureCollection;
-import org.geotools.filter.Filter;
import org.geotools.map.MapLayer;
import org.geotools.map.event.MapLayerEvent;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import schmitzm.geotools.feature.FeatureOperationTreeFilter;
+import schmitzm.geotools.feature.FeatureOperationTreeParser;
+import schmitzm.geotools.feature.FilterParser;
import schmitzm.geotools.map.event.FeatureSelectedEvent;
import schmitzm.geotools.map.event.MapLayerAdapter;
import schmitzm.swing.CaptionsChangeable;
@@ -61,6 +64,10 @@
* ueber eine Formel gefiltert werden kann. Beim Anwenden des Filters wird
* ein {@link FeatureSelectedEvent} ausgeloest, auf das z.B. mit dem
* Einfuegen eines neuen Layers reagiert werden kann.
+ * Standardmaessig wird ein {@link FeatureOperationTreeParser} verwendet,
+ * um die eingegebene Formel zu parsen (und einen {@link FeatureOperationTreeFilter}
+ * zu erstellen). Ueber {@code getFeatureCollectionFilterPanel().setFilterParser(FilterParser)}
+ * kann dieser jedoch einfach geaendert werden.
* @see FeatureCollectionFilterPanel
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
* @version 1.0
@@ -84,6 +91,10 @@
/** Der ANWENDEN-Button. */
protected JButton applyButton = null;
+ /** Parser, der standardmaessig verwendet wird, um den {@link Filter} zu
+ * erstellen. */
+ public static final FilterParser FILTER_PARSER = new FeatureOperationTreeParser();
+
private String frameTitle = GeotoolsGUIUtil.RESOURCE.getString(DIALOG_TITLE);
private JMapPane mapPane = null;
private MapLayer layer = null;
@@ -136,13 +147,11 @@
}
}
-
-
/**
* Initalisiert die GUI.
*/
protected void initGUI() throws IOException {
- filterPanel = new FeatureCollectionFilterPanel( (FeatureCollection<SimpleFeatureType, SimpleFeature>) layer.getFeatureSource().getFeatures(), true ) {
+ filterPanel = new FeatureCollectionFilterPanel(FILTER_PARSER, (FeatureCollection<SimpleFeatureType, SimpleFeature>) layer.getFeatureSource().getFeatures(), true ) {
@Override
protected void resetComponentsAfterTest(Throwable err) {
super.resetComponentsAfterTest(err);
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java 2009-08-31 18:22:21 UTC (rev 362)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java 2009-09-02 20:28:57 UTC (rev 363)
@@ -29,6 +29,8 @@
******************************************************************************/
package schmitzm.geotools.io;
+import gtmig.org.geotools.gce.arcgrid.ArcGridRaster;
+
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
@@ -73,12 +75,15 @@
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.coverage.grid.GridCoverage;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import schmitzm.data.WritableGridRaster;
import schmitzm.geotools.GTUtil;
import schmitzm.io.IOUtil;
+import schmitzm.lang.LangUtil;
import com.vividsolutions.jts.geom.Geometry;
@@ -91,15 +96,14 @@
* @version 1.0
*/
public class GeoImportUtil {
- private static final Logger LOGGER = Logger.getLogger(GeoImportUtil.class
- .getName());
+ private static final Logger LOGGER = Logger.getLogger(GeoImportUtil.class.getName());
/**
* These postfixes are associated with Arc/Info ASCII Grid files TODO .0
* habe ich auch schon gesehen. Nut leider kann man das nicht in einen enum
* packen.
* */
- static public enum ARCASCII_POSTFIXES {
+ public static enum ARCASCII_POSTFIXES {
arc, dat, ascii, txt, asc, a00
};
@@ -128,16 +132,82 @@
wld, jgw, pgw, tfw
};
+ ///////////////////////////////////////////////////////////////////////////
+ // ASCII IMPORT STYLE
+ ///////////////////////////////////////////////////////////////////////////
+
/**
+ * This type specifies how this class can proceed the import of ASCII rasters.
+ * @see GeoImportUtil#readGridFromArcInfoASCII(Object, CoordinateReferenceSystem)
+ * @see GeoImportUtil#readGridRasterFromGeoTiff(File, CoordinateReferenceSystem)
+ */
+ public static enum ARCASCII_IMPORT_TYPE {
+ /** Use the old {@link ArcGridRaster}. This works fine (colorization and
+ * no data transparency), but {@link ArcGridRaster} is deprecated
+ * and no longer supported since gt2-2.3.0-M0. */
+ USE_ARCGRIDRASTER,
+ /** Use the {@link ArcGridReader} from "standard" GT.<br>
+ * <b>Note:</b>There may be problems with colorization and
+ * no data transparency using this import type! */
+ USE_ARCGRIDREADER
+ }
+
+ /**
+ * Specifies how this class proceeds the import of ASCII rasters. The default is
+ * {@link ARCASCII_IMPORT_TYPE#USE_ARCGRIDREADER} because this works fine!
+ * @see GeoImportUtil#readGridFromArcInfoASCII(Object, CoordinateReferenceSystem)
+ * @see GeoImportUtil#readGridRasterFromGeoTiff(File, CoordinateReferenceSystem)
+ */
+ private static ARCASCII_IMPORT_TYPE ARCASCII_IMPORT_MODE = ARCASCII_IMPORT_TYPE.USE_ARCGRIDRASTER;
+
+ /**
+ * Sets how this class proceeds the import of ASCII rasters.
+ * @param mode the mode how to proceed the import
+ */
+ public static void setAsciiRasterImportMode(ARCASCII_IMPORT_TYPE mode) {
+ ARCASCII_IMPORT_MODE = mode;
+ }
+
+ /**
+ * Returns the default CRS used if no CRS can be found during import.
+ */
+ public static ARCASCII_IMPORT_TYPE getAsciiRasterImportMode() {
+ return ARCASCII_IMPORT_MODE;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // DEFAULT COORDINATE REFERENCE SYSTEM
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
* Standard-CRS, welches verwendet wird, wenn beim Import kein CRS ermittelt
* werden kann (Default: {@link DefaultGeographicCRS#WGS84}).<br>
* <b>Achtung:</b><br>
* Anwendungen koennen diese Variable gefahrlos ueberschreiben, um ein fuer
* die Anwendung adaequates Standard-CRS zu verwenden.
*/
- public static CoordinateReferenceSystem DEFAULT_CRS = DefaultGeographicCRS.WGS84;
+ private static CoordinateReferenceSystem DEFAULT_CRS = DefaultGeographicCRS.WGS84;
/**
+ * Sets the default CRS used if no CRS can be found during import.
+ * @param crs the new default CRS
+ */
+ public static void setDefaultCRS(CoordinateReferenceSystem crs) {
+ DEFAULT_CRS = crs;
+ }
+
+ /**
+ * Returns the default CRS used if no CRS can be found during import.
+ */
+ public static CoordinateReferenceSystem getDefaultCRS() {
+ return DEFAULT_CRS;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // FEATURE IMPORT
+ ///////////////////////////////////////////////////////////////////////////
+ /**
* Diese Methode extrahiert saemtliche Features aus einem ShapeFile-Projekt
* (<code><i>name</i>.shp <i>name</i>.prj <i>name</i>.dbf ...</code>) und
* speichert diese in einer
@@ -156,7 +226,7 @@
*
* @throws IOException
*/
- public static FeatureCollection readFeaturesFromShapeURL(URL url, URL prjUrl)
+ public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeURL(URL url, URL prjUrl)
throws IOException {
ShapefileDataStore store = new ShapefileDataStore(url);
try {
@@ -173,17 +243,15 @@
// store.forceSchemaCRS(DEFAULT_CRS);
}
String[] typeNames = store.getTypeNames();
- FeatureCollection fc = store.getFeatureSource(typeNames[0])
- .getFeatures();
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store.getFeatureSource(typeNames[0]).getFeatures();
// Create a new DefaultFeatureCollection to allow modifying
// operations on the collection ("fc" is a DataFeatureCollection, whose
// add(.) and remove(.) methods do nothing. Furthermore a
- // FIDFeatureReader
- // is used which returns copies of the features, so modifying the
- // attributes
- // does not effect the features in the collection!)
- FeatureCollection fc1 = FeatureCollections.newCollection(fc.getID());
+ // FIDFeatureReader is used which returns copies of the features,
+ // so modifying the attributes does not effect the features
+ // in the collection!)
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections.newCollection(fc.getID());
fc1.addAll(fc);
fc = fc1;
@@ -208,8 +276,7 @@
* hiet auf readFeaturesFromShapeURL(file.getURL) umgeleitet werden
* (SK)
*/
- public static FeatureCollection readFeaturesFromShapeFile(File file)
- throws Exception {
+ public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeFile(File file) throws Exception {
ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());
File prjFile = IOUtil.changeFileExt(file, "prj");
boolean delPrjFile = false;
@@ -223,14 +290,13 @@
+ file.getName());
CRS.parseWKT(prjString);
} catch (FileNotFoundException err) {
- store.forceSchemaCRS(getDEFAULT_CRS());
+ store.forceSchemaCRS(getDefaultCRS());
LOGGER.warn("No projection found for file " + file.getName()
+ ". Default is used.");
delPrjFile = true; // von DataStore erzeugte Datei wieder loeschen
}
String[] typeNames = store.getTypeNames();
- FeatureCollection fc = store.getFeatureSource(typeNames[0])
- .getFeatures();
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store.getFeatureSource(typeNames[0]).getFeatures();
if (delPrjFile)
prjFile.delete();
@@ -241,7 +307,7 @@
// is used which returns copies of the features, so modifying the
// attributes
// does not effect the features in the collection!)
- FeatureCollection fc1 = FeatureCollections.newCollection(fc.getID());
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections.newCollection(fc.getID());
fc1.addAll(fc);
fc = fc1;
@@ -249,29 +315,26 @@
}
/**
- * TODO DOKU
- *
- * @param shpURL
- * @param prjURL
- * @return
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
- * Krüger</a>
- * @throws IOException
+ * Creates a {@link DataStore} from shape file
+ * @param shpURL URL to shape file
+ * @param prjURL URL to projection file
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Krüger</a>
+ * @throws IOException if an error occur
*/
- public static DataStore readDataStoreFromShape(URL shpURL, URL prjURL)
- throws IOException {
+ public static DataStore readDataStoreFromShape(URL shpURL, URL prjURL) throws IOException {
Map<Object,Object> map = new HashMap<Object,Object>();
map.put("url", shpURL);
map.put("create spatial index", true);
// DataStore dataStore = DataStoreFinder.getDataStore( map );
- DataStore dataStore = new IndexedShapefileDataStore(shpURL, null,
- false, true, IndexType.QIX);
+ DataStore dataStore = new IndexedShapefileDataStore(
+ shpURL, null, false, true, IndexType.QIX);
// DataStore dataStore = new ShapefileDataStore(shpURL);
- System.out.println("DataStore = " + dataStore.getClass().toString());
+ LOGGER.debug("DataStore = " + dataStore.getClass().toString());
IndexedShapefileDataStore dataStoreIndex = (IndexedShapefileDataStore) dataStore;
- System.out.println("indexed = " + dataStoreIndex.isIndexed());
- System.out.println("memory = " + dataStoreIndex.isMemoryMapped());
+ LOGGER.debug("indexed = " + dataStoreIndex.isIndexed());
+ LOGGER.debug("memory = " + dataStoreIndex.isMemoryMapped());
+
return dataStore;
}
@@ -283,10 +346,10 @@
* {@link com.vividsolutions.jts.geom.Geometry}-Objekten.<br>
* Baut auf folgenden Geotools-Klassen auf: <code>
* <ul>
- * <li>{@link ShapefileReader org.geotools.data.shapefile.shp.ShapefileReader}</li>
- * <li>{@link Geometry com.vividsolutions.jts.geom.Geometry}</li>
- * </ul>
- * </code>
+ * <li>{@link ShapefileReader org.geotools.data.shapefile.shp.ShapefileReader}</li>
+ * <li>{@link Geomtry com.vividsolutions.jts.geom.Geometry}</li>
+ * </ul>
+ * </code>
*
* @param file
* Shape-File
@@ -314,82 +377,227 @@
return geomList;
}
- /**
- * Diese Methode importiert ein Raster aus einer Datei im
- * ArcInfoASCII-Grid-Format. Das CRS wird aus einem prj-File (EPSG-Code
- * "EPSG:..." oder WKT-Definition) gelesen. Ist dies nicht erfolgreich, wird
- * {@link #DEFAULT_CRS} als CRS verwendet.
- *
- * @param file
- * ASCII-File
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
- * @return {@link GridCoverage2D}
- */
- public static GridCoverage2D readGridFromArcInfoASCII(File file)
- throws Exception {
- return readGridFromArcInfoASCII(file, null);
- }
+ ///////////////////////////////////////////////////////////////////////////
+ // RASTER IMPORT (GridCoverage2D)
+ ///////////////////////////////////////////////////////////////////////////
- /**
- * Diese Methode importiert ein Raster aus einer Datei im
- * ArcInfoASCII-Grid-Format. Wenn kein CRS angegeben wird, wird versucht das
- * CRS aus einem prj-File (EPSG-Code "EPSG:..." oder WKT-Definition) zu
- * lesen. Ist dies nicht erfolgreich, wird {@link #DEFAULT_CRS} als CRS
- * verwendet.
- *
- * @param file
- * ASCII-File
- * @param crs
- * CoordinateReferenceSystem fuer das Raster (kann {@code null}
- * sein)
- * @throws Exception
- * @throws MalformedURLException
- * @throws java.lang.Exception
- * bei irgendeinem Fehler TODO
- */
- public static GridCoverage2D readGridFromArcInfoASCII(File file,
- CoordinateReferenceSystem crs) throws MalformedURLException, Exception {
- return readGridFromArcInfoASCII(file.toURI().toURL(), crs);
+ /**
+ * Imports a raster from file or URL in
+ * ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
+ * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
+ * is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ public static GridCoverage2D readGridFromArcInfoASCII(Object input) throws Exception {
+ return readGridFromArcInfoASCII(input, null);
+ }
- // ArcGridRaster reader = new ArcGridRaster( new BufferedReader( new
- // InputStreamReader( new FileInputStream(file) ) ), false );
- // WritableRaster raster = reader.readRaster();
- // if (crs == null)
- // crs = determineProjection(file);
- //
- // //
- // System.out.println("Position "+reader.getXlCorner()+" / "+reader.getYlCorner());
- // //
- // System.out.println("Size "+reader.getNCols()+" / "+reader.getNRows());
- // //
- // System.out.println("Min/Max "+reader.getMinValue()+" / "+reader.getMaxValue());
- // // System.out.println("NoData "+reader.getNoData());
- // // System.out.println("CellSize "+reader.getCellSize());
- //
- // float x = (float) reader.getXlCorner(); // Suedwestliche Ecke!
- // float y = (float) reader.getYlCorner(); // Suedwestliche Ecke!
- // float w = (float) (reader.getNCols() * reader.getCellSize()); //
- // reale Breite = RasterSpalten * Aufloesung
- // float h = (float) (reader.getNRows() * reader.getCellSize()); //
- // reale Hoehe = RasterZeilen * Aufloesung
- // Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
- // w, h));
- //
- // // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten
- // das
- // // Coloring des Rasters nicht klappt.
- // // --> Name der Categories muss (warum auch immer) mit dem Namen
- // // des Rasters uebereinstimmen!!!
- // return new GridCoverageFactory().create("", raster, envelope);
- // //
- // //=== OHNE ArcGridRaster ===
- // //// ArcGridReader reader = new ArcGridReader( new BufferedReader(
- // new InputStreamReader( new FileInputStream(file) ) ));
- // // ArcGridReader reader = new ArcGridReader( file );
- // // return (GridCoverage2D)reader.read(null);
- }
+ /**
+ * Imports a raster from file or URL in
+ * ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
+ * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
+ * is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ public static GridCoverage2D readGridFromArcInfoASCII(Object input, CoordinateReferenceSystem crs) throws Exception {
+ switch( getAsciiRasterImportMode() ) {
+ case USE_ARCGRIDREADER: return readGridFromArcInfoASCII_ArcGridReader(input, crs);
+ case USE_ARCGRIDRASTER: return readGridFromArcInfoASCII_ArcGridRaster(input, crs);
+ }
+ throw new UnsupportedOperationException("ASCII raster import mode not supported: "+getAsciiRasterImportMode());
+ }
+
+ /**
+ * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to import a raster
+ * from file or URL in ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
+ * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
+ * is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ private static GridCoverage2D readGridFromArcInfoASCII_ArcGridReader(Object input, CoordinateReferenceSystem crs) throws Exception {
+ Hints hints = new Hints();
+ if (crs != null) {
+ hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
+ }
+ ArcGridReader reader = new ArcGridReader(input ,hints);
+ GridCoverage2D gc = (GridCoverage2D) reader.read(null);
+ return gc;
+ }
+
+ /**
+ * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to import a raster
+ * from file or URL in ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
+ * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
+ * is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ private static GridCoverage2D readGridFromArcInfoASCII_ArcGridRaster(Object input, CoordinateReferenceSystem crs) throws Exception {
+ // Import raster data
+ ArcGridRaster reader = null;
+ if (input instanceof File)
+ reader = new ArcGridRaster( new BufferedReader( new InputStreamReader( new FileInputStream((File)input) ) ), false );
+ else if (input instanceof URL)
+ reader = new ArcGridRaster( (URL)input );
+ else
+ throw new UnsupportedOperationException("Import source not supported: "+LangUtil.getSimpleClassName(input));
+ WritableRaster raster = reader.readRaster();
+
+ // Import CRS
+ if (crs == null) {
+ if (input instanceof File)
+ crs = determineProjection((File)input);
+ else if (input instanceof URL)
+ crs = determineProjection((URL)input);
+ }
+
+// LOGGER.debug("Position "+reader.getXlCorner()+" / "+reader.getYlCorner());
+// LOGGER.debug("Size "+reader.getNCols()+" / "+reader.getNRows());
+// LOGGER.debug("Min/Max "+reader.getMinValue()+" / "+reader.getMaxValue());
+// LOGGER.debug("NoData "+reader.getNoData());
+// LOGGER.debug("CellSize "+reader.getCellSize());
+
+ float x = (float) reader.getXlCorner(); // SW corner!
+ float y = (float) reader.getYlCorner(); // SW corner!
+ // real width = colums * cell size
+ float w = (float) (reader.getNCols() * reader.getCellSize());
+ // real hight = rows * cell size
+ float h = (float) (reader.getNRows() * reader.getCellSize());
+ Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y, w, h));
+
+ // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten
+ // das Coloring des Rasters nicht klappt.
+ // --> Name der Categories muss (warum auch immer) mit dem Namen
+ // des Rasters uebereinstimmen!!!
+ return new GridCoverageFactory().create("", raster, envelope);
+ }
+ // NOT USED ANYMORE: File and URL are handled by the same method using Object
+// /**
+// * Diese Methode importiert ein Raster aus einer Datei im
+// * ArcInfoASCII-Grid-Format. Das CRS wird aus einem prj-File (EPSG-Code
+// * "EPSG:..." oder WKT-Definition) gelesen. Ist dies nicht erfolgreich, wird
+// * {@link #DEFAULT_CRS} als CRS verwendet.
+// * @param file ASCII-File
+// * @throws java.lang.Exception bei irgendeinem Fehler
+// * @return {@link GridCoverage2D}
+// */
+// public static GridCoverage2D readGridFromArcInfoASCII(File file) throws Exception {
+// return readGridFromArcInfoASCII(file, null);
+// }
+//
+// /**
+// * Diese Methode importiert ein Raster aus einer Datei im
+// * ArcInfoASCII-Grid-Format. Wenn kein CRS angegeben wird, wird versucht das
+// * CRS aus einem prj-File (EPSG-Code "EPSG:..." oder WKT-Definition) zu
+// * lesen. Ist dies nicht erfolgreich, wird {@link #DEFAULT_CRS} als CRS
+// * verwendet.
+// * @param file ASCII-File
+// * @param crs CoordinateReferenceSystem fuer das Raster (kann {@code null} sein)
+// * @throws MalformedURLException if the file can not be converted to URL
+// * @throws Exception bei irgendeinem Fehler
+// */
+// public static GridCoverage2D readGridFromArcInfoASCII(File file, CoordinateReferenceSystem crs) throws MalformedURLException, Exception {
+// return readGridFromArcInfoASCII(file.toURI().toURL(), crs);
+// }
+
+ /**
+ * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
+ *
+ * @param file
+ * GeoTIFF-File
+ * @throws java.lang.Exception
+ * bei irgendeinem Fehler
+ * @see #readGridFromGeoTiff(File, CoordinateReferenceSystem)
+ */
+ public static GridCoverage2D readGridFromGeoTiff(File file) throws Exception {
+ return readGridFromGeoTiff(file, null);
+ }
+
+ /**
+ * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
+ *
+ * @param file
+ * GeoTIFF-File
+ * @param crs
+ * erzwungenes CoordinateReferenceSystem fuer das Raster (kann
+ * {@code null} sein)
+ * @throws java.lang.Exception
+ * bei irgendeinem Fehler
+ * @see #createGridReaderFromGeoTiff(File, CoordinateReferenceSystem)
+ */
+ public static GridCoverage2D readGridFromGeoTiff(File file, CoordinateReferenceSystem crs) throws Exception {
+ // return (GridCoverage2D)createGridReaderFromGeoTiff(file, crs).read(null);
+ GridCoverage2D gc = null;
+ // Versuchen Geo-Information aus Tiff zu lesen
+ try {
+ Hints hints = new Hints();
+
+ // Wenn CRS angegeben, dieses durch Hint erzwingen
+ if (crs != null)
+ hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
+ // Reader (mit Metadaten) erzeugen
+ GeoTiffReader reader = new GeoTiffReader(file, hints);
+ // Wenn kein Referenzsystem vorhanden, versuchen ein prj-File zu
+ // verwenden
+ if (reader.getOriginalEnvelope().getCoordinateReferenceSystem() == null) {
+ LOGGER.warn("No projection information found in '"
+ + file.getName() + "'. Using prj-file...");
+ hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM,
+ determineProjection(file));
+ reader = new GeoTiffReader(file, hints);
+ }
+ gc = (GridCoverage2D) reader.read(null);
+ return gc;
+ } catch (UnsupportedOperationException err) {
+ // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
+ // ExceptionMonitor.show(null, err,
+ // "No geoinformation in TIFF, importing it as a normal file. Trying to read it as normal TIFF + Worldfile.");
+ } catch (NullPointerException err) {
+ // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
+ }
+
+ // keine Geo-Informationen in Tiff
+ // --> Raster ueber ImageIO einlesen und WorldFile/ProjectionFile
+ // verwenden
+ LOGGER.warn("No geo information found in '" + file.getName()
+ + "'. Using world- and prj-file...");
+ BufferedImage im = ImageIO.read(file);
+ if (im == null)
+ throw new IIOException("No image reader found for this image type!");
+ // World-File einlesen
+ File tfw = IOUtil.changeFileExt(file, "tfw");
+ double[] tfwInfo = readWorldFile(tfw);
+ float w = (float) (im.getWidth() * tfwInfo[0]); // reale Breite =
+ // RasterSpalten * hor.
+ // Aufloesung
+ float h = (float) (im.getHeight() * (-tfwInfo[3])); // reale Hoehe =
+ // RasterZeilen *
+ // vert. Aufloesung
+ float x = (float) tfwInfo[4]; // Suedwestliche Ecke!
+ float y = (float) tfwInfo[5] - h; // Suedwestliche Ecke (im tfw-File
+ // steht die Nordwestliche!)
+ // ggf. Projektion einlesen
+ if (crs == null)
+ crs = determineProjection(file);
+ Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
+ w, h));
+ // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten das
+ // Coloring des Rasters nicht klappt.
+ // --> Name der Categories muss (warum auch immer) mit dem Namen
+ // des Rasters uebereinstimmen!!!
+ gc = new GridCoverageFactory().create("", im.copyData(null), envelope);
+ return gc;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // RASTER IMPORT (AbstractGridCoverage2DReader)
+ ///////////////////////////////////////////////////////////////////////////
+
/**
* Diese Methode erzeugt einen {@link AbstractGridCoverage2DReader} aus
* einer Datei im GeoTIFF-Format. Zunaechst wird versucht, die
@@ -466,187 +674,94 @@
return createGridReaderFromGeoTiff(file, null);
}
- /**
- * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
- *
- * @param file
- * GeoTIFF-File
- * @param crs
- * erzwungenes CoordinateReferenceSystem fuer das Raster (kann
- * {@code null} sein)
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
- * @see #createGridReaderFromGeoTiff(File, CoordinateReferenceSystem)
- */
- public static GridCoverage2D readGridFromGeoTiff(File file,
- CoordinateReferenceSystem crs) throws Exception {
- // return (GridCoverage2D)createGridReaderFromGeoTiff(file,
- // crs).read(null);
- GridCoverage2D gc = null;
- // Versuchen Geo-Information aus Tiff zu lesen
- try {
- Hints hints = new Hints();
+ ///////////////////////////////////////////////////////////////////////////
+ // RASTER IMPORT (WritableGridRaster)
+ ///////////////////////////////////////////////////////////////////////////
- // Wenn CRS angegeben, dieses durch Hint erzwingen
- if (crs != null)
- hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
- // Reader (mit Metadaten) erzeugen
- GeoTiffReader reader = new GeoTiffReader(file, hints);
- // Wenn kein Referenzsystem vorhanden, versuchen ein prj-File zu
- // verwenden
- if (reader.getOriginalEnvelope().getCoordinateReferenceSystem() == null) {
- LOGGER.warn("No projection information found in '"
- + file.getName() + "'. Using prj-file...");
- hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM,
- determineProjection(file));
- reader = new GeoTiffReader(file, hints);
- }
- gc = (GridCoverage2D) reader.read(null);
- return gc;
- } catch (UnsupportedOperationException err) {
- // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
- // ExceptionMonitor.show(null, err,
- // "No geoinformation in TIFF, importing it as a normal file. Trying to read it as normal TIFF + Worldfile.");
- } catch (NullPointerException err) {
- // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
- }
-
- // keine Geo-Informationen in Tiff
- // --> Raster ueber ImageIO einlesen und WorldFile/ProjectionFile
- // verwenden
- LOGGER.warn("No geo information found in '" + file.getName()
- + "'. Using world- and prj-file...");
- BufferedImage im = ImageIO.read(file);
- if (im == null)
- throw new IIOException("No image reader found for this image type!");
- // World-File einlesen
- File tfw = IOUtil.changeFileExt(file, "tfw");
- double[] tfwInfo = readWorldFile(tfw);
- float w = (float) (im.getWidth() * tfwInfo[0]); // reale Breite =
- // RasterSpalten * hor.
- // Aufloesung
- float h = (float) (im.getHeight() * (-tfwInfo[3])); // reale Hoehe =
- // RasterZeilen *
- // vert. Aufloesung
- float x = (float) tfwInfo[4]; // Suedwestliche Ecke!
- float y = (float) tfwInfo[5] - h; // Suedwestliche Ecke (im tfw-File
- // steht die Nordwestliche!)
- // ggf. Projektion einlesen
- if (crs == null)
- crs = determineProjection(file);
- Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
- w, h));
- // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten das
- // Coloring des Rasters nicht klappt.
- // --> Name der Categories muss (warum auch immer) mit dem Namen
- // des Rasters uebereinstimmen!!!
- gc = new GridCoverageFactory().create("", im.copyData(null), envelope);
- return gc;
+ /**
+ * Import a raster from file or URL in ArcInfoASCII format.
+ * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
+ * If not present the {@link #DEFAULT_CRS} is used.
+ * @param input ASCII file or URL to the input file
+ */
+ public static WritableGridRaster readGridRasterFromArcInfoASCII(Object input) throws Exception {
+ return readGridRasterFromArcInfoASCII(input, null);
}
- /**
- * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
- *
- * @param file
- * GeoTIFF-File
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
- * @see #readGridFromGeoTiff(File, CoordinateReferenceSystem)
+ /**
+ * Import a raster from file or URL in ArcInfoASCII format.
+ * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
+ * If not present the {@link #DEFAULT_CRS} is used.
+ * @param input ASCII file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
*/
- public static GridCoverage2D readGridFromGeoTiff(File file)
- throws Exception {
- return readGridFromGeoTiff(file, null);
+ public static WritableGridRaster readGridRasterFromArcInfoASCII(Object input, CoordinateReferenceSystem crs) throws Exception {
+ switch( getAsciiRasterImportMode() ) {
+ case USE_ARCGRIDREADER: return readGridRasterFromArcInfoASCII_ArcGridReader(input, crs);
+ case USE_ARCGRIDRASTER: return readGridRasterFromArcInfoASCII_ArcGridRaster(input, crs);
+ }
+ throw new UnsupportedOperationException("ASCII raster import mode not supported: "+getAsciiRasterImportMode());
}
- /**
- * Diese Methode importiert ein Raster aus einer Datei im
- * ArcInfoASCII-Grid-Format. Das CRS wird aus einem prj-File (EPSG-Code
- * "EPSG:..." oder WKT-Definition) gelesen. Ist dies nicht erfolgreich, wird
- * {@link #DEFAULT_CRS} als CRS verwendet.
- *
- * @param file
- * ASCII-File
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
- */
- public static WritableGridRaster readGridRasterFromArcInfoASCII(File file)
- throws Exception {
- return readGridRasterFromArcInfoASCII(file, null);
- }
-
+ /**
+ * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to
+ * import a raster from file or URL in ArcInfoASCII format.
+ * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
+ * If not present the {@link #DEFAULT_CRS} is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridReader(Object input, CoordinateReferenceSystem crs) throws Exception {
+ GridCoverage2D grid = readGridFromArcInfoASCII(input, crs);
+ WritableRaster raster = grid.getRenderedImage().copyData(null);
+ return new WritableGridRaster(raster,grid.getEnvelope2D()) ;
+ }
+ /**
+ * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to
+ * import a raster from file or URL in ArcInfoASCII format.
+ * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
+ * If not present the {@link #DEFAULT_CRS} is used.
+ * @param input file or URL to the input file
+ * @param crs CRS forced to use (can be <code>null</code>)
+ */
+ private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridRaster(Object input, CoordinateReferenceSystem crs) throws Exception {
+ // Import raster data
+ ArcGridRaster reader = null;
+ if (input instanceof File)
+ reader = new ArcGridRaster( new BufferedReader( new InputStreamReader( new FileInputStream((File)input) ) ), false );
+ else if (input instanceof URL)
+ reader = new ArcGridRaster( (URL)input );
+ else
+ throw new UnsupportedOperationException("Import source not supported: "+LangUtil.getSimpleClassName(input));
+ WritableRaster raster = reader.readRaster();
+
+ // Import CRS
+ if (crs == null) {
+ if (input instanceof File)
+ crs = determineProjection((File)input);
+ else if (input instanceof URL)
+ crs = determineProjection((URL)input);
+ }
+
+// LOGGER.debug("Position "+reader.getXlCorner()+" / "+reader.getYlCorner());
+// LOGGER.debug("Size "+reader.getNCols()+" / "+reader.getNRows());
+// LOGGER.debug("Min/Max "+reader.getMinValue()+" / "+reader.getMaxValue());
+// LOGGER.debug("NoData "+reader.getNoData());
+// LOGGER.debug("CellSize "+reader.getCellSize());
+
+ float x = (float) reader.getXlCorner(); // SW corner!
+ float y = (float) reader.getYlCorner(); // SW corner!
+ // real width = colums * cell size
+ float w = (float) (reader.getNCols() * reader.getCellSize());
+ // real hight = rows * cell size
+ float h = (float) (reader.getNRows() * reader.getCellSize());
+ Rectangle2D envelope = new Rectangle2D.Float(x, y, w, h);
-
+ return new WritableGridRaster(raster, envelope, crs);
+ }
+
/**
- @param crs may be <code>null</code>
- */
- public static GridCoverage2D readGridFromArcInfoASCII(Object input,
- CoordinateReferenceSystem crs) throws Exception {
-
- Hints hints = new Hints();
- if (crs != null) {
- hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
- }
- ArcGridReader reader = new ArcGridReader(input ,hints);
- GridCoverage2D gc = (GridCoverage2D) reader.read(null);
-
- return gc;
- }
-
-
- /**
- * Diese Methode importiert ein Raster aus einer Datei im
- * ArcInfoASCII-Grid-Format. Wenn kein CRS angegeben wird, wird versucht das
- * CRS aus einem prj-File (EPSG-Code "EPSG:..." oder WKT-Definition) zu
- * lesen. Ist dies nicht erfolgreich, wird {@link #DEFAULT_CRS} als CRS
- * verwendet.
- *
- * @param file
- * ASCII-File
- * @param crs
- * CoordinateReferenceSystem fuer das Raster (kann {@code null}
- * sein)
- * @throws Exception
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
- */
- public static WritableGridRaster readGridRasterFromArcInfoASCII(File file,
- CoordinateReferenceSystem crs) throws Exception {
-
- GridCoverage2D grid = readGridFromArcInfoASCII(file, crs);
- WritableRaster raster = grid.getRenderedImage().copyData(null);
- return new WritableGridRaster(raster,grid.getEnvelope2D()) ;
-
-// ArcGridRaster reader = new ArcGridRaster(new BufferedReader(
-// new InputStreamReader(new FileInputStream(file))), false);
-// WritableRaster raster = reader.readRaster();
-// float x = (float) reader.getXlCorner(); // Suedwestliche Ecke!
-// float y = (float) reader.getYlCorner(); // Suedwestliche Ecke!
-// float w = (float) (reader.getNCols() * reader.getCellSize()); // reale
-// // Breite
-// // =
-// // RasterSpalten
-// // *
-// // Aufloesung
-// float h = (float) (reader.getNRows() * reader.getCellSize()); // reale
-// // Hoehe
-// // =
-// // RasterZeilen
-// // *
-// // Aufloesung
-// // Projektion einlesen
-// if (crs == null)
-// crs = determineProjection(file);
-// return new WritableGridRaster(raster,
-// new Rectangle2D.Float(x, y, w, h), crs);
-
- // === OHNE ArcGridRaster ===
- // GridCoverage2D grid = readGridFromArcInfoASCII(null,input);
- // WritableRaster raster = grid.getRenderedImage().copyData(null);
- // return( new WritableGridRaster(raster,grid.getEnvelope2D()) );
- }
-
- /**
* Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
* Zunaechst wird versucht, die Geo-Informationen (Referenz+CRS) aus den
* TIFF-Metadaten zu ermitteln. Ist dies nicht erfolgreich, werden ein
@@ -660,8 +775,7 @@
* @throws java.lang.Exception
* bei irgendeinem Fehler
*/
- public static WritableGridRaster readGridRasterFromGeoTiff(File file)
- throws Exception {
+ public static WritableGridRaster readGridRasterFromGeoTiff(File file) throws Exception {
return readGridRasterFromGeoTiff(file, null);
}
@@ -674,16 +788,12 @@
* WKT-Definition erlaubt. Kann kein CRS ermitteln werden, wird
* {@link #DEFAULT_CRS} als CRS verwendet.
*
- * @param file
- * GeoTIFF-File
- * @param crs
- * erzwungenes CoordinateReferenceSystem fuer das Raster (kann
+ * @param file GeoTIFF-File
+ * @param crs erzwungenes CoordinateReferenceSystem fuer das Raster (kann
* {@code null} sein)
- * @throws java.lang.Exception
- * bei irgendeinem Fehler
+ * @throws java.lang.Exception bei irgendeinem Fehler
*/
- public static WritableGridRaster readGridRasterFromGeoTiff(File file,
- CoordinateReferenceSystem crs) throws Exception {
+ public static WritableGridRaster readGridRasterFromGeoTiff(File file, CoordinateReferenceSystem crs) throws Exception {
// // GeoTiff-File einlesen
// BufferedImage im = ImageIO.read( file );
// if ( im == null )
@@ -715,18 +825,24 @@
// );
//
- GridCoverage2D gc = readGridFromGeoTiff(file, crs);
- Rectangle2D env = gc.getEnvelope2D();
- RenderedImage im = gc.getRenderedImage();
- WritableGridRaster raster = new WritableGridRaster(im.getData()
- .getDataBuffer().getDataType(), 0, 0, im.getWidth(), im
- .getHeight(), env, crs);
-
+ GridCoverage2D gc = readGridFromGeoTiff(file, crs);
+ Rectangle2D env = gc.getEnvelope2D();
+ RenderedImage im = gc.getRenderedImage();
+ WritableGridRaster raster = new WritableGridRaster(
+ im.getData().getDataBuffer().getDataType(),
+ 0, 0,
+ im.getWidth(), im.getHeight(),
+ env,
+ crs
+ );
im.copyData(raster);
return raster;
}
+ ///////////////////////////////////////////////////////////////////////////
+ // META DATA IMPORT (WORLD FILE)
+ ///////////////////////////////////////////////////////////////////////////
/**
* Liest ein World-File (.tfw) ein und liefert die darin zeilenweise
* gespeicherten Werte zurueck. Leer- und Kommentarzeilen werden dabei
@@ -828,6 +944,10 @@
return ret;
}
+ ///////////////////////////////////////////////////////////////////////////
+ // META DATA IMPORT (PROJECTION)
+ ///////////////////////////////////////////////////////////////////////////
+
/**
* Liest das CRS aus einer Datei. Zunaechst wird versucht das CRS aus der
* uebergebene Datei zu lesen. Ist dies nicht erfolgreich wird das zur Datei
@@ -837,27 +957,8 @@
* Datei
* @return {@code null}, wenn kein CRS gelesen werden konnte
*/
- public static CoordinateReferenceSystem determineProjection(File file)
- throws IOException {
-
- // ****************************************************************************
- // schonmal teilweise migriert... das geht direkt an die URL methode
- // weiter...
- // ****************************************************************************
-
- // CoordinateReferenceSystem crs = null;
- // // Versuchen CRS aus angegebener Datei zu lesen
- // crs = readProjectionFile(file);
- // // Wenn nicht erfolgreich versuchen die zur Datei korrespondierende
- // // prj-Datei einzulesen
- // if ( crs == null )
- // crs = readProjectionFile( IOUtil.changeFileExt(file,"prj") );
- // // Wenn nicht erfolgreich, Default verwenden
- // if ( crs == null ) {
- // LOGGER.warn("No projection found for file '"+file.getName()+"'. Default CRS used.");
- // crs = DEFAULT_CRS;
- // }
- return determineProjection(file.toURI().toURL());
+ public static CoordinateReferenceSystem determineProjection(File file) throws IOException {
+ return determineProjection(file.toURI().toURL());
}
/**
@@ -871,27 +972,24 @@
public static CoordinateReferenceSystem determineProjection(URL prjUrl) {
CoordinateReferenceSystem crs = null;
// Versuchen CRS aus angegebener Datei zu lesen
-
- LOGGER.debug("determineProjection: Try to read a projection from URL "
- + prjUrl);
+ LOGGER.debug("determineProjection: Try to read a projection from URL " + prjUrl);
try {
crs = GeoImportUtil.readProjectionFile(prjUrl);
} catch (IOException e) {
}
if (crs == null) {
- try {
- crs = GeoImportUtil.readProjectionFile(IOUtil.changeUrlExt(
- prjUrl, "prj"));
- } catch (IllegalArgumentException e) {
- } catch (IOException e) {
- }
+ try {
+ crs = GeoImportUtil.readProjectionFile(IOUtil.changeUrlExt(prjUrl, "prj"));
+ } catch (IllegalArgumentException e) {
+ } catch (IOException e) {
+ }
}
// Wenn nicht erfolgreich, Default verwenden
if (crs == null) {
- LOGGER.warn("No projection found in URL. Default CRS used.");
- crs = getDEFAULT_CRS();
+ LOGGER.warn("No projection found in URL. Default CRS used.");
+ crs = getDefaultCRS();
}
return crs;
}
@@ -912,11 +1010,10 @@
* @throws IOException
* falls die URL nicht wie erwartet gelesen werden konnte.
*/
- public static CoordinateReferenceSystem readProjectionFile(URL prjURL)
- throws IOException {
- String crsDefinition = readProjectionString(prjURL);
- CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
- return crs;
+ public static CoordinateReferenceSystem readProjectionFile(URL prjURL) throws IOException {
+ String crsDefinition = readProjectionString(prjURL);
+ CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
+ return crs;
}
/**
@@ -931,8 +1028,7 @@
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
* (University of Bonn/Germany)
*/
- public static CoordinateReferenceSystem readProjectionFile(File prjFile)
- throws IOException {
+ public static CoordinateReferenceSystem readProjectionFile(File prjFile) throws IOException {
String crsDefinition = readProjectionString(prjFile);
CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
// if ( crs == null )
@@ -971,7 +1067,6 @@
buffer.append(" ").append(line);
input.close();
return buffer.toString().trim();
-
}
/**
@@ -994,13 +1089,11 @@
*/
public static String readProjectionString(URL url) throws IOException {
if (url == null) {
- LOGGER
- .debug("readProjectionString returned empty String for url==null");
+ LOGGER.debug("readProjectionString returned empty String for url==null");
return "";
}
- BufferedReader input = new BufferedReader(new InputStreamReader(url
- .openStream()));
+ BufferedReader input = new BufferedReader(new InputStreamReader(url.openStream()));
try {
// Alle Zeilen der Datei aneinander haengen
StringBuffer buffer = new StringBuffer();
@@ -1021,13 +1114,4 @@
input.close();
}
}
-
- public static void setDEFAULT_CRS(CoordinateReferenceSystem dEFAULT_CRS) {
- DEFAULT_CRS = dEFAULT_CRS;
- }
-
- public static CoordinateReferenceSystem getDEFAULT_CRS() {
- return DEFAULT_CRS;
- }
-
}
More information about the Schmitzm-commits
mailing list