001: /*
002: * GeoTools - 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: package org.geotools.data.shapefile.indexed;
017:
018: import java.io.File;
019: import java.io.IOException;
020: import java.util.ArrayList;
021: import java.nio.channels.ReadableByteChannel;
022:
023: import com.vividsolutions.jts.geom.Envelope;
024: import com.vividsolutions.jts.geom.Geometry;
025:
026: import org.geotools.data.DataStore;
027: import org.geotools.data.DataUtilities;
028: import org.geotools.data.FeatureSource;
029: import org.geotools.data.FeatureStore;
030: import org.geotools.data.shapefile.Lock;
031: import org.geotools.data.shapefile.shp.IndexFile;
032: import org.geotools.data.shapefile.shp.ShapefileReader;
033: import org.geotools.feature.AttributeTypeFactory;
034: import org.geotools.feature.FeatureCollection;
035: import org.geotools.feature.FeatureCollections;
036: import org.geotools.feature.FeatureIterator;
037: import org.geotools.feature.FeatureType;
038: import org.geotools.feature.FeatureTypeFactory;
039: import org.geotools.TestData;
040:
041: /**
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/test/java/org/geotools/data/shapefile/indexed/ShapefileTest.java $
043: * @version $Id: ShapefileTest.java 22611 2006-11-06 21:23:28Z jgarnett $
044: * @author Ian Schneider
045: * @author James Macgill
046: */
047: public class ShapefileTest extends TestCaseSupport {
048: final String STATEPOP = "shapes/statepop.shp";
049: final String STATEPOP_IDX = "shapes/statepop.shx";
050: final String POINTTEST = "shapes/pointtest.shp";
051: final String POLYGONTEST = "shapes/polygontest.shp";
052: final String HOLETOUCHEDGE = "shapes/holeTouchEdge.shp";
053: final String EXTRAATEND = "shapes/extraAtEnd.shp";
054:
055: private final Lock lock = new Lock();
056:
057: public ShapefileTest(String testName) throws IOException {
058: super (testName);
059: }
060:
061: public static void main(String[] args) {
062: verbose = true;
063: junit.textui.TestRunner.run(suite(ShapefileTest.class));
064: }
065:
066: public void testLoadingStatePop() throws Exception {
067: loadShapes(STATEPOP, 49);
068: loadMemoryMapped(STATEPOP, 49);
069: }
070:
071: public void testLoadingSamplePointFile() throws Exception {
072: loadShapes(POINTTEST, 10);
073: loadMemoryMapped(POINTTEST, 10);
074: }
075:
076: public void testLoadingSamplePolygonFile() throws Exception {
077: loadShapes(POLYGONTEST, 2);
078: loadMemoryMapped(POLYGONTEST, 2);
079: }
080:
081: public void testLoadingTwice() throws Exception {
082: loadShapes(POINTTEST, 10);
083: loadShapes(POINTTEST, 10);
084: loadShapes(STATEPOP, 49);
085: loadShapes(STATEPOP, 49);
086: loadShapes(POLYGONTEST, 2);
087: loadShapes(POLYGONTEST, 2);
088: }
089:
090: /**
091: * It is posible for a point in a hole to touch the edge of its containing
092: * shell This test checks that such polygons can be loaded ok.
093: */
094: public void testPolygonHoleTouchAtEdge() throws Exception {
095: loadShapes(HOLETOUCHEDGE, 1);
096: loadMemoryMapped(HOLETOUCHEDGE, 1);
097: }
098:
099: /**
100: * It is posible for a shapefile to have extra information past the end of
101: * the normal feature area, this tests checks that this situation is delt
102: * with ok.
103: */
104: public void testExtraAtEnd() throws Exception {
105: loadShapes(EXTRAATEND, 3);
106: loadMemoryMapped(EXTRAATEND, 3);
107: }
108:
109: public void testIndexFile() throws Exception {
110: copyShapefiles(STATEPOP);
111: copyShapefiles(STATEPOP_IDX);
112: final ReadableByteChannel channel1 = TestData
113: .openChannel(STATEPOP); // Backed by InputStream
114: final ReadableByteChannel channel2 = TestData.openChannel(this ,
115: STATEPOP); // Backed by File
116: final ReadableByteChannel channel3 = TestData.openChannel(this ,
117: STATEPOP_IDX);
118: final ShapefileReader reader1 = new ShapefileReader(channel1,
119: lock);
120: final ShapefileReader reader2 = new ShapefileReader(channel2,
121: lock);
122: final IndexFile index = new IndexFile(channel3);
123: try {
124: for (int i = 0; i < index.getRecordCount(); i++) {
125: if (reader1.hasNext()) {
126: Geometry g1 = (Geometry) reader1.nextRecord()
127: .shape();
128: Geometry g2 = (Geometry) reader2.shapeAt(2 * (index
129: .getOffset(i)));
130: assertTrue(g1.equalsExact(g2));
131:
132: g2 = (Geometry) reader2.shapeAt(index
133: .getOffsetInBytes(i));
134: assertTrue(g1.equalsExact(g2));
135: } else {
136: fail("uneven number of records");
137: }
138:
139: //assertEquals(reader1.nextRecord().offset(),index.getOffset(i));
140: }
141: } finally {
142: reader1.close();
143: reader2.close();
144: index.close();
145: }
146: }
147:
148: public void testHolyPolygons() throws Exception {
149: Geometry g = readGeometry("holyPoly");
150:
151: FeatureTypeFactory factory = FeatureTypeFactory
152: .newInstance("junk");
153: factory.addType(AttributeTypeFactory.newAttributeType("a",
154: Geometry.class));
155:
156: FeatureType type = factory.getFeatureType();
157: FeatureCollection features = FeatureCollections.newCollection();
158: features.add(type.create(new Object[] { g }));
159:
160: File tmpFile = getTempFile();
161: tmpFile.delete();
162:
163: // write features
164: IndexedShapefileDataStoreFactory make = new IndexedShapefileDataStoreFactory();
165: DataStore s = make.createDataStore(tmpFile.toURL());
166: s.createSchema(type);
167:
168: String typeName = type.getTypeName();
169: FeatureStore store = (FeatureStore) s
170: .getFeatureSource(typeName);
171:
172: store.addFeatures(features);
173:
174: s = new IndexedShapefileDataStore(tmpFile.toURL());
175: typeName = s.getTypeNames()[0];
176:
177: FeatureSource source = s.getFeatureSource(typeName);
178: FeatureCollection fc = source.getFeatures();
179:
180: FeatureIterator f1iter = features.features();
181: FeatureIterator f2iter = fc.features();
182: try {
183: ShapefileRTreeReadWriteTest.compare(f1iter.next(), f2iter
184: .next());
185: } finally {
186: f1iter.close();
187: f2iter.close();
188: }
189: }
190:
191: public void testSkippingRecords() throws Exception {
192: ShapefileReader r = new ShapefileReader(TestData
193: .openChannel(STATEPOP), lock);
194: int idx = 0;
195:
196: while (r.hasNext()) {
197: idx++;
198: r.nextRecord();
199: }
200:
201: r.close();
202: assertEquals(49, idx);
203: }
204:
205: public void testShapefileReaderRecord() throws Exception {
206: ShapefileReader reader = new ShapefileReader(TestData
207: .openChannel(STATEPOP), lock);
208: ArrayList offsets = new ArrayList();
209:
210: while (reader.hasNext()) {
211: ShapefileReader.Record record = reader.nextRecord();
212: offsets.add(new Integer(record.offset()));
213:
214: Geometry geom = (Geometry) record.shape();
215: assertEquals(new Envelope(record.minX, record.maxX,
216: record.minY, record.maxY), geom
217: .getEnvelopeInternal());
218: record.toString();
219: }
220: reader.close();
221: copyShapefiles(STATEPOP);
222: reader = new ShapefileReader(TestData.openChannel(this ,
223: STATEPOP), lock);
224:
225: for (int i = 0, ii = offsets.size(); i < ii; i++) {
226: reader.shapeAt(((Integer) offsets.get(i)).intValue());
227: }
228: reader.close();
229: }
230:
231: private void loadShapes(String resource, int expected)
232: throws Exception {
233: final ReadableByteChannel c = TestData.openChannel(resource);
234: ShapefileReader reader = new ShapefileReader(c, lock);
235: int cnt = 0;
236:
237: while (reader.hasNext()) {
238: reader.nextRecord().shape();
239: cnt++;
240: }
241: reader.close();
242: assertEquals("Number of Geometries loaded incorect for : "
243: + resource, expected, cnt);
244: }
245:
246: private void loadMemoryMapped(String resource, int expected)
247: throws Exception {
248: final ReadableByteChannel c = TestData.openChannel(resource);
249: ShapefileReader reader = new ShapefileReader(c, lock);
250: int cnt = 0;
251: try {
252: while (reader.hasNext()) {
253: reader.nextRecord().shape();
254: cnt++;
255: }
256: } finally {
257: reader.close();
258: }
259: assertEquals("Number of Geometries loaded incorect for : "
260: + resource, expected, cnt);
261: }
262: }
|