OskariWFS3Client { public static SimpleFeatureCollection getFeatures(OskariLayer layer, ReferencedEnvelope bbox, CoordinateReferenceSystem crs) throws ServiceRuntimeException { String crsURI = getCrsURI(layer, crs); MathTransform transformCRS84ToTargetCRS = null; if (crsURI == null) { try { transformCRS84ToTargetCRS = CRS.equalsIgnoreMetadata(getCRS84(), crs) ? null : CRS.findMathTransform(getCRS84(), crs); } catch (Exception e) { throw new ServiceRuntimeException("Coordinate transformation failure", e); } } String bboxCrsURI = null; if (bbox != null) { bboxCrsURI = getCrsURI(layer, bbox.getCoordinateReferenceSystem()); if (bboxCrsURI == null) { try { bbox = transformEnvelope(bbox, getCRS84()); } catch (Exception e) { throw new ServiceRuntimeException("bbox coordinate transformation failure", e); } } } String endPoint = layer.getUrl(); String collectionId = layer.getName(); String user = layer.getUsername(); String pass = layer.getPassword(); int hardLimit = 10000; String path = getItemsPath(endPoint, collectionId); Map<String, String> query = getQueryParams(crsURI, bbox, bboxCrsURI, hardLimit); Map<String, String> headers = Collections.singletonMap("Accept", CONTENT_TYPE_GEOJSON); List<SimpleFeatureCollection> pages = new ArrayList<>(); int numFeatures = 0; SimpleFeatureType schema; try { HttpURLConnection conn = IOHelper.getConnection(path, user, pass, query, headers); conn = IOHelper.followRedirect(conn, user, pass, query, headers, MAX_REDIRECTS); validateResponse(conn, CONTENT_TYPE_GEOJSON); Map<String, Object> geojson = readMap(conn); boolean ignoreGeometryProperties = true; schema = GeoJSONSchemaDetector.getSchema(geojson, crs, ignoreGeometryProperties); SimpleFeatureCollection sfc = GeoJSONReader2.toFeatureCollection(geojson, schema, transformCRS84ToTargetCRS); numFeatures += sfc.size(); pages.add(sfc); String next = getLinkHref(geojson, "next"); while (next != null && numFeatures < hardLimit) { conn = IOHelper.getConnection(next, user, pass, null, headers); conn = IOHelper.followRedirect(conn, user, pass, null, headers, MAX_REDIRECTS); validateResponse(conn, CONTENT_TYPE_GEOJSON); geojson = readMap(conn); sfc = GeoJSONReader2.toFeatureCollection(geojson, schema, transformCRS84ToTargetCRS); numFeatures += sfc.size(); pages.add(sfc); next = getLinkHref(geojson, "next"); } } catch (IOException e) { throw new ServiceRuntimeException("IOException occured", e); } catch (MismatchedDimensionException | TransformException e) { throw new ServiceRuntimeException("Projection transformation failed", e); } if (pages.size() == 1) { return pages.get(0); } return new PaginatedFeatureCollection(pages, schema, "FeatureCollection", hardLimit); } private  OskariWFS3Client(); static SimpleFeatureCollection getFeatures(OskariLayer layer,
            ReferencedEnvelope bbox, CoordinateReferenceSystem crs);  }
@Ignore("Depends on outside service, results might vary") @Test public void testGetFeaturesServiceSupportingCRS_EPSG3067() throws Exception { OskariLayer layer = new OskariLayer(); layer.setUrl("https: layer.setName("rakennus"); layer.setCapabilities(JSONHelper.createJSONObject("crs-uri", new JSONArray(Arrays.asList("http: CoordinateReferenceSystem epsg3067 = CRS.decode("EPSG:3067"); ReferencedEnvelope bbox = new ReferencedEnvelope(500000, 501000, 6822000, 6823000, epsg3067); SimpleFeatureCollection sfc = OskariWFS3Client.getFeatures(layer, bbox, epsg3067); assertFalse(sfc.isEmpty()); try (SimpleFeatureIterator it = sfc.features()) { while (it.hasNext()) { Geometry geometryEnvelope = ((Geometry) it.next().getDefaultGeometry()).getEnvelope(); assertTrue(geometryEnvelope.within(JTS.toGeometry(bbox))); } } }