sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mlebi...@apache.org
Subject svn commit: r1713213 - /sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
Date Sun, 08 Nov 2015 09:03:37 GMT
Author: mlebihan
Date: Sun Nov  8 09:03:37 2015
New Revision: 1713213

URL: http://svn.apache.org/viewvc?rev=1713213&view=rev
Log:
Load multiple parts polygon from shapefile.

Modified:
    sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java

Modified: sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java?rev=1713213&r1=1713212&r2=1713213&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-shapefile/src/main/java/org/apache/sis/internal/shapefile/ShapefileByteReader.java
[UTF-8] Sun Nov  8 09:03:37 2015
@@ -21,12 +21,15 @@ import java.io.IOException;
 import java.nio.ByteOrder;
 import java.text.MessageFormat;
 import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.sis.feature.DefaultAttributeType;
 import org.apache.sis.feature.DefaultFeatureType;
 import org.apache.sis.internal.shapefile.jdbc.*;
 import org.apache.sis.storage.shapefile.InvalidShapefileFormatException;
 import org.apache.sis.storage.shapefile.ShapeTypeEnum;
+import org.apache.sis.util.logging.Logging;
 import org.opengis.feature.Feature;
 
 import com.esri.core.geometry.*;
@@ -204,40 +207,115 @@ public class ShapefileByteReader extends
     /**
      * Load polygon feature.
      * @param feature Feature to fill.
-     * @throws InvalidShapefileFormatException if the polygon cannot be handled.
      */
-    private void loadPolygonFeature(Feature feature) throws InvalidShapefileFormatException
{
+    private void loadPolygonFeature(Feature feature) {
         /* double xmin = */getByteBuffer().getDouble();
         /* double ymin = */getByteBuffer().getDouble();
         /* double xmax = */getByteBuffer().getDouble();
         /* double ymax = */getByteBuffer().getDouble();
-        int NumParts = getByteBuffer().getInt();
-        int NumPoints = getByteBuffer().getInt();
+        int numParts = getByteBuffer().getInt();
+        int numPoints = getByteBuffer().getInt();
 
-        if (NumParts > 1) {
-            throw new InvalidShapefileFormatException("Polygons with multiple linear rings
have not implemented yet.");
-        }
+        Polygon poly;
 
-        // read the one part
-        @SuppressWarnings("unused")
-        int Part = getByteBuffer().getInt();
+        // Handle multiple polygon parts.
+        if (numParts > 1) {
+            Logger log = Logging.getLogger(ShapefileByteReader.class.getName());
+            
+            if (log.isLoggable(Level.FINER)) {
+                String format = "Polygon with multiple linear rings encountered at position
{0,number} with {1,number} parts.";
+                String message = MessageFormat.format(format, getByteBuffer().position(),
numParts);
+                log.finer(message);
+            }
+            
+            poly = readMultiplePolygonParts(numParts, numPoints);
+        }
+        else {
+            // Polygon with an unique part.
+            poly = readUniquePolygonPart(numPoints);
+        }
+        
+        feature.setPropertyValue(GEOMETRY_NAME, poly);
+    }
+    
+    /**
+     * Read a polygon that has a unique part.
+     * @param numPoints Number of the points of the polygon.
+     * @return Polygon.
+     */
+    @Deprecated // As soon as the readMultiplePolygonParts method proofs working well, this
readUniquePolygonPart method can be removed and all calls be deferred to readMultiplePolygonParts.
+    private Polygon readUniquePolygonPart(int numPoints) {
+        int part = getByteBuffer().getInt();
+        
         Polygon poly = new Polygon();
 
         // create a line from the points
         double xpnt = getByteBuffer().getDouble();
         double ypnt = getByteBuffer().getDouble();
-        // Point oldpnt = new Point(xpnt, ypnt);
+
         poly.startPath(xpnt, ypnt);
 
-        for (int j = 0; j < NumPoints - 1; j++) {
+        for (int j = 0; j < numPoints - 1; j++) {
             xpnt = getByteBuffer().getDouble();
             ypnt = getByteBuffer().getDouble();
             poly.lineTo(xpnt, ypnt);
         }
-
-        feature.setPropertyValue(GEOMETRY_NAME, poly);
+        
+        return poly;
     }
+    
+    /**
+     * Read a polygon that has multiple parts.
+     * @param numParts Number of parts of this polygon.
+     * @param numPoints Total number of points of this polygon, all parts considered.
+     * @return a multiple part polygon.
+     */
+    private Polygon readMultiplePolygonParts(int numParts, int numPoints) {
+        /** 
+         * From ESRI Specification : 
+         * Parts : 0 5  (meaning : 0 designs the first v1, 5 designs the first v5 on the
points list below).
+         * Points : v1 v2 v3 v4 v1 v5 v8 v7 v6 v5
+         *
+         * POSITION  FIELD       VALUE      TYPE      NUMBER     ORDER
+         * Byte 0    Shape Type  5          Integer   1          Little
+         * Byte 4    Box         Box        Double    4          Little
+         * Byte 36   NumParts    NumParts   Integer   1          Little
+         * Byte 40   NumPoints   NumPoints  Integer   1          Little
+         * Byte 44   Parts       Parts      Integer   NumParts   Little
+         * Byte X    Points      Points     Point     NumPoints  Little        
+         */
+        int[] partsIndexes = new int[numParts];
+        
+        // Read all the parts indexes (starting at byte 44).
+        for(int index=0; index < numParts; index ++) {
+            partsIndexes[index] = getByteBuffer().getInt();
+        }
+
+        // Read all the points.
+        double[] xPoints = new double[numPoints];
+        double[] yPoints = new double[numPoints];
+
+        for(int index=0; index < numPoints; index ++) {
+            xPoints[index] = getByteBuffer().getDouble();
+            yPoints[index] = getByteBuffer().getDouble();
+        }
+        
+        // Create the polygon from the points.
+        Polygon poly = new Polygon();
 
+        // create a line from the points
+        for(int index=0; index < numPoints; index ++) {
+            if (index == 0) {
+                poly.startPath(xPoints[index], yPoints[index]);                
+            }
+            else {
+                poly.lineTo(xPoints[index], yPoints[index]);                
+            }
+        }
+        
+        return poly;
+    }
+    
     /**
      * Load polyline feature.
      * @param feature Feature to fill.



Mime
View raw message