001: package org.geotools.data.ogr;
002:
003: import java.io.File;
004: import java.io.FileNotFoundException;
005: import java.io.IOException;
006: import java.math.BigDecimal;
007: import java.math.BigInteger;
008: import java.net.URL;
009: import java.util.Date;
010: import java.util.Iterator;
011:
012: import org.geotools.TestData;
013: import org.geotools.data.DataStore;
014: import org.geotools.data.DataUtilities;
015: import org.geotools.data.DefaultQuery;
016: import org.geotools.data.FeatureReader;
017: import org.geotools.data.FeatureSource;
018: import org.geotools.data.FeatureWriter;
019: import org.geotools.data.Query;
020: import org.geotools.data.Transaction;
021: import org.geotools.data.shapefile.ShapefileDataStore;
022: import org.geotools.feature.AttributeType;
023: import org.geotools.feature.AttributeTypeFactory;
024: import org.geotools.feature.DefaultFeature;
025: import org.geotools.feature.Feature;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.feature.FeatureCollections;
028: import org.geotools.feature.FeatureIterator;
029: import org.geotools.feature.FeatureType;
030: import org.geotools.feature.FeatureTypeFactory;
031: import org.geotools.feature.FeatureTypes;
032: import org.geotools.feature.SimpleFeature;
033: import org.geotools.feature.type.BasicFeatureTypes;
034: import org.geotools.referencing.CRS;
035: import org.opengis.filter.Filter;
036:
037: import com.vividsolutions.jts.geom.Coordinate;
038: import com.vividsolutions.jts.geom.Geometry;
039: import com.vividsolutions.jts.geom.GeometryFactory;
040: import com.vividsolutions.jts.geom.Point;
041:
042: /**
043: * Basic test for OGR data store capabilites against file data sources
044: *
045: * @author aaime
046: */
047: public class OGRDataStoreTest extends TestCaseSupport {
048:
049: public OGRDataStoreTest(String testName) throws IOException {
050: super (testName);
051: }
052:
053: public void testGetTypeNames() throws FileNotFoundException,
054: IOException {
055: OGRDataStore store = new OGRDataStore(
056: getAbsolutePath(STATE_POP), null, null);
057: assertEquals(1, store.getTypeNames().length);
058: assertEquals("statepop", store.getTypeNames()[0]);
059: store = new OGRDataStore(getAbsolutePath(MIXED), null, null);
060: assertEquals(1, store.getTypeNames().length);
061: assertEquals("mixed", store.getTypeNames()[0]);
062: }
063:
064: public void testSchemaPop() throws Exception {
065: OGRDataStore s = new OGRDataStore(getAbsolutePath(STATE_POP),
066: null, null);
067: FeatureType schema = s.getSchema(s.getTypeNames()[0]);
068: AttributeType[] types = schema.getAttributeTypes();
069: assertEquals("Number of Attributes", 253, types.length);
070: assertTrue(CRS.equalsIgnoreMetadata(CRS.decode("EPSG:4269",
071: true), schema.getDefaultGeometry()
072: .getCoordinateSystem()));
073: }
074:
075: public void testSchemaMix() throws Exception {
076: OGRDataStore s = new OGRDataStore(getAbsolutePath(MIXED), null,
077: null);
078: FeatureType schema = s.getSchema(s.getTypeNames()[0]);
079: AttributeType[] types = schema.getAttributeTypes();
080: assertEquals("Number of Attributes", 11, types.length);
081: // mixed geometry types, only way is to use Geometry as geom type
082: assertEquals(Geometry.class, schema.getDefaultGeometry()
083: .getType());
084: // ah, can't compare the WKT against the EPSG database becuase it's
085: // apparently broken, it's EPSG:3003 but with (very) different TOWGS84
086: // parameters, crazy...
087: // assertTrue(CRS.equalsIgnoreMetadata(CRS.decode("EPSG:3003", true),
088: // schema
089: // .getDefaultGeometry().getCoordinateSystem()));
090: }
091:
092: /**
093: * Test envelope versus old DataSource
094: */
095: public void testOptimizedEnvelope() throws Exception {
096: FeatureCollection features = loadFeatures(STATE_POP, Query.ALL);
097: OGRDataStore s = new OGRDataStore(getAbsolutePath(STATE_POP),
098: null, null);
099: String typeName = s.getTypeNames()[0];
100:
101: assertEquals(features.getBounds(), s.getFeatureSource(typeName)
102: .getBounds());
103: assertNotNull(s.getFeatureSource(typeName).getBounds());
104: }
105:
106: public void testLoadAndVerify() throws Exception {
107: FeatureCollection features = loadFeatures(STATE_POP, Query.ALL);
108: int count = features.size();
109:
110: assertTrue("Have features", count > 0);
111: assertEquals("Number of Features loaded", 49, features.size());
112: assertEquals(49, countFeatures(features));
113:
114: FeatureType schema = firstFeature(features).getFeatureType();
115: assertNotNull(schema.getDefaultGeometry());
116: assertEquals("Number of Attributes", 253, schema
117: .getAttributeTypes().length);
118: assertEquals("Value of statename is wrong", firstFeature(
119: features).getAttribute("STATE_NAME"), "Illinois");
120: assertEquals("Value of land area is wrong",
121: ((Double) firstFeature(features)
122: .getAttribute("LAND_KM")).doubleValue(),
123: 143986.61, 0.001);
124: }
125:
126: public void testLoadAndCheckParentTypeIsPolygon() throws Exception {
127: FeatureCollection features = loadFeatures(STATE_POP, Query.ALL);
128: FeatureType schema = firstFeature(features).getFeatureType();
129: assertTrue(schema.isDescendedFrom(BasicFeatureTypes.POLYGON));
130: assertTrue(schema.isDescendedFrom(
131: FeatureTypes.DEFAULT_NAMESPACE, "polygonFeature"));
132: }
133:
134: public void testShapefileComparison() throws Exception {
135: URL url = TestData.url(STATE_POP);
136: ShapefileDataStore sds = new ShapefileDataStore(url);
137: OGRDataStore ods = new OGRDataStore(getAbsolutePath(STATE_POP),
138: null, null);
139:
140: assertEquals(sds.getSchema(), ods.getSchema(sds.getSchema()
141: .getTypeName()));
142:
143: DefaultQuery query = new DefaultQuery(sds.getSchema()
144: .getTypeName());
145: FeatureReader sfr = sds.getFeatureReader(query,
146: Transaction.AUTO_COMMIT);
147: FeatureReader ofr = ods.getFeatureReader(query,
148: Transaction.AUTO_COMMIT);
149: Feature sf = null;
150: Feature of = null;
151: while (true) {
152: if (!sfr.hasNext()) {
153: assertTrue(!ofr.hasNext());
154: break;
155: }
156: sf = sfr.next();
157: of = ofr.next();
158: for (int i = 0; i < sds.getSchema().getAttributeCount(); i++) {
159: Object shapeAtt = sf.getAttribute(i);
160: Object ogrAtt = of.getAttribute(i);
161: // don't know exactly why geometries have to be compared
162: // separately
163: // but issuing an assertEqual
164: if (shapeAtt instanceof Geometry)
165: assertTrue(((Geometry) (shapeAtt))
166: .equals((Geometry) ogrAtt));
167: else
168: assertEquals(shapeAtt, ogrAtt);
169: }
170: }
171: sfr.close();
172: ofr.close();
173: }
174:
175: public void testShapeWriteCapabilities() throws Exception {
176: OGRDataStore ods = new OGRDataStore(getAbsolutePath(STATE_POP),
177: null, null);
178: assertTrue(ods.supportsInPlaceWrite(ods.getTypeNames()[0]));
179: }
180:
181: public void testMIFWriteCapabilities() throws Exception {
182: OGRDataStore ods = new OGRDataStore(getAbsolutePath(MIXED),
183: null, null);
184: assertTrue(ods.supportsWriteNewLayer(ods.getTypeNames()[0]));
185: }
186:
187: /**
188: * Create a test file, then continue removing the first entry until there
189: * are no features left.
190: */
191: public void testRemoveFromFrontAndClose() throws Throwable {
192: OGRDataStore sds = createDataStore();
193:
194: String typeName = sds.getTypeNames()[0];
195: int idx = loadFeatures(sds, typeName).size();
196:
197: while (idx > 0) {
198: FeatureWriter writer = null;
199:
200: try {
201: writer = sds.getFeatureWriter(typeName, Filter.INCLUDE,
202: Transaction.AUTO_COMMIT);
203: writer.next();
204: writer.remove();
205: } finally {
206: if (writer != null) {
207: writer.close();
208: writer = null;
209: }
210: }
211: idx--;
212: assertEquals(idx, loadFeatures(sds, typeName).size());
213: }
214: }
215:
216: /**
217: * Create a test file, then continue removing the last entry until there are
218: * no features left.
219: */
220: public void testRemoveFromBackAndClose() throws Throwable {
221: OGRDataStore sds = createDataStore();
222: String typeName = sds.getTypeNames()[0];
223:
224: int idx = loadFeatures(sds, typeName).size();
225:
226: while (idx > 0) {
227: FeatureWriter writer = null;
228: try {
229: writer = sds.getFeatureWriter(sds.getTypeNames()[0],
230: Filter.INCLUDE, Transaction.AUTO_COMMIT);
231: while (writer.hasNext()) {
232: writer.next();
233: }
234: writer.remove();
235: } finally {
236: if (writer != null) {
237: writer.close();
238: writer = null;
239: }
240: }
241: assertEquals(--idx, loadFeatures(sds, typeName).size());
242: }
243:
244: }
245:
246: public void testCreateSchema() throws Exception {
247: String[] fileNames = shapeFileNames("test");
248: cleanFiles(fileNames);
249: String absolutePath = new File(fileNames[0]).getAbsolutePath();
250: OGRDataStore ds = new OGRDataStore(absolutePath,
251: "ESRI shapefile", null);
252: FeatureType schema = DataUtilities
253: .createType("test",
254: "geom:MultiPolygon,count:int,level1:double,level2:float,chars:string");
255: ds.createSchema(schema);
256:
257: // now do some testing
258: assertEquals(1, ds.getTypeNames().length);
259: assertEquals("test", ds.getTypeNames()[0]);
260: FeatureType ogrSchema = ds.getSchema(ds.getTypeNames()[0]);
261: assertEquals(schema.getDefaultGeometry().getType(), ogrSchema
262: .getDefaultGeometry().getType());
263: for (int i = 0; i < schema.getAttributeCount(); i++) {
264: AttributeType at = schema.getAttributeType(i);
265: if (at == schema.getDefaultGeometry())
266: continue;
267:
268: assertEquals(at.getName(), ogrSchema.getAttributeType(i)
269: .getName());
270: assertEquals("Wrong type for attribute " + at.getName(), at
271: .getType(), ogrSchema.getAttributeType(i).getType());
272: }
273: }
274:
275: public void testCreateWriteRead() throws Exception {
276: String typeName = "testw";
277: String[] files = shapeFileNames(typeName);
278: cleanFiles(files);
279:
280: File file = new File(typeName + ".shp");
281: OGRDataStore ds = new OGRDataStore(file.getAbsolutePath(),
282: "ESRI shapefile", null);
283: FeatureType schema = DataUtilities.createType(typeName,
284: "geom:Point,cat:int,name:string");
285: ds.createSchema(schema);
286:
287: GeometryFactory gf = new GeometryFactory();
288: // creating 20 geometries because with only a couple a finalization
289: // related error that did blew up the VM would not appear
290: Feature[] features = new Feature[20];
291: for (int i = 0; i < features.length; i++) {
292: features[i] = schema.create(new Object[] {
293: gf.createPoint(new Coordinate(i, i)),
294: new Integer(i), "" + i });
295: }
296:
297: FeatureWriter writer = ds.getFeatureWriterAppend("testw",
298: Transaction.AUTO_COMMIT);
299: for (int i = 0; i < features.length; i++) {
300: assertFalse(writer.hasNext());
301: DefaultFeature f = (DefaultFeature) writer.next();
302: f.setAttributes(features[i].getAttributes(null));
303: writer.write();
304: assertEquals(typeName + "." + i, f.getID());
305: }
306: writer.close();
307:
308: FeatureReader reader = ds.getFeatureReader("testw");
309: for (int i = 0; i < features.length; i++) {
310: assertTrue(reader.hasNext());
311: Feature f = reader.next();
312: for (int j = 0; j < schema.getAttributeCount(); j++) {
313: if (f.getAttribute(j) instanceof Geometry) {
314: // this is necessary because geometry equality is
315: // implemented as Geometry.equals(Geometry)
316: Geometry a = (Geometry) f.getAttribute(j);
317: Geometry b = (Geometry) features[i].getAttribute(j);
318: assertTrue(a.equals(b));
319: } else {
320: assertEquals(f.getAttribute(j), features[i]
321: .getAttribute(j));
322: }
323: }
324: }
325: assertFalse(reader.hasNext());
326: reader.close();
327: }
328:
329: public void testAttributesWriting() throws Exception {
330: FeatureCollection features = createFeatureCollection();
331: File tmpFile = getTempFile();
332: tmpFile.delete();
333: OGRDataStore s = new OGRDataStore(tmpFile.getAbsolutePath(),
334: "ESRI shapefile", null);
335: writeFeatures(s, features);
336: }
337:
338: // ---------------------------------------------------------------------------------------
339: // SUPPORT METHODS
340: // ---------------------------------------------------------------------------------------
341:
342: private int countFeatures(FeatureCollection features) {
343: int count = 0;
344: for (Iterator it = features.iterator(); it.hasNext(); it.next()) {
345: count++;
346: }
347: return count;
348: }
349:
350: protected FeatureCollection loadFeatures(String resource,
351: Query query) throws Exception {
352: assertNotNull(query);
353:
354: OGRDataStore s = new OGRDataStore(getAbsolutePath(resource),
355: null, null);
356: FeatureSource fs = s.getFeatureSource(s.getTypeNames()[0]);
357: return fs.getFeatures(query);
358: }
359:
360: protected FeatureCollection loadFeatures(DataStore store,
361: String typeName) throws Exception {
362: FeatureSource fs = store.getFeatureSource(typeName);
363: return fs.getFeatures();
364: }
365:
366: protected FeatureCollection createFeatureCollection()
367: throws Exception {
368: FeatureTypeFactory factory = FeatureTypeFactory
369: .newInstance("junk");
370: factory.addType(AttributeTypeFactory.newAttributeType("a",
371: Point.class));
372: factory.addType(AttributeTypeFactory.newAttributeType("b",
373: Byte.class));
374: factory.addType(AttributeTypeFactory.newAttributeType("c",
375: Short.class));
376: factory.addType(AttributeTypeFactory.newAttributeType("d",
377: Double.class));
378: factory.addType(AttributeTypeFactory.newAttributeType("e",
379: Float.class));
380: factory.addType(AttributeTypeFactory.newAttributeType("f",
381: String.class));
382: factory.addType(AttributeTypeFactory.newAttributeType("g",
383: Date.class));
384: factory.addType(AttributeTypeFactory.newAttributeType("h",
385: Boolean.class));
386: factory.addType(AttributeTypeFactory.newAttributeType("i",
387: Number.class));
388: factory.addType(AttributeTypeFactory.newAttributeType("j",
389: Long.class));
390: factory.addType(AttributeTypeFactory.newAttributeType("k",
391: BigDecimal.class));
392: factory.addType(AttributeTypeFactory.newAttributeType("l",
393: BigInteger.class));
394: FeatureType type = factory.getFeatureType();
395: FeatureCollection features = FeatureCollections.newCollection();
396: for (int i = 0, ii = 20; i < ii; i++) {
397: features.add(type.create(new Object[] {
398: new GeometryFactory().createPoint(new Coordinate(1,
399: -1)),
400: new Byte((byte) i),
401: new Short((short) i),
402: new Double(i),
403: new Float(i),
404: new String(i + " "),
405: new Date(i),
406: new Boolean(true),
407: new Integer(22),
408: new Long(1234567890123456789L),
409: new BigDecimal(new BigInteger(
410: "12345678901234567890123456789"), 2),
411: new BigInteger("12345678901234567890123456789") }));
412: }
413: return features;
414: }
415:
416: private void writeFeatures(DataStore s, FeatureCollection fc)
417: throws Exception {
418: s.createSchema(fc.features().next().getFeatureType());
419: FeatureWriter fw = s.getFeatureWriter(s.getTypeNames()[0],
420: Transaction.AUTO_COMMIT);
421: FeatureIterator it = fc.features();
422: while (it.hasNext()) {
423: ((SimpleFeature) fw.next()).setAttributes(it.next()
424: .getAttributes(null));
425: fw.write();
426: }
427: fw.close();
428: }
429:
430: private OGRDataStore createDataStore(File f) throws Exception {
431: FeatureCollection fc = createFeatureCollection();
432: f.delete();
433: OGRDataStore sds = new OGRDataStore(f.getAbsolutePath(),
434: "ESRI shapefile", null);
435: writeFeatures(sds, fc);
436: return sds;
437: }
438:
439: private OGRDataStore createDataStore() throws Exception {
440: return createDataStore(getTempFile());
441: }
442:
443: private String[] shapeFileNames(String typeName) {
444: return new String[] { typeName + ".shp", typeName + ".dbf",
445: typeName + ".shp", typeName + ".shx", typeName + ".prj" };
446: }
447:
448: private void cleanFiles(String[] files) {
449: for (int i = 0; i < files.length; i++) {
450: File f = new File(files[i]);
451: if (f.exists())
452: f.delete();
453: }
454: }
455: }
|