Source Code Cross Referenced for ShapeFile.java in  » GIS » deegree » org » deegree » io » shpapi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » deegree » org.deegree.io.shpapi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/shpapi/ShapeFile.java $
0002:        /*----------------    FILE HEADER  ------------------------------------------
0003:
0004:         This file is part of deegree.
0005:         Copyright (C) 2001-2008 by:
0006:         EXSE, Department of Geography, University of Bonn
0007:         http://www.giub.uni-bonn.de/deegree/
0008:         lat/lon GmbH
0009:         http://www.lat-lon.de
0010:
0011:         This library is free software; you can redistribute it and/or
0012:         modify it under the terms of the GNU Lesser General Public
0013:         License as published by the Free Software Foundation; either
0014:         version 2.1 of the License, or (at your option) any later version.
0015:
0016:         This library is distributed in the hope that it will be useful,
0017:         but WITHOUT ANY WARRANTY; without even the implied warranty of
0018:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019:         Lesser General Public License for more details.
0020:
0021:         You should have received a copy of the GNU Lesser General Public
0022:         License along with this library; if not, write to the Free Software
0023:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0024:
0025:         Contact:
0026:
0027:         Andreas Poth
0028:         lat/lon GmbH
0029:         Aennchenstr. 19
0030:         53177 Bonn
0031:         Germany
0032:         E-Mail: poth@lat-lon.de
0033:
0034:         Prof. Dr. Klaus Greve
0035:         Department of Geography
0036:         University of Bonn
0037:         Meckenheimer Allee 166
0038:         53115 Bonn
0039:         Germany
0040:         E-Mail: greve@giub.uni-bonn.de
0041:
0042:        
0043:         ---------------------------------------------------------------------------*/
0044:        package org.deegree.io.shpapi;
0045:
0046:        import java.io.ByteArrayInputStream;
0047:        import java.io.IOException;
0048:        import java.util.ArrayList;
0049:        import java.util.Enumeration;
0050:        import java.util.Hashtable;
0051:        import java.util.List;
0052:        import java.util.Map;
0053:
0054:        import org.deegree.datatypes.Types;
0055:        import org.deegree.io.dbaseapi.DBaseException;
0056:        import org.deegree.io.dbaseapi.DBaseFile;
0057:        import org.deegree.io.dbaseapi.DBaseIndex;
0058:        import org.deegree.io.dbaseapi.DBaseIndexException;
0059:        import org.deegree.io.dbaseapi.FieldDescriptor;
0060:        import org.deegree.io.rtree.HyperBoundingBox;
0061:        import org.deegree.io.rtree.HyperPoint;
0062:        import org.deegree.io.rtree.RTree;
0063:        import org.deegree.io.rtree.RTreeException;
0064:        import org.deegree.model.feature.Feature;
0065:        import org.deegree.model.feature.FeatureCollection;
0066:        import org.deegree.model.feature.FeatureFactory;
0067:        import org.deegree.model.feature.FeatureProperty;
0068:        import org.deegree.model.feature.schema.FeatureType;
0069:        import org.deegree.model.feature.schema.GeometryPropertyType;
0070:        import org.deegree.model.feature.schema.PropertyType;
0071:        import org.deegree.model.spatialschema.ByteUtils;
0072:        import org.deegree.model.spatialschema.Curve;
0073:        import org.deegree.model.spatialschema.Envelope;
0074:        import org.deegree.model.spatialschema.Geometry;
0075:        import org.deegree.model.spatialschema.GeometryException;
0076:        import org.deegree.model.spatialschema.GeometryFactory;
0077:        import org.deegree.model.spatialschema.JTSAdapter;
0078:        import org.deegree.model.spatialschema.MultiCurve;
0079:        import org.deegree.model.spatialschema.MultiPoint;
0080:        import org.deegree.model.spatialschema.MultiSurface;
0081:        import org.deegree.model.spatialschema.Point;
0082:        import org.deegree.model.spatialschema.Position;
0083:        import org.deegree.model.spatialschema.Ring;
0084:        import org.deegree.model.spatialschema.Surface;
0085:        import org.deegree.model.spatialschema.SurfaceInterpolationImpl;
0086:
0087:        import com.vividsolutions.jts.algorithm.CGAlgorithms;
0088:
0089:        /**
0090:         * Class representing an ESRI Shape File.
0091:         * 
0092:         * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
0093:         * @author last edited by: $Author: apoth $
0094:         * 
0095:         * @version $Revision: 9342 $, $Date: 2007-12-27 04:32:57 -0800 (Thu, 27 Dec 2007) $
0096:         */
0097:        public class ShapeFile {
0098:
0099:            private DBaseFile dbf = null;
0100:
0101:            private SHP2WKS shpwks = new SHP2WKS();
0102:
0103:            /*
0104:             * contains the dBase indexes
0105:             */
0106:            private Hashtable<String, DBaseIndex> dBaseIndexes = new Hashtable<String, DBaseIndex>(
0107:                    50);
0108:
0109:            /*
0110:             * aggregated Instance-variables
0111:             */
0112:            private MainFile shp = null;
0113:
0114:            private RTree rti = null;
0115:
0116:            private String fileName = null;
0117:
0118:            /*
0119:             * indicates if a dBase-file is associated to the shape-file
0120:             */
0121:            private boolean hasDBaseFile = true;
0122:
0123:            /*
0124:             * indicates if an R-tree index is associated to the shape-file
0125:             */
0126:            private boolean hasRTreeIndex = true;
0127:
0128:            /**
0129:             * constructor: <BR>
0130:             * Construct a ShapeFile from a file name.<BR>
0131:             */
0132:            public ShapeFile(String fileName) throws IOException {
0133:                this .fileName = fileName;
0134:                /*
0135:                 * initialize the MainFile
0136:                 */
0137:                shp = new MainFile(fileName);
0138:
0139:                /*
0140:                 * initialize the DBaseFile
0141:                 */
0142:                try {
0143:                    dbf = new DBaseFile(fileName);
0144:                } catch (IOException e) {
0145:                    hasDBaseFile = false;
0146:                }
0147:
0148:                /*
0149:                 * initialize the RTreeIndex
0150:                 */
0151:                try {
0152:                    rti = new RTree(fileName + ".rti");
0153:                } catch (RTreeException e) {
0154:                    hasRTreeIndex = false;
0155:                }
0156:
0157:                if (hasDBaseFile) {
0158:                    String[] s = null;
0159:                    try {
0160:                        s = getProperties();
0161:                    } catch (Exception e) {
0162:                        e.printStackTrace();
0163:                    }
0164:                    for (int i = 0; i < s.length; i++) {
0165:                        try {
0166:                            dBaseIndexes.put(s[i], new DBaseIndex(fileName
0167:                                    + "$" + s[i]));
0168:                        } catch (IOException e) {
0169:                        }
0170:                    }
0171:                }
0172:            }
0173:
0174:            /**
0175:             * constructor: <BR>
0176:             * Construct a ShapeFile from a file name.<BR>
0177:             */
0178:            public ShapeFile(String url, String rwflag) throws IOException {
0179:                this .fileName = url;
0180:                shp = new MainFile(url, rwflag);
0181:                // TODO: initialize dbf, rti
0182:                hasDBaseFile = false;
0183:                hasRTreeIndex = false;
0184:            }
0185:
0186:            /**
0187:             * 
0188:             */
0189:            public void close() {
0190:
0191:                shp.close();
0192:                dbf.close();
0193:
0194:                if (rti != null) {
0195:                    try {
0196:                        rti.close();
0197:                    } catch (Exception e) {
0198:                        // should never happen
0199:                        e.printStackTrace();
0200:                    }
0201:                }
0202:
0203:                for (Enumeration e = dBaseIndexes.elements(); e
0204:                        .hasMoreElements();) {
0205:                    DBaseIndex index = (DBaseIndex) e.nextElement();
0206:
0207:                    try {
0208:                        index.close();
0209:                    } catch (Exception ex) {
0210:                    }
0211:                }
0212:            }
0213:
0214:            /**
0215:             * Overrides the default feature type (which is generated from all columns in the dbase file) to
0216:             * allow customized naming and ordering of properties.
0217:             * 
0218:             * @param ft
0219:             * @param ftMapping
0220:             */
0221:            public void setFeatureType(FeatureType ft,
0222:                    Map<PropertyType, String> ftMapping) {
0223:                dbf.setFeatureType(ft, ftMapping);
0224:            }
0225:
0226:            /**
0227:             * returns true if a column is indexed
0228:             */
0229:            public boolean hasDBaseIndex(String column) {
0230:                DBaseIndex index = dBaseIndexes.get(column);
0231:                return index != null;
0232:            }
0233:
0234:            /**
0235:             * returns true if a dBase-file is associated to the shape-file<BR>
0236:             */
0237:            public boolean hasDBaseFile() {
0238:                return this .hasDBaseFile;
0239:            }
0240:
0241:            /**
0242:             * returns true if an R-tree index is associated to the shape-file<BR>
0243:             */
0244:            public boolean hasRTreeIndex() {
0245:                return this .hasRTreeIndex;
0246:            }
0247:
0248:            /**
0249:             * returns the number of records within a shape-file<BR>
0250:             */
0251:            public int getRecordNum() {
0252:                return shp.getRecordNum();
0253:            }
0254:
0255:            /**
0256:             * returns the minimum bounding rectangle of all geometries<BR>
0257:             * within the shape-file
0258:             */
0259:            public Envelope getFileMBR() {
0260:                double xmin = shp.getFileMBR().west;
0261:                double xmax = shp.getFileMBR().east;
0262:                double ymin = shp.getFileMBR().south;
0263:                double ymax = shp.getFileMBR().north;
0264:
0265:                return GeometryFactory.createEnvelope(xmin, ymin, xmax, ymax,
0266:                        null);
0267:            }
0268:
0269:            /**
0270:             * returns the minimum bound rectangle of RecNo'th Geometrie<BR>
0271:             */
0272:            public Envelope getMBRByRecNo(int recNo) throws IOException {
0273:                SHPEnvelope shpenv = shp.getRecordMBR(recNo);
0274:                double xmin = shpenv.west;
0275:                double xmax = shpenv.east;
0276:                double ymin = shpenv.south;
0277:                double ymax = shpenv.north;
0278:
0279:                return GeometryFactory.createEnvelope(xmin, ymin, xmax, ymax,
0280:                        null);
0281:            }
0282:
0283:            /**
0284:             * Returns the given entry of the shape file as a {@link Feature} instance.
0285:             * <p>
0286:             * This contains the geometry as well as the attributes stored into the dbase file. The geometry
0287:             * property will use a default name (app:GEOM).
0288:             * 
0289:             * @param RecNo
0290:             * @return the given entry of the shape file as a Feature instance
0291:             * @throws IOException
0292:             * @throws HasNoDBaseFileException
0293:             * @throws DBaseException
0294:             */
0295:            public Feature getFeatureByRecNo(int RecNo) throws IOException,
0296:                    HasNoDBaseFileException, DBaseException {
0297:
0298:                if (!hasDBaseFile) {
0299:                    throw new HasNoDBaseFileException(
0300:                            "Exception: there is no dBase-file "
0301:                                    + "associated to this shape-file");
0302:                }
0303:
0304:                // get feature (without geometry property) from DBaseFile
0305:                Feature feature = dbf.getFRow(RecNo);
0306:
0307:                // exchange null geometries with real geometry
0308:                Geometry geo = getGeometryByRecNo(RecNo);
0309:                GeometryPropertyType[] geoPTs = feature.getFeatureType()
0310:                        .getGeometryProperties();
0311:                for (int i = 0; i < geoPTs.length; i++) {
0312:                    FeatureProperty[] geoProp = feature.getProperties(geoPTs[i]
0313:                            .getName());
0314:                    for (int j = 0; j < geoProp.length; j++) {
0315:                        geoProp[j].setValue(geo);
0316:                    }
0317:                }
0318:
0319:                return feature;
0320:            }
0321:
0322:            /**
0323:             * returns RecNo'th Geometrie<BR>
0324:             */
0325:            public Geometry getGeometryByRecNo(int recNo) throws IOException {
0326:                Geometry geom = null;
0327:
0328:                int shpType = getShapeTypeByRecNo(recNo);
0329:
0330:                if (shpType == ShapeConst.SHAPE_TYPE_POINT) {
0331:                    SHPPoint shppoint = (SHPPoint) shp.getByRecNo(recNo);
0332:                    geom = shpwks.transformPoint(null, shppoint);
0333:                } else if (shpType == ShapeConst.SHAPE_TYPE_MULTIPOINT) {
0334:                    SHPMultiPoint shpmultipoint = (SHPMultiPoint) shp
0335:                            .getByRecNo(recNo);
0336:                    Point[] points = shpwks.transformMultiPoint(null,
0337:                            shpmultipoint);
0338:                    if (points != null) {
0339:                        MultiPoint mp = GeometryFactory
0340:                                .createMultiPoint(points);
0341:                        geom = mp;
0342:                    } else {
0343:                        geom = null;
0344:                    }
0345:                } else if (shpType == ShapeConst.SHAPE_TYPE_POLYLINE) {
0346:                    SHPPolyLine shppolyline = (SHPPolyLine) shp
0347:                            .getByRecNo(recNo);
0348:                    Curve[] curves = shpwks
0349:                            .transformPolyLine(null, shppolyline);
0350:                    if ((curves != null) && (curves.length > 1)) {
0351:                        // create multi curve
0352:                        MultiCurve mc = GeometryFactory
0353:                                .createMultiCurve(curves);
0354:                        geom = mc;
0355:                    } else if ((curves != null) && (curves.length == 1)) {
0356:                        // single curve
0357:                        geom = curves[0];
0358:                    } else {
0359:                        geom = null;
0360:                    }
0361:                } else if (shpType == ShapeConst.SHAPE_TYPE_POLYGON) {
0362:                    SHPPolygon shppoly = (SHPPolygon) shp.getByRecNo(recNo);
0363:                    Surface[] polygons = shpwks.transformPolygon(null, shppoly);
0364:                    if ((polygons != null) && (polygons.length > 1)) {
0365:                        // create multi surface
0366:                        MultiSurface ms = GeometryFactory
0367:                                .createMultiSurface(polygons);
0368:                        geom = ms;
0369:                    } else if ((polygons != null) && (polygons.length == 1)) {
0370:                        geom = polygons[0];
0371:                    } else {
0372:                        geom = null;
0373:                    }
0374:                } else if (shpType == ShapeConst.SHAPE_TYPE_POLYGONZ) {
0375:
0376:                    SHPPolygon3D shppoly = (SHPPolygon3D) shp.getByRecNo(recNo);
0377:
0378:                    Surface[] polygons = shpwks.transformPolygon(null, shppoly);
0379:
0380:                    if ((polygons != null) && (polygons.length > 1)) {
0381:                        // create multi surface
0382:                        MultiSurface ms = GeometryFactory
0383:                                .createMultiSurface(polygons);
0384:                        geom = ms;
0385:                    } else if ((polygons != null) && (polygons.length == 1)) {
0386:                        geom = polygons[0];
0387:                    } else {
0388:                        geom = null;
0389:                    }
0390:                }
0391:
0392:                return geom;
0393:            }
0394:
0395:            /**
0396:             * returns the type of the RecNo'th Geometrie<BR>
0397:             * per definition a shape file contains onlay one shape type<BR>
0398:             * but null shapes are possible too!<BR>
0399:             */
0400:            public int getShapeTypeByRecNo(int RecNo) throws IOException {
0401:                return shp.getShapeTypeByRecNo(RecNo);
0402:            }
0403:
0404:            /**
0405:             * returns a int array that containts all the record numbers that matches the search operation
0406:             */
0407:            public int[] getGeoNumbersByAttribute(String column,
0408:                    Comparable value) throws IOException, DBaseIndexException {
0409:                DBaseIndex index = dBaseIndexes.get(column);
0410:
0411:                if (index == null) {
0412:                    return null;
0413:                }
0414:
0415:                return index.search(value);
0416:            }
0417:
0418:            /**
0419:             * returns a ArrayList that contains all geomeries of the shape file<BR>
0420:             * which mbr's are completly or partly within the rectangle r<BR>
0421:             * only Points, MultiPoints, PolyLines and Polygons are handled<BR>
0422:             */
0423:            public int[] getGeoNumbersByRect(Envelope r) throws IOException {
0424:                SHPPoint geom = null;
0425:                int[] num = null;
0426:                int numRecs = getRecordNum();
0427:
0428:                Envelope mbr = getFileMBR();
0429:
0430:                if (!mbr.intersects(r)) {
0431:                    return null;
0432:                }
0433:
0434:                if (hasRTreeIndex) {
0435:                    try {
0436:                        // translate envelope (deegree) to bounding box (rtree)
0437:                        HyperBoundingBox box = new HyperBoundingBox(
0438:                                new HyperPoint(r.getMin().getAsArray()),
0439:                                new HyperPoint(r.getMax().getAsArray()));
0440:                        Object[] iNumbers = rti.intersects(box);
0441:                        num = new int[iNumbers.length];
0442:
0443:                        for (int i = 0; i < iNumbers.length; i++)
0444:                            num[i] = ((Integer) iNumbers[i]).intValue();
0445:
0446:                        return num;
0447:                    } catch (Exception e) {
0448:                        e.printStackTrace();
0449:                    }
0450:                }
0451:
0452:                // for every geometry (record) within the shape file
0453:                // check if it's inside the search-rectangle r
0454:                List<Integer> numbers = new ArrayList<Integer>(500);
0455:                for (int i = 0; i < numRecs; i++) {
0456:                    if (getShapeTypeByRecNo(i + 1) == ShapeConst.SHAPE_TYPE_NULL) {
0457:                    } else if (getShapeTypeByRecNo(i + 1) == ShapeConst.SHAPE_TYPE_POINT) {
0458:                        geom = (SHPPoint) shp.getByRecNo(i + 1);
0459:
0460:                        // is the Point within the seach rectangle?
0461:                        Position pos = GeometryFactory.createPosition(geom.x,
0462:                                geom.y);
0463:
0464:                        if (r.contains(pos) == true) {
0465:                            numbers.add(new Integer(i + 1));
0466:                        }
0467:                    } else {
0468:                        // get minimum bounding rectangle of the i'th record
0469:                        mbr = getMBRByRecNo(i + 1);
0470:
0471:                        // is the i'th record a geometrie having a mbr
0472:                        // (only for PolyLines, Polygons and MultiPoints mbrs are defined)
0473:                        if (mbr != null) {
0474:                            // if the tested rectangles are not disjunct the number of the
0475:                            // actual record is added to the ArrayList
0476:                            if (mbr.intersects(r)) {
0477:                                numbers.add(new Integer(i + 1));
0478:                            }
0479:                        }
0480:                    }
0481:                }
0482:
0483:                if (numbers.size() > 0) {
0484:                    num = new int[numbers.size()];
0485:
0486:                    // put all numbers within numbers to an array
0487:                    for (int i = 0; i < numbers.size(); i++) {
0488:                        num[i] = numbers.get(i);
0489:                    }
0490:                }
0491:
0492:                return num;
0493:            } // end of getGeoNumbersByRect
0494:
0495:            /**
0496:             * is a property unique?
0497:             */
0498:            public boolean isUnique(String property) {
0499:                DBaseIndex index = dBaseIndexes.get(property);
0500:
0501:                if (index == null) {
0502:                    return false;
0503:                }
0504:
0505:                return index.isUnique();
0506:            }
0507:
0508:            /**
0509:             * returns the properties (column headers) of the dBase-file<BR>
0510:             * associated to the shape-file<BR>
0511:             */
0512:            public String[] getProperties() throws HasNoDBaseFileException,
0513:                    DBaseException {
0514:                if (!hasDBaseFile) {
0515:                    throw new HasNoDBaseFileException(
0516:                            "Exception: there is no dBase-file "
0517:                                    + "associated to this shape-file");
0518:                }
0519:
0520:                return dbf.getProperties();
0521:            }
0522:
0523:            /**
0524:             * returns the datatype of each column of the database file<BR>
0525:             * associated to the shape-file<BR>
0526:             */
0527:            public String[] getDataTypes() throws HasNoDBaseFileException,
0528:                    DBaseException {
0529:                if (!hasDBaseFile) {
0530:                    throw new HasNoDBaseFileException(
0531:                            "Exception: there is no dBase-file "
0532:                                    + "associated to this shape-file");
0533:                }
0534:
0535:                return dbf.getDataTypes();
0536:            }
0537:
0538:            /**
0539:             * 
0540:             * 
0541:             * @return
0542:             * 
0543:             * @throws HasNoDBaseFileException
0544:             * @throws DBaseException
0545:             */
0546:            public int[] getDataLengths() throws HasNoDBaseFileException,
0547:                    DBaseException {
0548:                String[] properties = getProperties();
0549:                int[] retval = new int[properties.length];
0550:
0551:                for (int i = 0; i < properties.length; i++) {
0552:                    retval[i] = dbf.getDataLength(properties[i]);
0553:                }
0554:
0555:                return retval;
0556:            }
0557:
0558:            /**
0559:             * returns the datatype of each column of the dBase associated<BR>
0560:             * to the shape-file specified by fields<BR>
0561:             */
0562:            public String[] getDataTypes(String[] fields)
0563:                    throws HasNoDBaseFileException, DBaseException {
0564:                if (!hasDBaseFile) {
0565:                    throw new HasNoDBaseFileException(
0566:                            "Exception: there is no dBase-file "
0567:                                    + "associated to this shape-file");
0568:                }
0569:
0570:                return dbf.getDataTypes(fields);
0571:            }
0572:
0573:            /**
0574:             * returns the number of geometries within a feature collection<BR>
0575:             * 
0576:             * @param fc :
0577:             *            featurecollection which is checked for the number geomtries<BR>
0578:             */
0579:            private int getGeometryCount(FeatureCollection fc) {
0580:                return fc.size();
0581:            }
0582:
0583:            /**
0584:             * returns the type of the n'th feature in a featurecollection
0585:             * 
0586:             * @param fc
0587:             *            FeatureCollection. must not be empty.
0588:             * @param n
0589:             *            number of the feature which should be examined starts with 0
0590:             */
0591:            private int getGeometryType(FeatureCollection fc, int n) {
0592:                Feature feature = null;
0593:
0594:                feature = fc.getFeature(n);
0595:
0596:                Geometry[] g = feature.getGeometryPropertyValues();
0597:
0598:                if ((g == null) || (g.length == 0)) {
0599:                    return -1;
0600:                }
0601:
0602:                if (g[0] instanceof  Point) {
0603:                    return 0;
0604:                }
0605:
0606:                if (g[0] instanceof  Curve) {
0607:                    return 1;
0608:                }
0609:
0610:                if (g[0] instanceof  Surface) {
0611:                    return 2;
0612:                }
0613:
0614:                if (g[0] instanceof  MultiPoint) {
0615:                    return 3;
0616:                }
0617:
0618:                if (g[0] instanceof  MultiCurve) {
0619:                    return 4;
0620:                }
0621:
0622:                if (g[0] instanceof  MultiSurface) {
0623:                    return 5;
0624:                }
0625:
0626:                return -1;
0627:            }
0628:
0629:            /**
0630:             * returns the n'th feature of a featurecollection as a Geometry<BR>
0631:             * 
0632:             * @param fc :
0633:             *            FeatureCollection<BR>
0634:             * @param n :
0635:             *            number of the feature which should be returned<BR>
0636:             */
0637:            private Geometry getFeatureAsGeometry(FeatureCollection fc, int n) {
0638:                Feature feature = null;
0639:
0640:                feature = fc.getFeature(n);
0641:
0642:                return feature.getGeometryPropertyValues()[0];
0643:            }
0644:
0645:            /**
0646:             */
0647:            public FeatureProperty[] getFeatureProperties(FeatureCollection fc,
0648:                    int n) {
0649:                Feature feature = null;
0650:
0651:                feature = fc.getFeature(n);
0652:
0653:                PropertyType[] ftp = feature.getFeatureType().getProperties();
0654:                FeatureProperty[] fp = new FeatureProperty[ftp.length];
0655:                FeatureProperty[] fp_ = feature.getProperties();
0656:
0657:                for (int i = 0; i < ftp.length; i++) {
0658:                    fp[i] = FeatureFactory.createFeatureProperty(ftp[i]
0659:                            .getName(), fp_[i].getValue());
0660:                }
0661:
0662:                return fp;
0663:            }
0664:
0665:            /**
0666:             */
0667:            private void initDBaseFile(FeatureCollection fc)
0668:                    throws DBaseException {
0669:                FieldDescriptor[] fieldDesc = null;
0670:
0671:                // get feature properties
0672:                FeatureProperty[] pairs = getFeatureProperties(fc, 0);
0673:
0674:                // count regular fields
0675:                int cnt = 0;
0676:                FeatureType featT = fc.getFeature(0).getFeatureType();
0677:                PropertyType[] ftp = featT.getProperties();
0678:                for (int i = 0; i < pairs.length; i++) {
0679:                    Object obj = pairs[i].getValue();
0680:
0681:                    if (obj instanceof  Object[]) {
0682:                        obj = ((Object[]) obj)[0];
0683:                    }
0684:                    if (!(obj instanceof  ByteArrayInputStream)
0685:                            && !(obj instanceof  Geometry)) {
0686:                        cnt++;
0687:                    }
0688:                }
0689:
0690:                // allocate memory for fielddescriptors
0691:                fieldDesc = new FieldDescriptor[cnt];
0692:
0693:                // get properties names and types and create a FieldDescriptor
0694:                // for each properties except the geometry-property
0695:                cnt = 0;
0696:                for (int i = 0; i < ftp.length; i++) {
0697:                    int pos = ftp[i].getName().getLocalName().lastIndexOf('.');
0698:                    if (pos < 0) {
0699:                        pos = -1;
0700:                    }
0701:                    String s = ftp[i].getName().getLocalName().substring(
0702:                            pos + 1);
0703:                    if (ftp[i].getType() == Types.INTEGER) {
0704:                        fieldDesc[cnt++] = new FieldDescriptor(s, "N",
0705:                                (byte) 20, (byte) 0);
0706:                    } else if (ftp[i].getType() == Types.BIGINT) {
0707:                        fieldDesc[cnt++] = new FieldDescriptor(s, "N",
0708:                                (byte) 30, (byte) 0);
0709:                    } else if (ftp[i].getType() == Types.SMALLINT) {
0710:                        fieldDesc[cnt++] = new FieldDescriptor(s, "N",
0711:                                (byte) 4, (byte) 0);
0712:                    } else if (ftp[i].getType() == Types.CHAR) {
0713:                        fieldDesc[cnt++] = new FieldDescriptor(s, "C",
0714:                                (byte) 1, (byte) 0);
0715:                    } else if (ftp[i].getType() == Types.FLOAT) {
0716:                        fieldDesc[cnt++] = new FieldDescriptor(s, "N",
0717:                                (byte) 30, (byte) 10);
0718:                    } else if (ftp[i].getType() == Types.DOUBLE
0719:                            || ftp[i].getType() == Types.NUMERIC) {
0720:                        fieldDesc[cnt++] = new FieldDescriptor(s, "N",
0721:                                (byte) 30, (byte) 10);
0722:                    } else if (ftp[i].getType() == Types.VARCHAR) {
0723:                        fieldDesc[cnt++] = new FieldDescriptor(s, "C",
0724:                                (byte) 127, (byte) 0);
0725:                    } else if (ftp[i].getType() == Types.DATE) {
0726:                        fieldDesc[cnt++] = new FieldDescriptor(s, "D",
0727:                                (byte) 12, (byte) 0);
0728:                    }
0729:                }
0730:
0731:                // initialize/create DBaseFile
0732:                try {
0733:                    dbf = new DBaseFile(fileName, fieldDesc);
0734:                } catch (DBaseException e) {
0735:                    hasDBaseFile = false;
0736:                }
0737:            }
0738:
0739:            /**
0740:             * writes a OGC FeatureCollection to a ESRI shape file.<BR>
0741:             * all features in the collection must have the same properties.<BR>
0742:             * 
0743:             * @param fc
0744:             *            FeatureCollection. must not be null or empty.
0745:             * @throws Exception
0746:             */
0747:            public void writeShape(FeatureCollection fc) throws Exception {
0748:
0749:                int nbyte = 0;
0750:                int geotype = -1;
0751:                byte shptype = -1;
0752:                int typ_ = getGeometryType(fc, 0);
0753:                byte[] bytearray = null;
0754:                IndexRecord record = null;
0755:                SHPEnvelope mbr = null;
0756:                // mbr of the whole shape file
0757:                SHPEnvelope shpmbr = new SHPEnvelope();
0758:
0759:                // Set the Offset to the end of the fileHeader
0760:                int offset = ShapeConst.SHAPE_FILE_HEADER_LENGTH;
0761:
0762:                // initialize the dbasefile associated with the shapefile
0763:                initDBaseFile(fc);
0764:
0765:                // loop throug the Geometries of the feature collection anf write them
0766:                // to a bytearray
0767:                for (int i = 0; i < getGeometryCount(fc); i++) {
0768:                    if (i % 1000 == 0) {
0769:                        System.gc();
0770:                    }
0771:                    // write i'th features properties to a ArrayList
0772:                    PropertyType[] ftp = fc.getFeature(0).getFeatureType()
0773:                            .getProperties();
0774:                    ArrayList<Object> vec = new ArrayList<Object>(ftp.length);
0775:                    for (int j = 0; j < ftp.length; j++) {
0776:                        if (ftp[j].getType() == Types.GEOMETRY)
0777:                            continue;
0778:                        FeatureProperty fp = fc.getFeature(i)
0779:                                .getDefaultProperty(ftp[j].getName());
0780:                        Object obj = null;
0781:                        if (fp != null) {
0782:                            obj = fp.getValue();
0783:                        }
0784:
0785:                        if (obj instanceof  Object[]) {
0786:                            obj = ((Object[]) obj)[0];
0787:                        }
0788:
0789:                        if ((ftp[j].getType() == Types.INTEGER)
0790:                                || (ftp[j].getType() == Types.BIGINT)
0791:                                || (ftp[j].getType() == Types.SMALLINT)
0792:                                || (ftp[j].getType() == Types.CHAR)
0793:                                || (ftp[j].getType() == Types.FLOAT)
0794:                                || (ftp[j].getType() == Types.DOUBLE)
0795:                                || (ftp[j].getType() == Types.NUMERIC)
0796:                                || (ftp[j].getType() == Types.VARCHAR)
0797:                                || (ftp[j].getType() == Types.DATE)) {
0798:                            vec.add(obj);
0799:                        }
0800:
0801:                    }
0802:
0803:                    // write the ArrayList (properties) to the dbase file
0804:                    try {
0805:                        dbf.setRecord(vec);
0806:                    } catch (DBaseException db) {
0807:                        db.printStackTrace();
0808:                        throw new Exception(db.toString());
0809:                    }
0810:
0811:                    // Get Geometry Type of i'th feature
0812:                    geotype = getGeometryType(fc, i);
0813:
0814:                    if (geotype < 0) {
0815:                        continue;
0816:                    }
0817:
0818:                    if ((typ_ == 0) || (typ_ == 3)) {
0819:                        if ((geotype != 0) && (geotype != 3)) {
0820:                            throw new Exception(
0821:                                    "Not a homogen FeatureCollection");
0822:                        }
0823:                    }
0824:
0825:                    if ((typ_ == 1) || (typ_ == 4)) {
0826:                        if ((geotype != 1) && (geotype != 4)) {
0827:                            throw new Exception(
0828:                                    "Not a homogen FeatureCollection");
0829:                        }
0830:                    }
0831:
0832:                    if ((typ_ == 2) || (typ_ == 5)) {
0833:                        if ((geotype != 2) && (geotype != 5)) {
0834:                            throw new Exception(
0835:                                    "Not a homogen FeatureCollection");
0836:                        }
0837:                    }
0838:
0839:                    // get wks geometrie for feature (i) and write it to a file
0840:                    if (geotype == 0) {
0841:                        // Geometrie Type = Point
0842:                        Point wks = (Point) getFeatureAsGeometry(fc, i);
0843:                        SHPPoint shppoint = new SHPPoint(wks.getPosition());
0844:                        nbyte = shppoint.size();
0845:                        bytearray = new byte[nbyte
0846:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0847:                        shppoint.writeSHPPoint(bytearray,
0848:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0849:                        mbr = new SHPEnvelope(shppoint, shppoint);
0850:
0851:                        if (i == 0) {
0852:                            shpmbr = mbr;
0853:                        }
0854:
0855:                        shptype = 1;
0856:                    } else if (geotype == 1) {
0857:                        // Geometrie Type = LineString
0858:                        Curve[] wks = new Curve[1];
0859:                        wks[0] = (Curve) getFeatureAsGeometry(fc, i);
0860:
0861:                        SHPPolyLine shppolyline = new SHPPolyLine(wks);
0862:                        nbyte = shppolyline.size();
0863:                        bytearray = new byte[nbyte
0864:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0865:                        shppolyline.writeSHPPolyLine(bytearray,
0866:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0867:                        mbr = shppolyline.getEnvelope();
0868:
0869:                        if (i == 0) {
0870:                            shpmbr = mbr;
0871:                        }
0872:
0873:                        shptype = 3;
0874:                    } else if (geotype == 2) {
0875:                        // Geometrie Type = Polygon
0876:                        Surface[] wks = new Surface[1];
0877:                        wks[0] = (Surface) getFeatureAsGeometry(fc, i);
0878:                        validateOrientation(wks);
0879:
0880:                        SHPPolygon shppolygon = new SHPPolygon(wks);
0881:                        nbyte = shppolygon.size();
0882:                        bytearray = new byte[nbyte
0883:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0884:                        shppolygon.writeSHPPolygon(bytearray,
0885:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0886:                        mbr = shppolygon.getEnvelope();
0887:
0888:                        if (i == 0) {
0889:                            shpmbr = mbr;
0890:                        }
0891:
0892:                        shptype = 5;
0893:                    } else if (geotype == 3) {
0894:                        // Geometrie Type = MultiPoint
0895:                        MultiPoint wks = (MultiPoint) getFeatureAsGeometry(fc,
0896:                                i);
0897:                        SHPMultiPoint shpmultipoint = new SHPMultiPoint(wks);
0898:                        nbyte = shpmultipoint.size();
0899:                        bytearray = new byte[nbyte
0900:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0901:                        shpmultipoint.writeSHPMultiPoint(bytearray,
0902:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0903:                        mbr = shpmultipoint.getEnvelope();
0904:                        shptype = 8;
0905:                    } else if (geotype == 4) {
0906:                        // Geometrie Type = MultiLineString
0907:                        MultiCurve wks = (MultiCurve) getFeatureAsGeometry(fc,
0908:                                i);
0909:                        SHPPolyLine shppolyline = new SHPPolyLine(wks
0910:                                .getAllCurves());
0911:                        nbyte = shppolyline.size();
0912:                        bytearray = new byte[nbyte
0913:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0914:                        shppolyline.writeSHPPolyLine(bytearray,
0915:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0916:                        mbr = shppolyline.getEnvelope();
0917:
0918:                        if (i == 0) {
0919:                            shpmbr = mbr;
0920:                        }
0921:
0922:                        shptype = 3;
0923:                    } else if (geotype == 5) {
0924:                        // Geometrie Type = MultiPolygon
0925:                        MultiSurface wks = (MultiSurface) getFeatureAsGeometry(
0926:                                fc, i);
0927:                        SHPPolygon shppolygon = new SHPPolygon(wks
0928:                                .getAllSurfaces());
0929:                        nbyte = shppolygon.size();
0930:                        bytearray = new byte[nbyte
0931:                                + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH];
0932:                        shppolygon.writeSHPPolygon(bytearray,
0933:                                ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0934:                        mbr = shppolygon.getEnvelope();
0935:
0936:                        if (i == 0) {
0937:                            shpmbr = mbr;
0938:                        }
0939:
0940:                        shptype = 5;
0941:                    }
0942:
0943:                    // write bytearray to the shape file
0944:                    record = new IndexRecord(offset / 2, nbyte / 2);
0945:
0946:                    // write recordheader to the bytearray
0947:                    ByteUtils.writeBEInt(bytearray, 0, i);
0948:                    ByteUtils.writeBEInt(bytearray, 4, nbyte / 2);
0949:
0950:                    // write record (bytearray) including recordheader to the shape file
0951:                    shp.write(bytearray, record, mbr);
0952:
0953:                    // actualise shape file minimum boundary rectangle
0954:                    if (mbr.west < shpmbr.west) {
0955:                        shpmbr.west = mbr.west;
0956:                    }
0957:
0958:                    if (mbr.east > shpmbr.east) {
0959:                        shpmbr.east = mbr.east;
0960:                    }
0961:
0962:                    if (mbr.south < shpmbr.south) {
0963:                        shpmbr.south = mbr.south;
0964:                    }
0965:
0966:                    if (mbr.north > shpmbr.north) {
0967:                        shpmbr.north = mbr.north;
0968:                    }
0969:
0970:                    // icrement offset for pointing at the end of the file
0971:                    offset += (nbyte + ShapeConst.SHAPE_FILE_RECORD_HEADER_LENGTH);
0972:
0973:                    bytearray = null;
0974:                }
0975:
0976:                dbf.writeAllToFile();
0977:
0978:                // write shape header
0979:                shp.writeHeader(offset, shptype, shpmbr);
0980:
0981:            }
0982:
0983:            private void validateOrientation(Surface[] wks)
0984:                    throws GeometryException {
0985:                com.vividsolutions.jts.geom.Geometry jts = JTSAdapter
0986:                        .export(wks[0]);
0987:                CGAlgorithms.isCCW(jts.getCoordinates());
0988:                if (CGAlgorithms.isCCW(jts.getCoordinates())) {
0989:                    Position[] pos = wks[0].getSurfaceBoundary()
0990:                            .getExteriorRing().getPositions();
0991:                    Position[] pos2 = new Position[pos.length];
0992:                    for (int j = 0; j < pos2.length; j++) {
0993:                        pos2[j] = pos[pos.length - j - 1];
0994:                    }
0995:                    Position[][] iPos = null;
0996:                    if (wks[0].getSurfaceBoundary().getInteriorRings() != null) {
0997:                        Ring[] rings = wks[0].getSurfaceBoundary()
0998:                                .getInteriorRings();
0999:                        iPos = new Position[rings.length][];
1000:                        for (int j = 0; j < rings.length; j++) {
1001:                            pos = rings[j].getPositions();
1002:                            iPos[j] = new Position[pos.length];
1003:                            for (int k = 0; k < pos.length; k++) {
1004:                                iPos[j][k] = pos[pos.length - k - 1];
1005:                            }
1006:                        }
1007:                    }
1008:                    wks[0] = GeometryFactory.createSurface(pos2, iPos,
1009:                            new SurfaceInterpolationImpl(), wks[0]
1010:                                    .getCoordinateSystem());
1011:                }
1012:            }
1013:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.