All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wirelabs.jmaps.map.layer.WMTSLayer Maven / Gradle / Ivy

The newest version!
package net.wirelabs.jmaps.map.layer;


import lombok.extern.slf4j.Slf4j;
import net.opengis.ows.x11.DatasetDescriptionSummaryBaseType;
import net.opengis.wmts.x10.CapabilitiesDocument;
import net.opengis.wmts.x10.TileMatrixSetDocument;
import net.wirelabs.jmaps.map.geo.GeoUtils;
import net.wirelabs.jmaps.model.map.LayerDocument;
import okhttp3.HttpUrl;

import java.awt.*;
import java.awt.geom.Point2D;
import java.util.Optional;


import static net.wirelabs.jmaps.map.readers.WMTSCapReader.loadCapabilities;


/**
 * Created 5/20/23 by Michał Szwaczko ([email protected])
 * This class represents most common wmts layer
 * If you want to connect to more sophisticated wmts services
 * with custom urls etc you should extend this class into your own
 */
@Slf4j
public class WMTSLayer extends Layer {

    private static final String DEFAULT_GET_CAPABILITIES_PATH = "?service=WMTS&request=GetCapabilities";
    private final CapabilitiesDocument.Capabilities capabilities = loadCapabilities(getCapabilitiesUrl());
    private TileMatrixSetDocument.TileMatrixSet tms;


    protected String tmsName;
    protected String layerName;

    public WMTSLayer(LayerDocument.Layer layerDefinition) {

        super(layerDefinition);

        tmsName = layerDefinition.getTileMatrixSet();
        layerName = layerDefinition.getWmtsLayer();

        // if tms/layer is not specified
        // or tms/layer values given are not found in the capabilities file
        // set first ones found in capabilities file
        if (isEmpty(tmsName) || tmsNotExistent(tmsName))
            tmsName = capabilities.getContents().getTileMatrixSetList().get(0).getIdentifier().getStringValue();
        if (isEmpty(layerName) || layerNotExistent(layerName))
            layerName = capabilities.getContents().getDatasetDescriptionSummaryList().get(0).getIdentifier().getStringValue();

        findTileMatrixSetById(tmsName).ifPresentOrElse(tileMatrixSet -> {
            tms = tileMatrixSet;
            if (isEmpty(layerDefinition.getCrs())) {
                String crsName = GeoUtils.parseCrsUrn(tileMatrixSet.getSupportedCRS());
                setProjection(crsName);
                crs = crsName;
            }
            setMaxZoom(tileMatrixSet.getTileMatrixList().size() - 1);
            setTileSize(tileMatrixSet.getTileMatrixList().get(0).getTileWidth().intValue());
        }, () -> {
            log.warn("Cannot parse/setup layer " + layerDefinition.getName());
            log.warn("Setting global best-effort defaults");
            setMaxZoom(LayerDefaults.MAX_ZOOM);
            setTileSize(LayerDefaults.TILE_SIZE);
            setCrs(LayerDefaults.CRS);

        });

    }

    private Optional findTileMatrixSetById(String id) {

        return capabilities.getContents().getTileMatrixSetList()
                .stream()
                .filter(x -> x.getIdentifier().getStringValue().equals(id))
                .findFirst();
    }

    private Optional findLayerById(String id) {
        //capabilities.getContents().getDatasetDescriptionSummaryList().get(0).getIdentifier().getStringValue(
        return capabilities.getContents().getDatasetDescriptionSummaryList()
                .stream()
                .filter(x -> x.getIdentifier().getStringValue().equals(id))
                .findFirst();
    }


    boolean tmsNotExistent(String tms) {
        Optional xx = findTileMatrixSetById(tms);
        if (xx.isEmpty()) {
            log.info("TileMatrixSet {} not existing in Capabilities. Setting default", tms);
        }
        return xx.isEmpty();
    }

    boolean layerNotExistent(String layer) {
        Optional xx = findLayerById(layer);
        if (xx.isEmpty()) {
            log.info("Layer  {} not existing in Capabilities. Setting default", layer);
        }
        return xx.isEmpty();
    }

    boolean isEmpty(String s) {
        return (s == null || s.isBlank());
    }


    /**
     * Override this method if wmts service has nonstandard 'getCapabilities' path
     */
    protected String getCapabilitiesUrl() {
        return url + DEFAULT_GET_CAPABILITIES_PATH;
    }


    @Override
    public Dimension getSizeInTiles(int zoom) {

        int width = tms.getTileMatrixList().get(zoom).getMatrixWidth().intValue();
        int height = tms.getTileMatrixList().get(zoom).getMatrixHeight().intValue();
        return new Dimension(width, height);
    }

    // todo: add style and format (recognize from capabilities)
    @Override
    public String createTileUrl(int x, int y, int zoom) {
        return HttpUrl.parse(url).newBuilder().
                addQueryParameter("Service", "WMTS")
                .addQueryParameter("Request", "GetTile")
                .addQueryParameter("Layer", layerName)
                .addQueryParameter("Version", "1.0.0")
                .addQueryParameter("format", "image/png")
                .addQueryParameter("style", "default")
                .addQueryParameter("TileMatrixSet", tmsName)
                .addQueryParameter("TileMatrix", tms.getTileMatrixList().get(zoom).getIdentifier().getStringValue())
                .addQueryParameter("TileRow", String.valueOf(y))
                .addQueryParameter("TileCol", String.valueOf(x))
                .toString();

    }

    @Override
    public Point2D getTopLeftCornerInMeters() {

        double x = (double) tms.getTileMatrixList().get(0).getTopLeftCorner().get(0);
        double y = (double) tms.getTileMatrixList().get(0).getTopLeftCorner().get(1);
        if (swapAxis) {
            return new Point2D.Double(y, x);
        } else {
            return new Point2D.Double(x, y);
        }
    }


    @Override
    public double getMetersPerPixelAtZoom(int zoom) {
        return tms.getTileMatrixList().get(zoom).getScaleDenominator() * 0.00028;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy