package org.geotools.data.sort; import static org.junit.Assert.*; import java.io.IOException; import java.util.Date; import java.util.NoSuchElementException; import org.geotools.data.collection.DelegateFeatureReader; import org.geotools.data.simple.DelegateSimpleFeatureReader; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureReader; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.DefaultFeatureCollection; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.FilterFactory; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; /** * * * @source $URL$ */ public class SortedReaderTest { SimpleFeatureReader fr; FilterFactory ff; SortBy[] peopleAsc; SortBy[] peopleDesc; SortBy[] fidAsc; SimpleFeatureType schema; SimpleFeatureCollection fc; private SortBy[] dateAsc; @Before public void setup() throws IOException { SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder(); typeBuilder.setName("test"); typeBuilder.setNamespaceURI("test"); typeBuilder.setCRS(DefaultGeographicCRS.WGS84); typeBuilder.add("defaultGeom", Point.class, DefaultGeographicCRS.WGS84); typeBuilder.add("PERSONS", Integer.class); typeBuilder.add("byte", Byte.class); typeBuilder.add("short", Short.class); typeBuilder.add("long", Long.class); typeBuilder.add("float", Float.class); typeBuilder.add("double", Double.class); typeBuilder.add("date", Date.class); typeBuilder.add("sql_date", java.sql.Date.class); typeBuilder.add("sql_time", java.sql.Time.class); typeBuilder.add("sql_timestamp", java.sql.Timestamp.class); typeBuilder.add("otherGeom", LineString.class); typeBuilder.setDefaultGeometry("defaultGeom"); schema = (SimpleFeatureType) typeBuilder.buildFeatureType(); SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); GeometryFactory gf = new GeometryFactory(); fc = new DefaultFeatureCollection("test", schema); double x = -140; double y = 45; final int features = 500; for (int i = 0; i < features; i++) { Point point = gf.createPoint(new Coordinate(x + i, y + i)); point.setUserData(DefaultGeographicCRS.WGS84); builder.add(point); builder.add(new Integer(i)); builder.add(new Byte((byte) i)); builder.add(new Short((short) i)); builder.add(new Long(i)); builder.add(new Float(i)); builder.add(new Double(i)); builder.add(new Date()); builder.add(new java.sql.Date(System.currentTimeMillis())); builder.add(new java.sql.Time(System.currentTimeMillis())); builder.add(new java.sql.Timestamp(System.currentTimeMillis())); LineString line = gf.createLineString(new Coordinate[] { new Coordinate(x + i, y + i), new Coordinate(x + i + 1, y + i + 1) }); line.setUserData(DefaultGeographicCRS.WGS84); builder.add(line); fc.add(builder.buildFeature(i + "")); } // add a feature with a null geometry builder.add(null); builder.add(new Integer(-1)); builder.add(null); fc.add(builder.buildFeature((features + 1) + "")); fr = new DelegateSimpleFeatureReader(schema, fc.features()); ff = CommonFactoryFinder.getFilterFactory(null); peopleAsc = new SortBy[] { ff.sort("PERSONS", SortOrder.ASCENDING) }; peopleDesc = new SortBy[] { ff.sort("PERSONS", SortOrder.DESCENDING) }; dateAsc = new SortBy[] { ff.sort("date", SortOrder.ASCENDING) }; fidAsc = new SortBy[] { SortBy.NATURAL_ORDER }; } @After public void tearDown() throws IOException { fr.close(); } @Test public void testCanSort() { assertTrue(SortedFeatureReader.canSort(schema, peopleAsc)); assertTrue(SortedFeatureReader.canSort(schema, peopleDesc)); assertTrue(SortedFeatureReader.canSort(schema, fidAsc)); } @Test public void testMemorySort() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureReader sr = null; try { sr = new SortedFeatureReader(fr, peopleAsc, 1000); assertSortedOnPeopleAsc(sr); } finally { if (sr != null) { sr.close(); } } } @Test public void testFileSortDate() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureReader sr = null; try { sr = new SortedFeatureReader(fr, dateAsc, 100); assertSortedOnDateAsc(sr); } finally { if (sr != null) { sr.close(); } } } @Test public void testFileSortPeople() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureReader sr = null; try { sr = new SortedFeatureReader(fr, peopleAsc, 5); assertSortedOnPeopleAsc(sr); } finally { if (sr != null) { sr.close(); } } } @Test public void testIteratorSortReduce() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureIterator fi = null; try { fi = new SortedFeatureIterator(fc.features(), schema, peopleAsc, 1000); assertSortedOnPeopleAsc(fi); } finally { if (fi != null) { fi.close(); } } } @Test public void testSortDescending() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureReader sr = null; try { sr = new SortedFeatureReader(fr, peopleDesc, 1000); double prev = -1; while (fr.hasNext()) { SimpleFeature f = fr.next(); double curr = (Double) f.getAttribute("PERSONS"); if (prev > 0) { assertTrue(curr <= prev); } prev = curr; } } finally { if (sr != null) { sr.close(); } } } @Test public void testSortNatural() throws IOException { // make it so that we are not going to hit the disk SimpleFeatureReader sr = null; try { sr = new SortedFeatureReader(fr, fidAsc, 1000); String prev = null; while (fr.hasNext()) { SimpleFeature f = fr.next(); String id = f.getID(); if (prev != null) { assertTrue(id.compareTo(prev) >= 0); } prev = id; } } finally { if (sr != null) { sr.close(); } } } private void assertSortedOnPeopleAsc(SimpleFeatureReader fr) throws IllegalArgumentException, NoSuchElementException, IOException { double prev = -1; while (fr.hasNext()) { SimpleFeature f = fr.next(); int curr = (Integer) f.getAttribute("PERSONS"); if (prev > 0) { assertTrue(curr >= prev); } prev = curr; } } private void assertSortedOnDateAsc(SimpleFeatureReader fr) throws IllegalArgumentException, NoSuchElementException, IOException { Date prev = null; while (fr.hasNext()) { SimpleFeature f = fr.next(); Date curr = (Date) f.getAttribute("date"); if (prev != null) { assertTrue(prev.compareTo(curr) <= 0); } prev = curr; } } private void assertSortedOnPeopleAsc(SimpleFeatureIterator fi) throws IllegalArgumentException, NoSuchElementException, IOException { double prev = -1; while (fi.hasNext()) { SimpleFeature f = fi.next(); int curr = (Integer) f.getAttribute("PERSONS"); if (prev > 0) { assertTrue(curr >= prev); } prev = curr; } } }