001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.data.shapefile;
018:
019: import java.io.File;
020: import java.io.IOException;
021: import java.nio.channels.Channels;
022: import java.nio.channels.ReadableByteChannel;
023: import java.util.ArrayList;
024:
025: import org.geotools.data.DataStore;
026: import org.geotools.data.DataUtilities;
027: import org.geotools.data.FeatureSource;
028: import org.geotools.data.FeatureStore;
029: import org.geotools.data.shapefile.shp.IndexFile;
030: import org.geotools.data.shapefile.shp.ShapefileReader;
031: import org.geotools.feature.AttributeTypeFactory;
032: import org.geotools.feature.FeatureCollection;
033: import org.geotools.feature.FeatureCollections;
034: import org.geotools.feature.FeatureType;
035: import org.geotools.feature.FeatureTypeFactory;
036: import org.geotools.TestData;
037:
038: import com.vividsolutions.jts.geom.Envelope;
039: import com.vividsolutions.jts.geom.Geometry;
040:
041: /**
042: *
043: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/test/java/org/geotools/data/shapefile/ShapefileTest.java $
044: * @version $Id: ShapefileTest.java 22666 2006-11-09 03:50:28Z jgarnett $
045: * @author Ian Schneider
046: * @author James Macgill
047: */
048: public class ShapefileTest extends TestCaseSupport {
049:
050: final String STATEPOP = "shapes/statepop.shp";
051: final String STATEPOP_IDX = "shapes/statepop.shx";
052: final String POINTTEST = "shapes/pointtest.shp";
053: final String POLYGONTEST = "shapes/polygontest.shp";
054: final String HOLETOUCHEDGE = "shapes/holeTouchEdge.shp";
055: final String EXTRAATEND = "shapes/extraAtEnd.shp";
056:
057: public ShapefileTest(String testName) throws IOException {
058: super (testName);
059: }
060:
061: public void testLoadingStatePop() throws Exception {
062: loadShapes(STATEPOP, 49);
063: loadMemoryMapped(STATEPOP, 49);
064: }
065:
066: public void testLoadingSamplePointFile() throws Exception {
067: loadShapes(POINTTEST, 10);
068: loadMemoryMapped(POINTTEST, 10);
069: }
070:
071: public void testLoadingSamplePolygonFile() throws Exception {
072: loadShapes(POLYGONTEST, 2);
073: loadMemoryMapped(POLYGONTEST, 2);
074: }
075:
076: public void testLoadingTwice() throws Exception {
077: loadShapes(POINTTEST, 10);
078: loadShapes(POINTTEST, 10);
079: loadShapes(STATEPOP, 49);
080: loadShapes(STATEPOP, 49);
081: loadShapes(POLYGONTEST, 2);
082: loadShapes(POLYGONTEST, 2);
083: }
084:
085: /**
086: * It is posible for a point in a hole to touch the edge of its containing shell
087: * This test checks that such polygons can be loaded ok.
088: */
089: public void testPolygonHoleTouchAtEdge() throws Exception {
090: loadShapes(HOLETOUCHEDGE, 1);
091: loadMemoryMapped(HOLETOUCHEDGE, 1);
092: }
093:
094: /**
095: * It is posible for a shapefile to have extra information past the end
096: * of the normal feature area, this tests checks that this situation is
097: * delt with ok.
098: */
099: public void testExtraAtEnd() throws Exception {
100: loadShapes(EXTRAATEND, 3);
101: loadMemoryMapped(EXTRAATEND, 3);
102: }
103:
104: public void testIndexFile() throws Exception {
105: copyShapefiles(STATEPOP);
106: copyShapefiles(STATEPOP_IDX);
107: final ReadableByteChannel channel1 = TestData
108: .openChannel(STATEPOP); // Backed by InputStream
109: final ReadableByteChannel channel2 = TestData.openChannel(this ,
110: STATEPOP); // Backed by File
111: final ReadableByteChannel channel3 = TestData.openChannel(this ,
112: STATEPOP_IDX);
113: final ShapefileReader reader1 = new ShapefileReader(channel1,
114: new Lock());
115: final ShapefileReader reader2 = new ShapefileReader(channel2,
116: new Lock());
117: final IndexFile index = new IndexFile(channel3);
118: for (int i = 0; i < index.getRecordCount(); i++) {
119: if (reader1.hasNext()) {
120:
121: Geometry g1 = (Geometry) reader1.nextRecord().shape();
122: Geometry g2 = (Geometry) reader2.shapeAt(2 * (index
123: .getOffset(i)));
124: assertTrue(g1.equalsExact(g2));
125:
126: } else {
127: fail("uneven number of records");
128: }
129: //assertEquals(reader1.nextRecord().offset(),index.getOffset(i));
130: }
131: reader1.close();
132: reader2.close();
133: index.close();
134: }
135:
136: public void testHolyPolygons() throws Exception {
137: Geometry g = readGeometry("holyPoly");
138:
139: FeatureTypeFactory factory = FeatureTypeFactory
140: .newInstance("junk");
141: factory.addType(AttributeTypeFactory.newAttributeType("a",
142: Geometry.class));
143: FeatureType type = factory.getFeatureType();
144: FeatureCollection features = FeatureCollections.newCollection();
145: features.add(type.create(new Object[] { g }));
146:
147: File tmpFile = getTempFile();
148: tmpFile.delete();
149:
150: // write features
151: ShapefileDataStoreFactory make = new ShapefileDataStoreFactory();
152: DataStore s = make.createDataStore(tmpFile.toURL());
153: s.createSchema(type);
154: String typeName = type.getTypeName();
155: FeatureStore store = (FeatureStore) s
156: .getFeatureSource(typeName);
157:
158: store.addFeatures(features);
159:
160: s = new ShapefileDataStore(tmpFile.toURL());
161: typeName = s.getTypeNames()[0];
162: FeatureSource source = s.getFeatureSource(typeName);
163: FeatureCollection fc = source.getFeatures();
164:
165: ShapefileReadWriteTest.compare(features, fc);
166: }
167:
168: public void testSkippingRecords() throws Exception {
169: final ReadableByteChannel c = TestData.openChannel(STATEPOP);
170: final ShapefileReader r = new ShapefileReader(c, new Lock());
171: int idx = 0;
172: while (r.hasNext()) {
173: idx++;
174: r.nextRecord();
175: }
176: assertEquals(49, idx);
177: r.close();
178: c.close();
179: }
180:
181: public void testShapefileReaderRecord() throws Exception {
182: final ReadableByteChannel c1 = TestData.openChannel(STATEPOP);
183: ShapefileReader reader = new ShapefileReader(c1, new Lock());
184: ArrayList offsets = new ArrayList();
185: while (reader.hasNext()) {
186: ShapefileReader.Record record = reader.nextRecord();
187: offsets.add(new Integer(record.offset()));
188: Geometry geom = (Geometry) record.shape();
189: assertEquals(new Envelope(record.minX, record.maxX,
190: record.minY, record.maxY), geom
191: .getEnvelopeInternal());
192: record.toString();
193: }
194: copyShapefiles(STATEPOP);
195: reader.close();
196: final ReadableByteChannel c2 = TestData.openChannel(this ,
197: STATEPOP);
198: reader = new ShapefileReader(c2, new Lock());
199: for (int i = 0, ii = offsets.size(); i < ii; i++) {
200: reader.shapeAt(((Integer) offsets.get(i)).intValue());
201: }
202: reader.close();
203: c2.close();
204: c1.close();
205: }
206:
207: private void loadShapes(String resource, int expected)
208: throws Exception {
209: final ReadableByteChannel c = TestData.openChannel(resource);
210: ShapefileReader reader = new ShapefileReader(c, new Lock());
211: int cnt = 0;
212: while (reader.hasNext()) {
213: reader.nextRecord().shape();
214: cnt++;
215: }
216: assertEquals("Number of Geometries loaded incorect for : "
217: + resource, expected, cnt);
218: reader.close();
219: }
220:
221: private void loadMemoryMapped(String resource, int expected)
222: throws Exception {
223: final ReadableByteChannel c = TestData.openChannel(resource);
224: ShapefileReader reader = new ShapefileReader(c, new Lock());
225: int cnt = 0;
226: while (reader.hasNext()) {
227: reader.nextRecord().shape();
228: cnt++;
229: }
230: assertEquals("Number of Geometries loaded incorect for : "
231: + resource, expected, cnt);
232: reader.close();
233: }
234: }
|