GeoPackage gpkg = new GeoPackage(file);
// Initialize the GeoPackage file in order to avoid exceptions when accessing the geoPackage file
gpkg.init();
for (int i=0; i < contents.getLayerCount() ; i++) {
Layer layer = contents.getLayer(i);
if (layer.getType() == LayerType.FEATURES){
FeaturesLayer features = (FeaturesLayer) layer;
QName ftName = features.getFeatureType();
QueryType query = Wfs20Factory.eINSTANCE.createQueryType();
query.getTypeNames().add(ftName);
if (features.getSrs() == null) {
String ns = ftName.getNamespaceURI() != null
? ftName.getNamespaceURI() : ftName.getPrefix();
FeatureTypeInfo ft =
catalog.getFeatureTypeByName(ns, ftName.getLocalPart());
if (ft != null) {
try {
query.setSrsName(new URI(ft.getSRS()));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
else {
query.setSrsName(features.getSrs());
}
if (features.getPropertyNames() != null) {
query.getPropertyNames().addAll(features.getPropertyNames());
}
Filter filter = features.getFilter();
//add bbox to filter if there is one
if (features.getBbox() != null){
String defaultGeometry = catalog.getFeatureTypeByName(features.getFeatureType().getLocalPart())
.getFeatureType().getGeometryDescriptor().getLocalName();
Envelope e = features.getBbox();
// HACK: because we are going through wfs 2.0, flip the coordinates (specified in xy)
// which will then be later flipped back to xy
if (query.getSrsName() != null) {
try {
CoordinateReferenceSystem crs = CRS.decode(query.getSrsName().toString());
if (crs instanceof GeographicCRS) {
// flip the bbox
e = new Envelope(e.getMinY(), e.getMaxY(), e.getMinX(), e.getMaxX());
}
}
catch(Exception ex) {
throw new RuntimeException(ex);
}
}
Filter bboxFilter = filterFactory.bbox(filterFactory.property(defaultGeometry),
ReferencedEnvelope.reference(e));
if (filter == null) {
filter = bboxFilter;
} else {
filter = filterFactory.and(filter, bboxFilter);
}
}
query.setFilter(filter);
GetFeatureType getFeature = Wfs20Factory.eINSTANCE.createGetFeatureType();
getFeature.getAbstractQueryExpression().add(query);
FeatureCollectionResponse fc = getFeatureDelegate.run(GetFeatureRequest.adapt(getFeature));
for (FeatureCollection collection: fc.getFeatures()) {
if (! (collection instanceof SimpleFeatureCollection)) {
throw new ServiceException("GeoPackage OutputFormat does not support Complex Features.");
}
FeatureEntry e = new FeatureEntry();
e.setTableName(layer.getName());
addLayerMetadata(e, features);
ReferencedEnvelope bounds = collection.getBounds();
if (features.getBbox() != null){
bounds = ReferencedEnvelope.reference(bounds.intersection(features.getBbox()));
}
e.setBounds(bounds);
gpkg.add(e, (SimpleFeatureCollection) collection);
}
} else if (layer.getType() == LayerType.TILES) {
TilesLayer tiles = (TilesLayer) layer;
GetMapRequest request = new GetMapRequest();
request.setLayers(new ArrayList<MapLayerInfo>());
for (QName layerQName : tiles.getLayers()) {
LayerInfo layerInfo = null;
if ("".equals(layerQName.getNamespaceURI())) {
layerInfo = catalog.getLayerByName(layerQName.getLocalPart());
} else {
layerInfo = catalog.getLayerByName(new NameImpl(layerQName.getNamespaceURI(), layerQName.getLocalPart()));
}
if (layerInfo == null) {
throw new ServiceException("Layer not found: " + layerQName);
}
request.getLayers().add(new MapLayerInfo(layerInfo));
}
if (tiles.getBbox() == null) {
try {
// generate one from requests layers
CoordinateReferenceSystem crs =
tiles.getSrs() != null ? CRS.decode(tiles.getSrs().toString()) : null;
ReferencedEnvelope bbox = null;
for (MapLayerInfo l : request.getLayers()) {
ResourceInfo r = l.getResource();
ReferencedEnvelope b = null;
if (crs != null) {
// transform from lat lon bbox
b = r.getLatLonBoundingBox().transform(crs, true);
}
else {
// use native bbox
b = r.getNativeBoundingBox();
if (bbox != null) {
// transform
b = b.transform(bbox.getCoordinateReferenceSystem(), true);
}
}
if (bbox != null) {
bbox.include(b);
}
else {
bbox = b;
}
}
request.setBbox(bbox);
}
catch(Exception e) {
String msg = "Must specify bbox, unable to derive from requested layers";
throw new RuntimeException(msg ,e);
}
}
else {
request.setBbox(tiles.getBbox());
}
if (tiles.getSrs() == null) {
// use srs of first layer
ResourceInfo r = request.getLayers().iterator().next().getResource();
request.setSRS(r.getSRS());
}
else {
request.setSRS(tiles.getSrs().toString());
}
// Get the request SRS defined and set is as the request CRS
String srs = request.getSRS();
if(srs != null && !srs.isEmpty()){
try {
request.setCrs(CRS.decode(srs));
} catch (FactoryException e) {
throw new RuntimeException(e);
}
}
request.setBgColor(tiles.getBgColor());
request.setTransparent(tiles.isTransparent());
request.setStyleBody(tiles.getSldBody());
if (tiles.getSld() != null) {
request.setStyleUrl(tiles.getSld().toURL());
}
else if (tiles.getSldBody() != null) {
request.setStyleBody(tiles.getSldBody());
}
else {
request.setStyles(new ArrayList<Style>());
if (tiles.getStyles() != null) {
for (String styleName : tiles.getStyles()) {
StyleInfo info = catalog.getStyleByName(styleName);
if (info != null){
request.getStyles().add(info.getStyle());
}
}
}
if (request.getStyles().isEmpty()) {
for (MapLayerInfo layerInfo : request.getLayers()) {
request.getStyles().add(layerInfo.getDefaultStyle());
}
}
}
request.setFormat("none");
Map formatOptions = new HashMap();
formatOptions.put("format",tiles.getFormat());
if (tiles.getCoverage() != null) {
if (tiles.getCoverage().getMinZoom() != null) {
formatOptions.put("min_zoom", tiles.getCoverage().getMinZoom());
}
if (tiles.getCoverage().getMaxZoom() != null) {
formatOptions.put("max_zoom", tiles.getCoverage().getMaxZoom());
}
if (tiles.getCoverage().getMinColumn() != null) {
formatOptions.put("min_column", tiles.getCoverage().getMinColumn());
}
if (tiles.getCoverage().getMaxColumn() != null) {
formatOptions.put("max_column", tiles.getCoverage().getMaxColumn());
}
if (tiles.getCoverage().getMinRow() != null) {
formatOptions.put("min_row", tiles.getCoverage().getMinRow());
}
if (tiles.getCoverage().getMaxRow() != null) {
formatOptions.put("max_row", tiles.getCoverage().getMaxRow());
}
}
if (tiles.getGridSetName() != null) {
formatOptions.put("gridset", tiles.getGridSetName());
}
request.setFormatOptions(formatOptions);
TileEntry e = new TileEntry();
addLayerMetadata(e, tiles);
if (tiles.getGrids() != null) {
mapOutput.addTiles(gpkg, e, request, tiles.getGrids(), layer.getName());
} else {
mapOutput.addTiles(gpkg, e, request, layer.getName());
}
}
}
gpkg.close();