sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1631785 - in /sis/branches/JDK8/storage/sis-shapefile/src: main/java/org/apache/sis/storage/shapefile/ test/java/org/apache/sis/storage/shapefile/
Date Tue, 14 Oct 2014 15:21:31 GMT
Author: desruisseaux
Date: Tue Oct 14 15:21:30 2014
New Revision: 1631785

URL: http://svn.apache.org/r1631785
Log:
Commited the refactoring done by Marc Le Bihan
https://issues.apache.org/jira/browse/SIS-180
This commit does not include yet the JDBC classes.
Those classes will be the subject of a separated commit.

Added:
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/Database.java
      - copied, changed from r1631330, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
  (with props)
Modified:
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/DataType.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/FieldDescriptor.java
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
    sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/DataType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/DataType.java?rev=1631785&r1=1631784&r2=1631785&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/DataType.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/DataType.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -28,33 +28,72 @@ package org.apache.sis.storage.shapefile
  * @see <a href="http://www.clicketyclick.dk/databases/xbase/format/data_types.html">Xbase
Data Types</a>
  */
 public enum DataType {
+    /** Character (less than 254 characters). */
+    Character('C'),
+
+    /** Number (less than 18 characters, can include sign and decimal). */
+    Number('N'),
+
+    /** Logical (3 way, ? Y,y,T,t  N,n,F,f). */
+    Logical('L'),
+
+    /** Date (YYYYMMDD format). */
+    Date('D'),
+
+    /** Memo (Pointer to ASCII text field). */
+    Memo('M'),
+
+    /** Floating point (20 digits). */
+    FloatingPoint('F'),
 
-    Character('C'), // < 254 characters
-    Number('N'), // < 18 characters, can include sign and decimal
-    Logical('L'), // 3 way, ? Y,y,T,t  N,n,F,f
-    Date('D'), // YYYYMMDD
-    Memo('M'), // Pointer to ASCII text field
-    FloatingPoint('F'), // 20 digits
     // CharacterNameVariable("?"),  //1-254 Characters
-    Picture('P'), // Memo
-    Currency('Y'), // Foxpro
-    DateTime('T'), // 32 bit little-endian Julian date, 32 byte little endian milliseconds
since midnight
-    Integer('I'), // 4 byte little endian
-    VariField('V'), // ???
-    Variant('X'), // ???
-    TimeStamp('@'), // see url
-    Double('O'), //
-    AutoIncrement('+'); // ???
 
+    /** Picture (memo). */
+    Picture('P'),
+
+    /** Currency (Foxpro). */
+    Currency('Y'),
+
+    /** Date time (32 bit little-endian Julian date, 32 byte little endian milliseconds since
midnight). */
+    DateTime('T'),
+
+    /** Integer (4 byte little endian). */
+    Integer('I'),
+
+    /** Varifield (???). */
+    VariField('V'),
+
+    /** Variant (???). */
+    Variant('X'),
+
+    /** Time stamp (see url). */
+    TimeStamp('@'),
+
+    /** Double. */
+    Double('O'),
+
+    /** Auto increment. */
+    AutoIncrement('+');
+
+    /** Data type. */
     public final char datatype;
 
-    DataType(char datatype) {
-        this.datatype = datatype;
+    /**
+     * Construct a datatype.
+     * @param type Data type.
+     */
+    DataType(char type) {
+        this.datatype = type;
     }
 
-    public static DataType valueOfDataType(char datatype) {
+    /**
+     * Return the Datatype enum of a code.
+     * @param code Character code describing the dbf datatype.
+     * @return Datatype.
+     */
+    public static DataType valueOfDataType(char code) {
         for (DataType v : values()) {
-            if (v.datatype == datatype) {
+            if (v.datatype == code) {
                 return v;
             }
         }

Copied: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/Database.java
(from r1631330, sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/Database.java?p2=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/Database.java&p1=sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java&r1=1631330&r2=1631785&rev=1631785&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/Database.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -16,109 +16,110 @@
  */
 package org.apache.sis.storage.shapefile;
 
-import java.io.IOException;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import com.esri.core.geometry.Point;
-import com.esri.core.geometry.Polygon;
-import com.esri.core.geometry.Polyline;
-import com.esri.core.geometry.Geometry;
-
-import org.apache.sis.feature.DefaultFeatureType;
-import org.apache.sis.feature.DefaultAttributeType;
-import org.apache.sis.storage.DataStoreException;
-
-// Branch-dependent imports
-import org.opengis.feature.Feature;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
 
+import org.opengis.feature.*;
 
 /**
- * Provides a ShapeFile Reader.
- *
- * @author  Travis L. Pinney
- * @since   0.5
- * @version 0.5
- * @module
- *
- * @see <a href="http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf">ESRI Shapefile
Specification</a>
- * @see <a href="http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm">dBASE
III File Structure</a>
+ * Load a whole DBF file.
+ * @see <a href="http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm" >Database
structure</a>
+ * @author Travis L. Pinney
  */
-public class ShapeFile {
-    private static final String GEOMETRY_NAME = "geometry";
-
-    public int FileCode;   // big
-    public int FileLength;  // big // The value for file length is the total length of the
file in 16-bit words
-    public int Version; // little
-    public ShapeTypeEnum ShapeType; // little
-    public double xmin; // little
-    public double ymin; // little
-    public double xmax; // little
-    public double ymax; // little
-    public double zmin; // little
-    public double zmax; // little
-    public double mmin; // little
-    public double mmax; // little
+public class Database implements AutoCloseable {
+    /** Database filename. */
+    private String m_dbfFile;
 
+    /** Indicates is the database file is closed or not. */
+    private boolean isClosed;
 
-    // http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm
+    /** Valid dBASE III PLUS table file (03h without a memo .DBT file; 83h with a memo).
*/
     public byte DbaseVersion;
+
+    /** Date of last update; in YYMMDD format. */
     public byte[] DbaseLastUpdate = new byte[3];
-    public int FeatureCount;
+
+    /** Number of records in the table. */
+    public int recordCount;
+
+    /** Number of bytes in the header. */
     public short DbaseHeaderBytes;
+
+    /** Number of bytes in the record. */
     public short DbaseRecordBytes;
-    // reserve 3 bytes
+
+    /** Reserved bytes. */
     public byte[] DbasePlusLanReserved = new byte[13];
-    // reserve 4 bytes
 
-    public ArrayList<FieldDescriptor> FDArray = new ArrayList<FieldDescriptor>();
-    public Map<Integer, Feature> FeatureMap = new HashMap<Integer, Feature>();
+    /** Fields descriptor. */
+    public ArrayList<FieldDescriptor> fieldsDescriptors = new ArrayList<>();
 
+    /** Input Stream on the DBF. */
+    private FileInputStream fis;
 
+    /** File channel on the file. */
+    private FileChannel fc;
 
-    public ShapeFile(String shpfile) throws IOException, DataStoreException {
-        FileInputStream fis = new FileInputStream(shpfile);
-        FileChannel fc = fis.getChannel();
-        int fsize = (int) fc.size();
-        MappedByteBuffer rf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
+    /** Buffer reader. */
+    private MappedByteBuffer df;
+
+    /** Current row rumber. */
+    private int rowNum;
+
+    /**
+     * Load a database file.
+     * @param dbfFile Database file.
+     * @throws FileNotFoundException if the database file cannot be found.
+     */
+    public Database(String dbfFile) throws FileNotFoundException {
+        Objects.requireNonNull(dbfFile, "The database file to load cannot be null.");
+        m_dbfFile = dbfFile;
+
+        fis = new FileInputStream(m_dbfFile);
+        fc = fis.getChannel();
+        rowNum = 0;
+        isClosed = false;
+    }
+
+    /**
+     * Return the record count of the database file.
+     * @return Record count.
+     */
+    public int getRecordCount() {
+        return this.recordCount;
+    }
+
+    /**
+     * Return the fields descriptor.
+     * @return Field descriptor.
+     */
+    public ArrayList<FieldDescriptor> getFieldsDescriptor() {
+        return this.fieldsDescriptors;
+    }
+
+    /**
+     * Return the mapped byte buffer currently used to read that database file.
+     * @return Database file.
+     */
+    public MappedByteBuffer getByteBuffer() {
+        return this.df;
+    }
 
-        this.FileCode = rf.getInt();
-        rf.getInt(); rf.getInt(); rf.getInt(); rf.getInt(); rf.getInt();
-        this.FileLength = rf.getInt() * 2;
-
-        byte [] data = new byte[4];
-
-        rf.order(ByteOrder.LITTLE_ENDIAN);
-        this.Version = rf.getInt();
-        this.ShapeType = ShapeTypeEnum.get(rf.getInt());
-        this.xmin = rf.getDouble();
-        this.ymin = rf.getDouble();
-        this.xmax = rf.getDouble();
-        this.ymax = rf.getDouble();
-        this.zmin = rf.getDouble();
-        this.zmax = rf.getDouble();
-        this.mmin = rf.getDouble();
-        this.mmax = rf.getDouble();
-        rf.order(ByteOrder.BIG_ENDIAN);
-
-        StringBuilder b = new StringBuilder(shpfile);
-        b.replace(shpfile.length() - 3, shpfile.length() , "dbf");
-        String file_base = b.toString();
-
-        FileInputStream fis2 = new FileInputStream(file_base);
-        FileChannel fc2 = fis2.getChannel();
-        int fsize2 = (int) fc2.size();
-        MappedByteBuffer df = fc2.map(FileChannel.MapMode.READ_ONLY, 0, fsize2);
+    /**
+     * Loading the database file content from binary .dbf file.
+     * @throws IOException if the file cannot be opened.
+     */
+    public void loadDescriptor() throws IOException {
+        int fsize = (int) fc.size();
+        df = fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
 
         this.DbaseVersion = df.get();
         df.get(this.DbaseLastUpdate);
 
         df.order(ByteOrder.LITTLE_ENDIAN);
-        this.FeatureCount = df.getInt();
+        this.recordCount = df.getInt();
         this.DbaseHeaderBytes = df.getShort();
         this.DbaseRecordBytes = df.getShort();
         df.order(ByteOrder.BIG_ENDIAN);
@@ -127,175 +128,150 @@ public class ShapeFile {
         df.get(DbasePlusLanReserved);
         df.getInt();
 
-        while(df.position() <  this.DbaseHeaderBytes - 1) {
-            FieldDescriptor fd = new FieldDescriptor();
-            df.get(fd.FieldName);
-            char dt = (char) df.get();
-            fd.FieldType = DataType.valueOfDataType(dt);
-            df.get(fd.FieldAddress);
-            fd.FieldLength = df.get();
-            fd.FieldDecimalCount = df.get();
-            df.getShort(); // reserved
-            df.get(fd.DbasePlusLanReserved2);
-            fd.WorkAreaID = df.get();
-            df.get(fd.DbasePlusLanReserved3);
-            fd.SetFields = df.get();
-            data = new byte[6];
-            df.get(data); // reserved
-
-            this.FDArray.add(fd);
+        while (df.position() < this.DbaseHeaderBytes - 1) {
+            FieldDescriptor fd = toFieldDescriptor();
+            this.fieldsDescriptors.add(fd);
             // loop until you hit the 0Dh field terminator
         }
-        final DefaultFeatureType featureType = getFeatureType(shpfile);
-
-        df.get(); // should be 0d for field terminator
+    }
 
-        for (Integer i = 0; i < this.FeatureCount; i++) {
-            // insert points into some type of list
-            int RecordNumber = rf.getInt();
-            int ContentLength = rf.getInt();
-
-            data = new byte[4];
-            rf.order(ByteOrder.LITTLE_ENDIAN);
-            int ShapeType = rf.getInt();
-            final Feature f = featureType.newInstance();
-
-            if (ShapeType == ShapeTypeEnum.Point.getValue()) {
-                double x = rf.getDouble();
-                double y = rf.getDouble();
-                Point pnt = new Point(x,y);
-                f.setPropertyValue(GEOMETRY_NAME, pnt);
-
-            } else if (ShapeType == ShapeTypeEnum.Polygon.getValue()) {
-                double xmin = rf.getDouble();
-                double ymin = rf.getDouble();
-                double xmax = rf.getDouble();
-                double ymax = rf.getDouble();
-                int NumParts = rf.getInt();
-                int NumPoints = rf.getInt();
-
-                if (NumParts > 1) {
-                    throw new DataStoreException("Polygons with multiple linear rings have
not implemented yet.");
-                }
-
-                // read the one part
-                int Part = rf.getInt();
-                Polygon poly = new Polygon();
-
-                // create a line from the points
-                double xpnt = rf.getDouble();
-                double ypnt = rf.getDouble();
-                //Point oldpnt = new Point(xpnt, ypnt);
-                poly.startPath(xpnt, ypnt);
-                for (int j=0; j < NumPoints-1; j++) {
-                    xpnt = rf.getDouble();
-                    ypnt = rf.getDouble();
-                    poly.lineTo(xpnt, ypnt);
-                }
-                f.setPropertyValue(GEOMETRY_NAME, poly);
-
-            } else if (ShapeType == ShapeTypeEnum.PolyLine.getValue()) {
-                double xmin = rf.getDouble();
-                double ymin = rf.getDouble();
-                double xmax = rf.getDouble();
-                double ymax = rf.getDouble();
-
-                int NumParts = rf.getInt();
-                int NumPoints = rf.getInt();
-
-                int [] NumPartArr = new int[NumParts+1];
-
-                for (int n=0; n < NumParts; n++) {
-                    int idx = rf.getInt();
-                    NumPartArr[n] = idx;
-                }
-                NumPartArr[NumParts] = NumPoints;
-
-                data = new byte[8];
-
-                double xpnt, ypnt;
-                Polyline ply = new Polyline();
-
-                for (int m=0; m < NumParts; m++) {
-                    xpnt = rf.getDouble();
-                    ypnt = rf.getDouble();
-                    ply.startPath(xpnt, ypnt);
-
-                    for (int j=NumPartArr[m]; j < NumPartArr[m+1] - 1; j++) {
-                        xpnt = rf.getDouble();
-                        ypnt = rf.getDouble();
-                        ply.lineTo(xpnt, ypnt);
-                    }
-                }
+    /**
+     * Read the next row as a set of objects.
+     * @return Map of field name / object value.
+     */
+    public HashMap<String, Object> readNextRowAsObjects() {
+        // TODO: ignore deleted records
+        df.get(); // denotes whether deleted or current
+        // read first part of record
+
+        HashMap<String, Object> fieldsValues = new HashMap<>();
+
+        for (FieldDescriptor fd : this.fieldsDescriptors) {
+            byte[] data = new byte[fd.getLength()];
+            df.get(data);
+
+            int length = data.length;
+            while (length != 0 && data[length - 1] <= ' ') {
+                length--;
+            }
 
-                f.setPropertyValue(GEOMETRY_NAME, ply);
+            String value = new String(data, 0, length);
+            fieldsValues.put(fd.getName(), value);
+        }
 
-            } else {
-                throw new DataStoreException("Unsupported shapefile type: " + this.ShapeType);
-            }
+        rowNum ++;
+        return fieldsValues;
+    }
 
-            rf.order(ByteOrder.BIG_ENDIAN);
-            // read in each Record and Populate the Feature
+    /**
+     * Return the current row number red.
+     * @return Row number (zero based) or -1 if reading has not started.
+     */
+    public int getRowNum() {
+        return rowNum;
+    }
 
-            // TODO: ignore deleted records
-            df.get(); // denotes whether deleted or current
-            // read first part of record
-
-            for (FieldDescriptor fd: this.FDArray) {
-                data = new byte[fd.getLength()];
-                df.get(data);
-                int length = data.length;
-                while (length != 0 && data[length - 1] <= ' ') {
-                    length--;
-                }
-                String value = new String(data, 0, length);
-                f.setPropertyValue(fd.getName(), value);
+    /**
+     * Load a row into a feature.
+     * @param feature Feature to fill.
+     */
+    public void loadRowIntoFeature(Feature feature) {
+        // TODO: ignore deleted records
+        df.get(); // denotes whether deleted or current
+        // read first part of record
+
+        for (FieldDescriptor fd : this.fieldsDescriptors) {
+            byte[] data = new byte[fd.getLength()];
+            df.get(data);
+
+            int length = data.length;
+            while (length != 0 && data[length - 1] <= ' ') {
+                length--;
             }
 
-            this.FeatureMap.put(RecordNumber, f);
+            String value = new String(data, 0, length);
+            feature.setPropertyValue(fd.getName(), value);
         }
 
-        fc.close();
-        fc2.close();
-        fis.close();
-        fis2.close();
+        rowNum ++;
     }
 
-    private DefaultFeatureType getFeatureType(final String name) {
-        final int n = FDArray.size();
-        final DefaultAttributeType<?>[] attributes = new DefaultAttributeType<?>[n
+ 1];
-        final Map<String,Object> properties = new HashMap<>(4);
-        for (int i=0; i<n; i++) {
-            properties.put(DefaultAttributeType.NAME_KEY, FDArray.get(i).getName());
-            attributes[i] = new DefaultAttributeType<>(properties, String.class, 1,
1, null);
-        }
-        properties.put(DefaultAttributeType.NAME_KEY, GEOMETRY_NAME);
-        attributes[n] = new DefaultAttributeType<>(properties, Geometry.class, 1, 1,
null);
-        properties.put(DefaultAttributeType.NAME_KEY, name);
-        return new DefaultFeatureType(properties, false, null, attributes);
+    /**
+     * Create a field descriptor from the current position of the binary stream.
+     * @return FieldDescriptor or null if there is no more available.
+     */
+    private FieldDescriptor toFieldDescriptor() {
+        // If there is no more field description available, return null.
+        if (df.position() >= this.DbaseHeaderBytes - 1)
+            return null;
+
+        FieldDescriptor fd = new FieldDescriptor();
+
+        // Field name.
+        df.get(fd.FieldName);
+
+        // Field type.
+        char dt = (char) df.get();
+        fd.FieldType = DataType.valueOfDataType(dt);
+
+        // Field address.
+        df.get(fd.FieldAddress);
+
+        // Length and scale.
+        fd.FieldLength = df.get();
+        fd.FieldDecimalCount = df.get();
+
+        df.getShort(); // reserved
+
+        df.get(fd.DbasePlusLanReserved2);
+
+        // Work area id.
+        fd.WorkAreaID = df.get();
+
+        df.get(fd.DbasePlusLanReserved3);
+
+        // Fields.
+        fd.SetFields = df.get();
+
+        byte[] data = new byte[6];
+        df.get(data); // reserved
+
+        return (fd);
+    }
+
+    /**
+     * @see java.lang.AutoCloseable#close()
+     */
+    @Override
+    public void close() throws IOException {
+        if (fc != null)
+            fc.close();
+
+        if (fis != null)
+            fis.close();
+
+        isClosed = true;
+    }
+
+    /**
+     * Determines if the database is closed.
+     * @return true if it is closed.
+     */
+    public boolean isClosed() {
+        return isClosed;
     }
 
+    /**
+     * @see java.lang.Object#toString()
+     */
     @Override
     public String toString() {
         StringBuilder s = new StringBuilder();
         String lineSeparator = System.getProperty("line.separator", "\n");
 
-        s.append("FileCode: ").append(FileCode).append(lineSeparator);
-        s.append("FileLength: ").append(FileLength).append(lineSeparator);
-        s.append("Version: ").append(Version).append(lineSeparator);
-        s.append("ShapeType: ").append(ShapeType).append(lineSeparator);
-        s.append("xmin: ").append(xmin).append(lineSeparator);
-        s.append("ymin: ").append(ymin).append(lineSeparator);
-        s.append("xmax: ").append(xmax).append(lineSeparator);
-        s.append("ymax: ").append(ymax).append(lineSeparator);
-        s.append("zmin: ").append(zmin).append(lineSeparator);
-        s.append("zmax: ").append(zmax).append(lineSeparator);
-        s.append("mmin: ").append(mmin).append(lineSeparator);
-        s.append("mmax: ").append(mmax).append(lineSeparator);
-        s.append("------------------------").append(lineSeparator);
         s.append("DbaseVersion: ").append(DbaseVersion).append(lineSeparator);
         s.append("DbaseLastUpdate: ").append(new String(DbaseLastUpdate)).append(lineSeparator);
-        s.append("FeatureCount: ").append(FeatureCount).append(lineSeparator);
+        s.append("FeatureCount: ").append(recordCount).append(lineSeparator);
         s.append("DbaseHeaderBytes: ").append(DbaseHeaderBytes).append(lineSeparator);
         s.append("DbaseRecordBytes: ").append(DbaseRecordBytes).append(lineSeparator);
         s.append("DbasePlusLanReserved: ").append(DbasePlusLanReserved).append(lineSeparator);

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/FieldDescriptor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/FieldDescriptor.java?rev=1631785&r1=1631784&r2=1631785&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/FieldDescriptor.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/FieldDescriptor.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -18,26 +18,42 @@ package org.apache.sis.storage.shapefile
 
 
 /**
- *
+ * Field descriptor.
  * @author  Travis L. Pinney
  * @since   0.4
  * @version 0.4
  * @module
  */
 public class FieldDescriptor {
-
+    /** Field name. */
     public byte[] FieldName = new byte[11];
+
+    /** Field type. */
     public DataType FieldType;
+
     public byte[] FieldAddress = new byte[4];
+
+    /** Field length. */
     public byte FieldLength;
+
+    /** Decimal count. */
     public byte FieldDecimalCount;
+
+    /** Reserved 2. */
     public byte[] DbasePlusLanReserved2 = new byte[2];
+
+    /** Work area id. */
     public byte WorkAreaID;
-    public byte[] DbasePlusLanReserved3 = new byte[2];
-    public byte SetFields;
 
+    /** Reserved 3. */
+    public byte[] DbasePlusLanReserved3 = new byte[2];
 
+    public byte SetFields;
 
+    /**
+     * Return the field name.
+     * @return Field name.
+     */
     public String getName() {
         int length = FieldName.length;
         while (length != 0 && FieldName[length - 1] <= ' ') {
@@ -46,10 +62,17 @@ public class FieldDescriptor {
         return new String(this.FieldName, 0, length);
     }
 
+    /**
+     * Return the field length.
+     * @return field length.
+     */
     public int getLength() {
         return Byte.toUnsignedInt(this.FieldLength);
     }
 
+    /**
+     * @see java.lang.Object#toString()
+     */
     @Override
     public String toString() {
 

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java?rev=1631785&r1=1631784&r2=1631785&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/ShapeFile.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -21,9 +21,10 @@ import java.nio.ByteOrder;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
 import java.io.FileInputStream;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+import java.text.MessageFormat;
 import com.esri.core.geometry.Point;
 import com.esri.core.geometry.Polygon;
 import com.esri.core.geometry.Polyline;
@@ -36,12 +37,11 @@ import org.apache.sis.storage.DataStoreE
 // Branch-dependent imports
 import org.opengis.feature.Feature;
 
-
 /**
  * Provides a ShapeFile Reader.
  *
- * @author  Travis L. Pinney
- * @since   0.5
+ * @author Travis L. Pinney
+ * @since 0.5
  * @version 0.5
  * @module
  *
@@ -49,232 +49,285 @@ import org.opengis.feature.Feature;
  * @see <a href="http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm">dBASE
III File Structure</a>
  */
 public class ShapeFile {
+    /** Name of the Geometry field. */
     private static final String GEOMETRY_NAME = "geometry";
 
-    public int FileCode;   // big
-    public int FileLength;  // big // The value for file length is the total length of the
file in 16-bit words
+    /** File code. */
+    public int FileCode; // big
+
+    /** File length. */
+    public int FileLength; // big // The value for file length is the total length of the
file in 16-bit words
+
+    /** File version. */
     public int Version; // little
+
+    /** Shapefile type. */
     public ShapeTypeEnum ShapeType; // little
+
+    /** X Min. */
     public double xmin; // little
+
+    /** Y Min. */
     public double ymin; // little
+
+    /** X Max. */
     public double xmax; // little
+
+    /** Y Max. */
     public double ymax; // little
+
+    /** Z Min. */
     public double zmin; // little
+
+    /** Z Max. */
     public double zmax; // little
+
+    /** M Min. */
     public double mmin; // little
+
+    /** M Max. */
     public double mmax; // little
 
+    /** Underlying databasefile content. */
+    private Database dbf;
 
-    // http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm
-    public byte DbaseVersion;
-    public byte[] DbaseLastUpdate = new byte[3];
-    public int FeatureCount;
-    public short DbaseHeaderBytes;
-    public short DbaseRecordBytes;
-    // reserve 3 bytes
-    public byte[] DbasePlusLanReserved = new byte[13];
-    // reserve 4 bytes
+    /** Features existing in the shapefile. */
+    public Map<Integer, Feature> FeatureMap = new HashMap<>();
 
-    public ArrayList<FieldDescriptor> FDArray = new ArrayList<FieldDescriptor>();
-    public Map<Integer, Feature> FeatureMap = new HashMap<Integer, Feature>();
+    /**
+     * Construct a Shapefile from a file.
+     * @param shpfile file to read.
+     * @throws IOException if the file cannot be opened.
+     * @throws DataStoreException if the shapefile is not valid.
+     */
+    public ShapeFile(String shpfile) throws IOException, DataStoreException {
+        Objects.requireNonNull(shpfile, "The shapefile to load cannot be null.");
 
+        // Deduct database file name.
+        StringBuilder b = new StringBuilder(shpfile);
+        b.replace(shpfile.length() - 3, shpfile.length(), "dbf");
 
+        dbf = new Database(b.toString());
 
-    public ShapeFile(String shpfile) throws IOException, DataStoreException {
-        FileInputStream fis = new FileInputStream(shpfile);
-        FileChannel fc = fis.getChannel();
-        int fsize = (int) fc.size();
-        MappedByteBuffer rf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
-
-        this.FileCode = rf.getInt();
-        rf.getInt(); rf.getInt(); rf.getInt(); rf.getInt(); rf.getInt();
-        this.FileLength = rf.getInt() * 2;
-
-        byte [] data = new byte[4];
-
-        rf.order(ByteOrder.LITTLE_ENDIAN);
-        this.Version = rf.getInt();
-        this.ShapeType = ShapeTypeEnum.get(rf.getInt());
-        this.xmin = rf.getDouble();
-        this.ymin = rf.getDouble();
-        this.xmax = rf.getDouble();
-        this.ymax = rf.getDouble();
-        this.zmin = rf.getDouble();
-        this.zmax = rf.getDouble();
-        this.mmin = rf.getDouble();
-        this.mmax = rf.getDouble();
-        rf.order(ByteOrder.BIG_ENDIAN);
+        try (FileInputStream fis = new FileInputStream(shpfile); FileChannel fc = fis.getChannel();)
{
+            int fsize = (int) fc.size();
+            MappedByteBuffer rf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fsize);
+
+            this.FileCode = rf.getInt();
+            rf.getInt();
+            rf.getInt();
+            rf.getInt();
+            rf.getInt();
+            rf.getInt();
+            this.FileLength = rf.getInt() * 2;
 
-        StringBuilder b = new StringBuilder(shpfile);
-        b.replace(shpfile.length() - 3, shpfile.length() , "dbf");
-        String file_base = b.toString();
+            rf.order(ByteOrder.LITTLE_ENDIAN);
+            this.Version = rf.getInt();
+            this.ShapeType = ShapeTypeEnum.get(rf.getInt());
+            this.xmin = rf.getDouble();
+            this.ymin = rf.getDouble();
+            this.xmax = rf.getDouble();
+            this.ymax = rf.getDouble();
+            this.zmin = rf.getDouble();
+            this.zmax = rf.getDouble();
+            this.mmin = rf.getDouble();
+            this.mmax = rf.getDouble();
+            rf.order(ByteOrder.BIG_ENDIAN);
 
-        FileInputStream fis2 = new FileInputStream(file_base);
-        FileChannel fc2 = fis2.getChannel();
-        int fsize2 = (int) fc2.size();
-        MappedByteBuffer df = fc2.map(FileChannel.MapMode.READ_ONLY, 0, fsize2);
-
-        this.DbaseVersion = df.get();
-        df.get(this.DbaseLastUpdate);
-
-        df.order(ByteOrder.LITTLE_ENDIAN);
-        this.FeatureCount = df.getInt();
-        this.DbaseHeaderBytes = df.getShort();
-        this.DbaseRecordBytes = df.getShort();
-        df.order(ByteOrder.BIG_ENDIAN);
-        df.getShort(); // reserved
-        df.get(); // reserved
-        df.get(DbasePlusLanReserved);
-        df.getInt();
-
-        while(df.position() <  this.DbaseHeaderBytes - 1) {
-            FieldDescriptor fd = new FieldDescriptor();
-            df.get(fd.FieldName);
-            char dt = (char) df.get();
-            fd.FieldType = DataType.valueOfDataType(dt);
-            df.get(fd.FieldAddress);
-            fd.FieldLength = df.get();
-            fd.FieldDecimalCount = df.get();
-            df.getShort(); // reserved
-            df.get(fd.DbasePlusLanReserved2);
-            fd.WorkAreaID = df.get();
-            df.get(fd.DbasePlusLanReserved3);
-            fd.SetFields = df.get();
-            data = new byte[6];
-            df.get(data); // reserved
+            dbf.loadDescriptor();
+            final DefaultFeatureType featureType = getFeatureType(shpfile);
 
-            this.FDArray.add(fd);
-            // loop until you hit the 0Dh field terminator
+            dbf.getByteBuffer().get(); // should be 0d for field terminator
+            loadFeatures(featureType, rf);
+        } finally {
+            dbf.close();
         }
-        final DefaultFeatureType featureType = getFeatureType(shpfile);
+    }
 
-        df.get(); // should be 0d for field terminator
+    /**
+     * Returns the underlying database file.
+     * @return Underlying database file.
+     */
+    public Database getDatabase() {
+        return this.dbf;
+    }
+
+    /**
+     * Returns the feature count of the shapefile.
+     * @return Feature count.
+     */
+    public int getFeatureCount() {
+        return this.dbf.getRecordCount();
+    }
 
-        for (Integer i = 0; i < this.FeatureCount; i++) {
+    /**
+     * Load the features of a shapefile.
+     * @param featureType Features descriptor.
+     * @param rf byte buffer mapper.
+     * @throws DataStoreException if a validation problem occurs.
+     */
+    private void loadFeatures(DefaultFeatureType featureType, MappedByteBuffer rf) throws
DataStoreException {
+        for (Integer i = 0; i < this.dbf.getRecordCount(); i++) {
             // insert points into some type of list
             int RecordNumber = rf.getInt();
+            @SuppressWarnings("unused")
             int ContentLength = rf.getInt();
 
-            data = new byte[4];
             rf.order(ByteOrder.LITTLE_ENDIAN);
-            int ShapeType = rf.getInt();
+            int iShapeType = rf.getInt();
             final Feature f = featureType.newInstance();
 
-            if (ShapeType == ShapeTypeEnum.Point.getValue()) {
-                double x = rf.getDouble();
-                double y = rf.getDouble();
-                Point pnt = new Point(x,y);
-                f.setPropertyValue(GEOMETRY_NAME, pnt);
-
-            } else if (ShapeType == ShapeTypeEnum.Polygon.getValue()) {
-                double xmin = rf.getDouble();
-                double ymin = rf.getDouble();
-                double xmax = rf.getDouble();
-                double ymax = rf.getDouble();
-                int NumParts = rf.getInt();
-                int NumPoints = rf.getInt();
-
-                if (NumParts > 1) {
-                    throw new DataStoreException("Polygons with multiple linear rings have
not implemented yet.");
-                }
-
-                // read the one part
-                int Part = rf.getInt();
-                Polygon poly = new Polygon();
-
-                // create a line from the points
-                double xpnt = rf.getDouble();
-                double ypnt = rf.getDouble();
-                //Point oldpnt = new Point(xpnt, ypnt);
-                poly.startPath(xpnt, ypnt);
-                for (int j=0; j < NumPoints-1; j++) {
-                    xpnt = rf.getDouble();
-                    ypnt = rf.getDouble();
-                    poly.lineTo(xpnt, ypnt);
-                }
-                f.setPropertyValue(GEOMETRY_NAME, poly);
-
-            } else if (ShapeType == ShapeTypeEnum.PolyLine.getValue()) {
-                double xmin = rf.getDouble();
-                double ymin = rf.getDouble();
-                double xmax = rf.getDouble();
-                double ymax = rf.getDouble();
-
-                int NumParts = rf.getInt();
-                int NumPoints = rf.getInt();
-
-                int [] NumPartArr = new int[NumParts+1];
-
-                for (int n=0; n < NumParts; n++) {
-                    int idx = rf.getInt();
-                    NumPartArr[n] = idx;
-                }
-                NumPartArr[NumParts] = NumPoints;
-
-                data = new byte[8];
-
-                double xpnt, ypnt;
-                Polyline ply = new Polyline();
-
-                for (int m=0; m < NumParts; m++) {
-                    xpnt = rf.getDouble();
-                    ypnt = rf.getDouble();
-                    ply.startPath(xpnt, ypnt);
-
-                    for (int j=NumPartArr[m]; j < NumPartArr[m+1] - 1; j++) {
-                        xpnt = rf.getDouble();
-                        ypnt = rf.getDouble();
-                        ply.lineTo(xpnt, ypnt);
-                    }
-                }
+            ShapeTypeEnum type = ShapeTypeEnum.get(iShapeType);
 
-                f.setPropertyValue(GEOMETRY_NAME, ply);
+            if (type == null)
+                throw new DataStoreException(MessageFormat.format("The shapefile feature
type {0} doesn''t match to any known feature type.", featureType));
 
-            } else {
-                throw new DataStoreException("Unsupported shapefile type: " + this.ShapeType);
+            switch (type) {
+            case Point:
+                loadPointFeature(rf, f);
+                break;
+
+            case Polygon:
+                loadPolygonFeature(rf, f);
+                break;
+
+            case PolyLine:
+                loadPolylineFeature(rf, f);
+                break;
+
+            default:
+                throw new DataStoreException("Unsupported shapefile type: " + iShapeType);
             }
 
             rf.order(ByteOrder.BIG_ENDIAN);
             // read in each Record and Populate the Feature
 
-            // TODO: ignore deleted records
-            df.get(); // denotes whether deleted or current
-            // read first part of record
-
-            for (FieldDescriptor fd: this.FDArray) {
-                data = new byte[fd.getLength()];
-                df.get(data);
-                int length = data.length;
-                while (length != 0 && data[length - 1] <= ' ') {
-                    length--;
-                }
-                String value = new String(data, 0, length);
-                f.setPropertyValue(fd.getName(), value);
-            }
+            dbf.loadRowIntoFeature(f);
 
             this.FeatureMap.put(RecordNumber, f);
         }
+    }
+
+    /**
+     * Load point feature.
+     * @param rf Byte buffer.
+     * @param feature Feature to fill.
+     */
+    private void loadPointFeature(MappedByteBuffer rf, Feature feature) {
+        double x = rf.getDouble();
+        double y = rf.getDouble();
+        Point pnt = new Point(x, y);
+        feature.setPropertyValue(GEOMETRY_NAME, pnt);
+    }
+
+    /**
+     * Load polygon feature.
+     * @param rf Byte buffer.
+     * @param feature Feature to fill.
+     * @throws DataStoreException if the polygon cannot be handled.
+     */
+    private void loadPolygonFeature(MappedByteBuffer rf, Feature feature) throws DataStoreException
{
+        /* double xmin = */rf.getDouble();
+        /* double ymin = */rf.getDouble();
+        /* double xmax = */rf.getDouble();
+        /* double ymax = */rf.getDouble();
+        int NumParts = rf.getInt();
+        int NumPoints = rf.getInt();
+
+        if (NumParts > 1) {
+            throw new DataStoreException("Polygons with multiple linear rings have not implemented
yet.");
+        }
+
+        // read the one part
+        @SuppressWarnings("unused")
+        int Part = rf.getInt();
+        Polygon poly = new Polygon();
+
+        // create a line from the points
+        double xpnt = rf.getDouble();
+        double ypnt = rf.getDouble();
+        // Point oldpnt = new Point(xpnt, ypnt);
+        poly.startPath(xpnt, ypnt);
+
+        for (int j = 0; j < NumPoints - 1; j++) {
+            xpnt = rf.getDouble();
+            ypnt = rf.getDouble();
+            poly.lineTo(xpnt, ypnt);
+        }
+
+        feature.setPropertyValue(GEOMETRY_NAME, poly);
+    }
+
+    /**
+     * Load polyline feature.
+     * @param rf Byte buffer.
+     * @param feature Feature to fill.
+     */
+    private void loadPolylineFeature(MappedByteBuffer rf, Feature feature) {
+        /* double xmin = */rf.getDouble();
+        /* double ymin = */rf.getDouble();
+        /* double xmax = */rf.getDouble();
+        /* double ymax = */rf.getDouble();
+
+        int NumParts = rf.getInt();
+        int NumPoints = rf.getInt();
+
+        int[] NumPartArr = new int[NumParts + 1];
+
+        for (int n = 0; n < NumParts; n++) {
+            int idx = rf.getInt();
+            NumPartArr[n] = idx;
+        }
+        NumPartArr[NumParts] = NumPoints;
 
-        fc.close();
-        fc2.close();
-        fis.close();
-        fis2.close();
+        double xpnt, ypnt;
+        Polyline ply = new Polyline();
+
+        for (int m = 0; m < NumParts; m++) {
+            xpnt = rf.getDouble();
+            ypnt = rf.getDouble();
+            ply.startPath(xpnt, ypnt);
+
+            for (int j = NumPartArr[m]; j < NumPartArr[m + 1] - 1; j++) {
+                xpnt = rf.getDouble();
+                ypnt = rf.getDouble();
+                ply.lineTo(xpnt, ypnt);
+            }
+        }
+
+        feature.setPropertyValue(GEOMETRY_NAME, ply);
     }
 
+    /**
+     * Create a feature descriptor.
+     * @param name Name of the field.
+     * @return The feature type.
+     */
     private DefaultFeatureType getFeatureType(final String name) {
-        final int n = FDArray.size();
+        Objects.requireNonNull(name, "The feature name cannot be null.");
+
+        final int n = dbf.getFieldsDescriptor().size();
         final DefaultAttributeType<?>[] attributes = new DefaultAttributeType<?>[n
+ 1];
-        final Map<String,Object> properties = new HashMap<>(4);
-        for (int i=0; i<n; i++) {
-            properties.put(DefaultAttributeType.NAME_KEY, FDArray.get(i).getName());
+        final Map<String, Object> properties = new HashMap<>(4);
+
+        // Load data field.
+        for (int i = 0; i < n; i++) {
+            properties.put(DefaultAttributeType.NAME_KEY, dbf.getFieldsDescriptor().get(i).getName());
             attributes[i] = new DefaultAttributeType<>(properties, String.class, 1,
1, null);
         }
+
+        // Add geometry field.
         properties.put(DefaultAttributeType.NAME_KEY, GEOMETRY_NAME);
         attributes[n] = new DefaultAttributeType<>(properties, Geometry.class, 1, 1,
null);
+
+        // Add name.
         properties.put(DefaultAttributeType.NAME_KEY, name);
         return new DefaultFeatureType(properties, false, null, attributes);
     }
 
+    /**
+     * @see java.lang.Object#toString()
+     */
     @Override
     public String toString() {
         StringBuilder s = new StringBuilder();
@@ -293,12 +346,7 @@ public class ShapeFile {
         s.append("mmin: ").append(mmin).append(lineSeparator);
         s.append("mmax: ").append(mmax).append(lineSeparator);
         s.append("------------------------").append(lineSeparator);
-        s.append("DbaseVersion: ").append(DbaseVersion).append(lineSeparator);
-        s.append("DbaseLastUpdate: ").append(new String(DbaseLastUpdate)).append(lineSeparator);
-        s.append("FeatureCount: ").append(FeatureCount).append(lineSeparator);
-        s.append("DbaseHeaderBytes: ").append(DbaseHeaderBytes).append(lineSeparator);
-        s.append("DbaseRecordBytes: ").append(DbaseRecordBytes).append(lineSeparator);
-        s.append("DbasePlusLanReserved: ").append(DbasePlusLanReserved).append(lineSeparator);
+        s.append(dbf.toString());
 
         return s.toString();
     }

Added: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java?rev=1631785&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
(added)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * Shapefile.
+ *
+ * @author Travis L. Pinney
+ * @author Marc Le Bihan
+ */
+package org.apache.sis.storage.shapefile;

Propchange: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java?rev=1631785&r1=1631784&r2=1631785&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/test/java/org/apache/sis/storage/shapefile/ShapeFileTest.java
[UTF-8] Tue Oct 14 15:21:30 2014
@@ -34,25 +34,49 @@ import static org.junit.Assert.*;
  * @module
  */
 public final strictfp class ShapeFileTest extends TestCase {
-    private static String path(final String name) throws IOException, URISyntaxException
{
+    /**
+     * Returns URI path to a resource.
+     * @param name Resource name.
+     * @return URI path.
+     * @throws URISyntaxException if the resource name is incorrect.
+     */
+    private static String path(final String name) throws URISyntaxException {
         return new File(ShapeFileTest.class.getResource(name).toURI()).getPath();
     }
 
+    /**
+     * Test polylines count.
+     * @throws URISyntaxException if the resource name is incorrect.
+     * @throws IOException if the shapefile cannot be found or an I/O error occurs.
+     * @throws DataStoreException if the shapefile has a structure problem.
+     */
     @Test
     public void testPolyineCount() throws URISyntaxException, IOException, DataStoreException
{
         ShapeFile shp = new ShapeFile(path("SignedBikeRoute_4326_clipped.shp"));
-        assertEquals(shp.FeatureMap.size(), shp.FeatureCount);
+        assertEquals(shp.FeatureMap.size(), shp.getFeatureCount());
     }
 
-    @Test
-    public void testPolygonCount() throws URISyntaxException, IOException, DataStoreException
{
+    /**
+     * Test polygon count.
+     * @throws URISyntaxException if the resource name is incorrect.
+     * @throws IOException if the shapefile cannot be found or an I/O error occurs.
+     * @throws DataStoreException if the shapefile has a structure problem.
+     */
+     @Test
+     public void testPolygonCount() throws URISyntaxException, IOException, DataStoreException
{
         ShapeFile shp = new ShapeFile(path("ANC90Ply_4326.shp"));
-        assertEquals(shp.FeatureMap.size(), shp.FeatureCount);
+        assertEquals(shp.FeatureMap.size(), shp.getFeatureCount());
     }
 
-    @Test
-    public void testPointCount() throws URISyntaxException, IOException, DataStoreException
{
+     /**
+      * Test point count.
+      * @throws URISyntaxException if the resource name is incorrect.
+      * @throws IOException if the shapefile cannot be found or an I/O error occurs.
+      * @throws DataStoreException if the shapefile has a structure problem.
+      */
+     @Test
+     public void testPointCount() throws URISyntaxException, IOException, DataStoreException
{
         ShapeFile shp = new ShapeFile(path("ABRALicenseePt_4326_clipped.shp"));
-        assertEquals(shp.FeatureMap.size(), shp.FeatureCount);
+        assertEquals(shp.FeatureMap.size(), shp.getFeatureCount());
     }
 }



Mime
View raw message