package org.mapfish.print.map.geotools; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.io.Files; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultEngineeringCRS; import org.json.JSONObject; import org.junit.Test; import org.mapfish.print.AbstractMapfishSpringTest; import org.mapfish.print.Constants; import org.mapfish.print.TestHttpClientFactory; import org.mapfish.print.config.Configuration; import org.mapfish.print.config.ConfigurationFactory; import org.mapfish.print.http.ConfigFileResolvingHttpRequestFactory; import org.mapfish.print.http.MfClientHttpRequestFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.mock.http.client.MockClientHttpRequest; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.test.annotation.DirtiesContext; import java.io.File; import java.net.URI; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; public class FeaturesParserTest extends AbstractMapfishSpringTest { private static final String EXAMPLE_GEOJSONFILE = "geojson/geojson-inconsistent-attributes-2.json"; @Autowired private TestHttpClientFactory requestFactory; @Autowired private ConfigurationFactory configurationFactory; @Test public void testParseCRSBackwardCompat() throws Exception { JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"EPSG\",\n" + " \"properties\" : {\n" + " \"code\":\"4326\"\n" + " }\n" + "}\n}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertEquals("EPSG:4326", CRS.lookupIdentifier(crs, false)); } @Test public void testParseCRSNameCode() throws Exception { JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"name\",\n" + " \"properties\" : {\n" + " \"name\":\"EPSG:4326\"\n" + " }\n" + "}}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertEquals("EPSG:4326", CRS.lookupIdentifier(crs, false)); } @Test public void testParseCRSNameURI() throws Exception { JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"name\",\n" + " \"properties\" : {\n" + " \"name\":\"urn:ogc:def:crs:EPSG::4326\"\n" + " }\n" + "}}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertEquals("EPSG:4326", CRS.lookupIdentifier(crs, false)); } @Test @DirtiesContext public void testParseCRSLinkOgcWkt() throws Exception { requestFactory.registerHandler(new Predicate<URI>() { @Override public boolean apply(@Nullable URI input) { return input != null && input.getHost().equals("spatialreference.org"); } }, new TestHttpClientFactory.Handler() { @Override public MockClientHttpRequest handleRequest(URI uri, HttpMethod httpMethod) throws Exception { String wkt = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\"," + "\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]]," + "UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]"; MockClientHttpRequest mockClientHttpRequest = new MockClientHttpRequest(); mockClientHttpRequest.setResponse(new MockClientHttpResponse(wkt.getBytes(), HttpStatus.OK)); return mockClientHttpRequest; } }); JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"link\",\n" + " \"properties\" : {\n" + " \"href\":\"http://spatialreference.org/ref/epsg/4326/ogcwkt/\",\n" + " \"type\":\"ogcwkt\"\n" + " }\n" + "}}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertEquals("EPSG:4326", CRS.lookupIdentifier(crs, false)); } @Test @DirtiesContext public void testParseCRSLinkEsriWkt() throws Exception { requestFactory.registerHandler(new Predicate<URI>() { @Override public boolean apply(@Nullable URI input) { return input != null && input.getHost().equals("spatialreference.org"); } }, new TestHttpClientFactory.Handler() { @Override public MockClientHttpRequest handleRequest(URI uri, HttpMethod httpMethod) throws Exception { String wkt = "GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137,298.257223563]]," + "PRIMEM[\"Greenwich\"," + "0],UNIT[\"Degree\",0.017453292519943295]]"; MockClientHttpRequest mockClientHttpRequest = new MockClientHttpRequest(); mockClientHttpRequest.setResponse(new MockClientHttpResponse(wkt.getBytes(), HttpStatus.OK)); return mockClientHttpRequest; } }); JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"link\",\n" + " \"properties\" : {\n" + " \"href\":\"http://spatialreference.org/ref/epsg/4326/esriwkt/\",\n" + " \"type\":\"esriwkt\"\n" + " }\n" + "}}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertNotSame(DefaultEngineeringCRS.GENERIC_2D, crs); } public void testParseCRSLinkProj4() throws Exception { JSONObject crsJSON = new JSONObject("{\"crs\":{\n" + " \"type\":\"link\",\n" + " \"properties\" : {\n" + " \"href\":\"http://spatialreference.org/ref/epsg/4326/proj4/\",\n" + " \"type\":\"proj4\"\n" + " }\n" + "}}"); CoordinateReferenceSystem crs = FeaturesParser.parseCoordinateReferenceSystem(this.requestFactory, crsJSON, false); assertNotNull(crs); assertNotSame(DefaultEngineeringCRS.GENERIC_2D, crs); } @Test public void testTreatStringAsGeoJson() throws Exception { Configuration configuration = configurationFactory.getConfig(getFile("geojson/config.yaml")); MfClientHttpRequestFactory configRequestFactory = new ConfigFileResolvingHttpRequestFactory(requestFactory, configuration); FeaturesParser featuresParser = new FeaturesParser( configRequestFactory, false); for (File geojsonExample : getGeoJsonExamples()) { try { int numFeatures = getNumExpectedFeatures(geojsonExample); final String geojson = Files.toString(geojsonExample, Constants.DEFAULT_CHARSET); final SimpleFeatureCollection simpleFeatureCollection = featuresParser.treatStringAsGeoJson(geojson); assertEquals(geojsonExample.getName(), numFeatures, simpleFeatureCollection.size()); } catch (AssertionError e) { throw e; } catch (Throwable t) { t.printStackTrace(); throw new AssertionError("Exception raised when processing: " + geojsonExample.getName() + "\n" + t.getMessage()); } } } @Test public void testTreatStringAsGeoJsonEmptyCollection() throws Exception { Configuration configuration = configurationFactory.getConfig(getFile("geojson/config.yaml")); MfClientHttpRequestFactory configRequestFactory = new ConfigFileResolvingHttpRequestFactory(requestFactory, configuration); FeaturesParser featuresParser = new FeaturesParser( configRequestFactory, false); final String geojson = "{\"type\": \"FeatureCollection\", \"features\": []}"; final SimpleFeatureCollection simpleFeatureCollection = featuresParser.treatStringAsGeoJson(geojson); assertEquals(0, simpleFeatureCollection.size()); } private int getNumExpectedFeatures(File geojsonExample) { final Pattern numExpectedFilesPattern = Pattern.compile(".*-(\\d+)\\.json"); final Matcher matcher = numExpectedFilesPattern.matcher(geojsonExample.getName()); matcher.find(); final String numFeatures = matcher.group(1); return Integer.parseInt(numFeatures); } private Iterable<File> getGeoJsonExamples() { final File file = getFile(EXAMPLE_GEOJSONFILE); File directory = file.getParentFile(); return Iterables.filter(Files.fileTreeTraverser().children(directory), new Predicate<File>() { @Override public boolean apply(@Nullable File input) { return input.getName().endsWith(".json"); } }); } }