/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geotools.data.csv.parse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; import org.geotools.data.csv.CSVFileState; import org.junit.Test; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeType; import org.opengis.feature.type.GeometryDescriptor; import org.opengis.feature.type.GeometryType; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Point; public class CSVLatLonStrategyTest { @Test public void testBuildFeatureType() { String input = CSVTestStrategySupport.buildInputString("lat,lon,quux,morx\n"); CSVFileState fileState = new CSVFileState(input, "foo"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 3, featureType.getAttributeCount()); assertEquals("Invalid featuretype name", "foo", featureType.getName().getLocalPart()); assertEquals("Invalid name", "foo", featureType.getTypeName()); List<AttributeDescriptor> attrs = featureType.getAttributeDescriptors(); assertEquals("Invalid number of attributes", 3, attrs.size()); List<String> attrNames = new ArrayList<String>(2); for (AttributeDescriptor attr : attrs) { if (!(attr instanceof GeometryDescriptor)) { attrNames.add(attr.getName().getLocalPart()); } } Collections.sort(attrNames); assertEquals("Invalid property descriptor", "morx", attrNames.get(0)); assertEquals("Invalid property descriptor", "quux", attrNames.get(1)); GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor(); GeometryType geometryType = geometryDescriptor.getType(); assertEquals("Invalid geometry name", "location", geometryType.getName().getLocalPart()); } @Test public void testBuildFeature() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,lon,fleem,zoo", "3,4,car,cdr", "8,9,blub,frob"); CSVFileState fileState = new CSVFileState(input, "bar"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); CSVIterator iterator = strategy.iterator(); assertTrue("next value not read", iterator.hasNext()); SimpleFeature feature = iterator.next(); Point geometry = (Point) feature.getDefaultGeometry(); Coordinate coordinate = geometry.getCoordinate(); assertEquals("Invalid point", 3, coordinate.y, 0.1); assertEquals("Invalid point", 4, coordinate.x, 0.1); assertEquals("Invalid feature property", "car", feature.getAttribute("fleem").toString()); assertEquals("Invalid feature property", "cdr", feature.getAttribute("zoo").toString()); assertTrue("next value not read", iterator.hasNext()); feature = iterator.next(); geometry = (Point) feature.getDefaultGeometry(); coordinate = geometry.getCoordinate(); assertEquals("Invalid point", 8, coordinate.y, 0.1); assertEquals("Invalid point", 9, coordinate.x, 0.1); assertEquals("Invalid feature property", "blub", feature.getAttribute("fleem").toString()); assertEquals("Invalid feature property", "frob", feature.getAttribute("zoo").toString()); assertFalse("extra next value", iterator.hasNext()); try { iterator.next(); fail("NoSuchElementException should have been thrown"); } catch (NoSuchElementException e) { assertTrue(true); } } @Test public void testBuildFeatureDifferentTypes() throws IOException { String input = CSVTestStrategySupport.buildInputString( "doubleval,intval,lat,stringval,lon", "3.8,7,73.28,foo,-14.39", "9.12,-38,0,bar,29", "-37,0,49,baz,0"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); CSVIterator iterator = strategy.iterator(); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("invalid attribute count", 4, featureType.getAttributeCount()); GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor(); String localName = geometryDescriptor.getLocalName(); assertEquals("Invalid geometry name", "location", localName); assertEquals("Invalid attribute type", "java.lang.Double", getBindingName(featureType, "doubleval")); assertEquals("Invalid attribute type", "java.lang.Integer", getBindingName(featureType, "intval")); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "stringval")); // iterate through values and verify Object[][] expValues = new Object[][] { new Object[] { 3.8, 7, "foo", 73.28, -14.39 }, new Object[] { 9.12, -38, "bar", 0, 29 }, new Object[] { -37.0, 0, "baz", 49, 0 } }; Object[] expTypes = new Object[] { Double.class, Integer.class, String.class }; List<SimpleFeature> features = new ArrayList<SimpleFeature>(3); while (iterator.hasNext()) { features.add(iterator.next()); } assertEquals("Invalid number of features", 3, features.size()); String[] attrNames = new String[] { "doubleval", "intval", "stringval" }; int i = 0; for (SimpleFeature feature : features) { Object[] expVals = expValues[i]; for (int j = 0; j < 3; j++) { String attr = attrNames[j]; Object value = feature.getAttribute(attr); Class<?> type = value.getClass(); assertEquals("Invalid attribute type", expTypes[j], type); assertEquals("Invalid value", expVals[j], value); } i++; } } @Test public void testNoGeometry() throws IOException { String input = CSVTestStrategySupport.buildInputString("a,b", "foo,bar"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid number of attributes", 2, featureType.getAttributeCount()); assertNull("Expected no geometry in feature type", featureType.getGeometryDescriptor()); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "a")); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "b")); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); assertEquals("Invalid feature attribute count", 2, feature.getAttributeCount()); assertEquals("Invalid attribute", "foo", feature.getAttribute("a")); assertEquals("Invalid attribute", "bar", feature.getAttribute("b")); } @Test public void testOnlyLat() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,quux", "foo,morx"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid number of attributes", 2, featureType.getAttributeCount()); assertNull("Unexpected geometry", featureType.getGeometryDescriptor()); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "lat")); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "quux")); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); assertEquals("Invalid lat value", "foo", feature.getAttribute("lat")); assertEquals("Invalid lat value", "morx", feature.getAttribute("quux")); } @Test public void testDataDoesNotContainAllFields() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,lon,foo,bar", "-72.3829,42.29,quux"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 3, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); Point point = (Point) feature.getAttribute("location"); Coordinate coordinate = point.getCoordinate(); assertEquals("Invalid x coordinate", 42.29, coordinate.x, 0.1); assertEquals("Invalid y coordinate", -72.3829, coordinate.y, 0.1); assertEquals("Invalid attribute value", "quux", feature.getAttribute("foo")); assertNull("Expected null", feature.getAttribute("bar")); } @Test public void testDataContainsMoreFields() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,lon,foo", "-72.3829,42.29,quux,morx"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); assertEquals("Invalid attribute count", 2, feature.getAttributeCount()); assertNotNull("No location", feature.getAttribute("location")); assertEquals("Invalid attribute value", "quux", feature.getAttribute("foo")); } @Test public void testDataDifferentTypes() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,lon,foo", "-72.3829,42.29,38", "12,-13.21,9", "foo,2.5,7.8"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 3, featureType.getAttributeCount()); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "lat")); assertEquals("Invalid attribute type", "java.lang.Double", getBindingName(featureType, "lon")); assertEquals("Invalid attribute type", "java.lang.Double", getBindingName(featureType, "foo")); assertNull("Unexpected geometry", featureType.getGeometryDescriptor()); CSVIterator iterator = strategy.iterator(); String[] expLats = new String[] { "-72.3829", "12", "foo" }; Double[] expLons = new Double[] { 42.29, -13.21, 2.5 }; Double[] expFoos = new Double[] { 38.0, 9.0, 7.8 }; int i = 0; while (iterator.hasNext()) { SimpleFeature feature = iterator.next(); assertEquals("Invalid attribute count", 3, feature.getAttributeCount()); assertEquals("Invalid lat value", expLats[i], feature.getAttribute("lat")); assertEquals("Invalid lat value", expLons[i], (Double) feature.getAttribute("lon"), 0.1); assertEquals("Invalid foo value", expFoos[i], (Double) feature.getAttribute("foo"), 0.1); i++; } } @Test public void testDataFewerRowsDifferentType() throws IOException { String input = CSVTestStrategySupport.buildInputString("a,b", "foo"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); assertEquals("Invalid attribute type", "java.lang.String", getBindingName(featureType, "a")); assertEquals("Invalid attribute type", "java.lang.Integer", getBindingName(featureType, "b")); } @Test public void testLngColumnSpelling() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,lng,fleem", "73.239,-42.389,morx"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertNotNull("No geometry found", featureType.getGeometryDescriptor()); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); Point geometry = (Point) feature.getDefaultGeometry(); Coordinate coordinate = geometry.getCoordinate(); assertEquals("Invalid lat", -42.389, coordinate.x, 0.1); assertEquals("Invalid lon", 73.239, coordinate.y, 0.1); assertEquals("Invalid attribute value", "morx", feature.getAttribute("fleem")); } @Test public void testLongColumnSpelling() throws IOException { String input = CSVTestStrategySupport.buildInputString("lat,long,fleem", "73.239,-42.389,morx"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertNotNull("No geometry found", featureType.getGeometryDescriptor()); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); Point geometry = (Point) feature.getDefaultGeometry(); Coordinate coordinate = geometry.getCoordinate(); assertEquals("Invalid lat", -42.389, coordinate.x, 0.1); assertEquals("Invalid lon", 73.239, coordinate.y, 0.1); assertEquals("Invalid attribute value", "morx", feature.getAttribute("fleem")); } @Test public void testLatLngColumnsSpelledOut() throws Exception { String input = CSVTestStrategySupport.buildInputString("latitude,longitude,fleem", "73.239,-42.389,morx"); CSVFileState fileState = new CSVFileState(input, "typename"); CSVLatLonStrategy strategy = new CSVLatLonStrategy(fileState); SimpleFeatureType featureType = strategy.getFeatureType(); assertNotNull("No geometry found", featureType.getGeometryDescriptor()); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); SimpleFeature feature = iterator.next(); Point geometry = (Point) feature.getDefaultGeometry(); Coordinate coordinate = geometry.getCoordinate(); assertEquals("Invalid lat", -42.389, coordinate.x, 0.1); assertEquals("Invalid lon", 73.239, coordinate.y, 0.1); assertEquals("Invalid attribute value", "morx", feature.getAttribute("fleem")); } private String getBindingName(SimpleFeatureType featureType, String col) { AttributeDescriptor descriptor = featureType.getDescriptor(col); AttributeType attributeType = descriptor.getType(); Class<?> binding = attributeType.getBinding(); String bindingName = binding.getName(); return bindingName; } @Test public void testSpecifiedBuildFeatureType() { String input = CSVTestStrategySupport.buildInputString("quux,morx\n"); CSVFileState fileState = new CSVFileState(input, "foo"); CSVStrategy strategy = new CSVLatLonStrategy(fileState, "quux", "morx"); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 1, featureType.getAttributeCount()); assertEquals("Invalid featuretype name", "foo", featureType.getName().getLocalPart()); assertEquals("Invalid name", "foo", featureType.getTypeName()); GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor(); assertEquals("Invalid geometry attribute name", "location", geometryDescriptor.getLocalName()); } @Test public void testCreateFeature() throws IOException { String input = CSVTestStrategySupport.buildInputString("fleem,zoo,morx", "3,4,car", "8,9.9,cdr"); CSVFileState fileState = new CSVFileState(input, "bar"); CSVStrategy strategy = new CSVLatLonStrategy(fileState, "fleem", "zoo"); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); List<AttributeDescriptor> attrs = featureType.getAttributeDescriptors(); CSVTestStrategySupport.verifyType(attrs.get(0), Point.class); CSVTestStrategySupport.verifyType(attrs.get(1), String.class); CSVIterator iterator = strategy.iterator(); assertTrue("next value not read", iterator.hasNext()); SimpleFeature feature = iterator.next(); assertNull("Unexpected property", feature.getAttribute("fleem")); assertNull("Unexpected property", feature.getAttribute("zoo")); assertEquals("Invalid feature property", "car", feature.getAttribute("morx")); assertNotNull("Missing geometry", feature.getDefaultGeometry()); assertTrue("next value not read", iterator.hasNext()); feature = iterator.next(); assertNull("Unexpected property", feature.getAttribute("fleem")); assertNull("Unexpected property", feature.getAttribute("zoo")); assertEquals("Invalid feature property", "cdr", feature.getAttribute("morx")); assertNotNull("Missing geometry", feature.getDefaultGeometry()); assertFalse("extra next value", iterator.hasNext()); try { iterator.next(); fail("NoSuchElementException should have been thrown"); } catch (NoSuchElementException e) { assertTrue(true); } } @Test public void testCreateSpecifiedLatLngColumnsDontExist() throws IOException { String input = CSVTestStrategySupport.buildInputString("blub", "fubar"); CSVFileState fileState = new CSVFileState(input, "zul"); CSVStrategy strategy = new CSVLatLonStrategy(fileState, "non", "existing"); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 1, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); assertTrue("next value not read", iterator.hasNext()); SimpleFeature feature = iterator.next(); assertNull("Unexpected geometry", feature.getDefaultGeometry()); } @Test public void testCreateSpecifiedLatLngColumnsNotNumeric() throws IOException { String input = CSVTestStrategySupport.buildInputString("foo,bar", "3.8,quux"); CSVFileState fileState = new CSVFileState(input, "zul"); CSVStrategy strategy = new CSVLatLonStrategy(fileState, "foo", "bar"); SimpleFeatureType featureType = strategy.getFeatureType(); assertEquals("Invalid attribute count", 2, featureType.getAttributeCount()); CSVIterator iterator = strategy.iterator(); assertTrue("next value not read", iterator.hasNext()); SimpleFeature feature = iterator.next(); assertNull("Unexpected geometry", feature.getDefaultGeometry()); } }