package org.geotoolkit.data.geojson; import org.geotoolkit.data.geojson.binding.GeoJSONFeatureCollection; import org.geotoolkit.data.geojson.binding.GeoJSONObject; import org.geotoolkit.data.geojson.utils.GeoJSONParser; import org.geotoolkit.util.NamesExt; import org.opengis.util.GenericName; import com.vividsolutions.jts.geom.*; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.data.*; import org.geotoolkit.data.query.QueryBuilder; import org.geotoolkit.data.session.Session; import org.geotoolkit.storage.DataStores; import org.apache.sis.referencing.CommonCRS; import org.junit.Test; import org.opengis.parameter.ParameterValueGroup; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import org.apache.sis.feature.builder.AttributeRole; import org.apache.sis.feature.builder.FeatureTypeBuilder; import org.apache.sis.internal.feature.AttributeConvention; import static org.geotoolkit.data.geojson.GeoJSONFeatureStoreFactory.*; import static org.junit.Assert.*; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.PropertyType; /** * @author Quentin Boileau (Geomatys) */ public class GeoJSONReadTest extends org.geotoolkit.test.TestBase { @Test public void readPointTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/point.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("point"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("point", Point.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readMultiPointTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/multipoint.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("multipoint"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("multipoint", MultiPoint.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readLineStringTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/linestring.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("linestring"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("linestring", LineString.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readMultiLineStringTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/multilinestring.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("multilinestring"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("multilinestring", MultiLineString.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readPolygonTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/polygon.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("polygon"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("polygon", Polygon.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readMultiPolygonTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/multipolygon.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("multipolygon"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("multipolygon", MultiPolygon.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readGeometryCollectionTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/geometrycollection.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("geometrycollection"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildGeometryFeatureType("geometrycollection", GeometryCollection.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readFeatureTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/feature.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("feature"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildSimpleFeatureType("feature"), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(1, fcoll.size()); } @Test public void readFeatureCollectionTest() throws DataStoreException, URISyntaxException { URL pointFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/featurecollection.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(pointFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("featurecollection"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildFCFeatureType("featurecollection"), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(7, fcoll.size()); } /** * Test reading of Features with array as properties value * @throws DataStoreException */ @Test public void readPropertyArrayTest() throws DataStoreException, URISyntaxException { URL arrayFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/f_prop_array.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(arrayFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); assertEquals(NamesExt.create("f_prop_array"), name); FeatureType ft = store.getFeatureType(name.toString()); testFeatureTypes(buildPropertyArrayFeatureType("f_prop_array", Geometry.class), ft); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(2, fcoll.size()); Double[][] array1 = new Double[5][5]; Double[][] array2 = new Double[5][5]; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { array1[i][j] = (double) (i + j); array2[i][j] = (double) (i - j); } } FeatureIterator ite = fcoll.iterator(); Feature feat1 = ite.next(); assertArrayEquals(array1, (Double[][]) feat1.getProperty("array").getValue()); Feature feat2 = ite.next(); assertArrayEquals(array2, (Double[][]) feat2.getProperty("array").getValue()); } /** * This test ensure that properties fields with null value doesn't rise NullPointerException * @throws DataStoreException */ @Test public void readNullPropsTest() throws DataStoreException, URISyntaxException { URL jsonFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/sample_with_null_properties.json"); ParameterValueGroup param = PARAMETERS_DESCRIPTOR.createValue(); param.parameter(PATH.getName().getCode()).setValue(jsonFile.toURI()); FeatureStore store = (FeatureStore) DataStores.open(param); assertNotNull(store); assertEquals(1, store.getNames().size()); GenericName name = store.getNames().iterator().next(); FeatureType ft = store.getFeatureType(name.toString()); Session session = store.createSession(false); FeatureCollection fcoll = session.getFeatureCollection(QueryBuilder.all(name.toString())); assertEquals(15, fcoll.size()); } /** * Test GeoJSONParser full and lazy reading on FeatureCollection */ @Test public void parserTest() throws URISyntaxException, IOException { URL fcFile = GeoJSONReadTest.class.getResource("/org/geotoolkit/geojson/featurecollection.json"); Path fcPath = Paths.get(fcFile.toURI()); // test with full reading GeoJSONObject geoJSONObject = GeoJSONParser.parse(fcPath, false); assertTrue(geoJSONObject instanceof GeoJSONFeatureCollection); GeoJSONFeatureCollection geojsonFC = (GeoJSONFeatureCollection) geoJSONObject; assertFalse(geojsonFC.isLazyMode()); assertEquals(7, geojsonFC.getFeatures().size()); for (int i = 0; i < 7; i++) { assertTrue(geojsonFC.hasNext()); assertNotNull(geojsonFC.next()); } assertFalse(geojsonFC.hasNext()); //end of collection // test in lazy reading geoJSONObject = GeoJSONParser.parse(fcPath, true); assertTrue(geoJSONObject instanceof GeoJSONFeatureCollection); geojsonFC = (GeoJSONFeatureCollection) geoJSONObject; assertTrue(geojsonFC.isLazyMode()); assertEquals(0, geojsonFC.getFeatures().size()); //lazy don't know number of features for (int i = 0; i < 7; i++) { assertTrue(geojsonFC.hasNext()); assertNotNull(geojsonFC.next()); } assertFalse(geojsonFC.hasNext()); //end of collection } private FeatureType buildPropertyArrayFeatureType(String name, Class geomClass) { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName(name); ftb.addAttribute(Double[][].class).setName("array"); ftb.addAttribute(geomClass).setName(AttributeConvention.GEOMETRY_PROPERTY).setCRS(CommonCRS.WGS84.normalizedGeographic()).addRole(AttributeRole.DEFAULT_GEOMETRY); return ftb.build(); } private FeatureType buildGeometryFeatureType(String name, Class geomClass) { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName(name); ftb.addAttribute(geomClass).setName(AttributeConvention.GEOMETRY_PROPERTY).setCRS(CommonCRS.WGS84.normalizedGeographic()).addRole(AttributeRole.DEFAULT_GEOMETRY); return ftb.build(); } private FeatureType buildSimpleFeatureType(String name) { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName(name); ftb.addAttribute(Polygon.class).setName("geometry").setCRS(CommonCRS.WGS84.normalizedGeographic()).addRole(AttributeRole.DEFAULT_GEOMETRY); ftb.addAttribute(String.class).setName("name"); return ftb.build(); } private FeatureType buildFCFeatureType(String name) { final FeatureTypeBuilder ftb = new FeatureTypeBuilder(); ftb.setName(name); ftb.addAttribute(Geometry.class).setName("geometry").setCRS(CommonCRS.WGS84.normalizedGeographic()).addRole(AttributeRole.DEFAULT_GEOMETRY); ftb.addAttribute(String.class).setName("name"); ftb.addAttribute(String.class).setName("address"); return ftb.build(); } private void testFeatureTypes(FeatureType expected, FeatureType result) { for(PropertyType desc : expected.getProperties(true)){ PropertyType td = result.getProperty(desc.getName().tip().toString()); assertNotNull(td); if(td instanceof AttributeType){ assertEquals(((AttributeType) td).getValueClass(), ((AttributeType)desc).getValueClass()); } } } }