Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting mapml-proxy cascading #374

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/en/user/source/extensions/mapml/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ Using tiles to access the layer can increase the performance of your web map. Th
**Use Tiles**
If the "Use Tiles" checkbox is checked, by default the output MapML will define a tile-based reference to the WMS server. Otherwise, an image-based reference will be used. If one or more of the MapML-defined GridSets is referenced by the layer or layer group in its "Tile Caching" profile, GeoServer will generate tile references instead of generating WMS GetMap URLs in the MapML document body.

Client Requests
^^^^^^^^^^^^^^^

When configuring a cascaded WMS or WMTS remote layers, a new "Client Requests" setting is available.

**Remote**
If the "Remote" checkbox is checked, the link templates embedded in MapML will refer to the remote WMS/WMTS.
The MapML viewer will directly contact the remote server if certain criteria are met:

- No restricting DataAccessLimit security is associated to the layer (e.g. with GeoFence integration) that will do filtering, clipping or similar operations. In that case, the MapML will point to the local GeoServer so that the param is honored.
- No vendor parameters are used in the incoming request. If vendor parameters are used (e.g., request clipping with geometric mask) the MapML is pointing to the local GeoServer so that the vendor parameter is honored
- The remote Server is supporting the requested CoordinateReferenceSystem for that layer.
- GetTile requests will be sent to the remote server if there is a compatible gridset for that layer (same origin, same CRS, same tile sizes, same levels and same resolutions)

Vector Settings
^^^^^^^^^^^^^^^

Expand Down
10 changes: 10 additions & 0 deletions src/extension/mapml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
<version>0.3.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public final class MapMLConstants {
/** MapML layer metadata use tiles */
public static final String MAPML_USE_TILES = "mapml.useTiles";

/** MapML layer metadata remote client request */
public static final String MAPML_USE_REMOTE = "mapml.useRemote";

/** MapML layer resource metadata */
public static final String RESOURCE_METADATA = "resource.metadata";

Expand Down Expand Up @@ -86,6 +89,9 @@ public final class MapMLConstants {
/** USE_TILES */
public static final String USE_TILES = "useTiles";

/** REMOTE */
public static final String USE_REMOTE = "useRemote";

/** LICENSE_LINK */
public static final String LICENSE = "licenseLink";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.geoserver.mapml.MapMLConstants.MAPML_SKIP_ATTRIBUTES_FO;
import static org.geoserver.mapml.MapMLConstants.MAPML_SKIP_STYLES_FO;
import static org.geoserver.mapml.MapMLConstants.MAPML_USE_FEATURES;
import static org.geoserver.mapml.MapMLConstants.MAPML_USE_REMOTE;
import static org.geoserver.mapml.MapMLConstants.MAPML_USE_TILES;
import static org.geoserver.mapml.MapMLHTMLOutput.PREVIEW_TCRS_MAP;
import static org.geoserver.mapml.template.MapMLMapTemplate.MAPML_PREVIEW_HEAD_FTL;
Expand Down Expand Up @@ -182,13 +183,6 @@ public class MapMLDocumentBuilder {
private Boolean isMultiExtent = MAPML_MULTILAYER_AS_MULTIEXTENT_DEFAULT;
private MapMLMapTemplate mapMLMapTemplate = new MapMLMapTemplate();

static {
PREVIEW_TCRS_MAP.put("OSMTILE", new TiledCRS("OSMTILE"));
PREVIEW_TCRS_MAP.put("CBMTILE", new TiledCRS("CBMTILE"));
PREVIEW_TCRS_MAP.put("APSTILE", new TiledCRS("APSTILE"));
PREVIEW_TCRS_MAP.put("WGS84", new TiledCRS("WGS84"));
}

/**
* Constructor
*
Expand Down Expand Up @@ -606,6 +600,7 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl
.getGridSubset(projType.value())
!= null;
boolean useTiles = Boolean.TRUE.equals(layerMeta.get(MAPML_USE_TILES, Boolean.class));
boolean useRemote = Boolean.TRUE.equals(layerMeta.get(MAPML_USE_REMOTE, Boolean.class));
boolean useFeatures = useFeatures(layer, layerMeta);

return new MapMLLayerMetadata(
Expand All @@ -623,6 +618,7 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl
styleName,
tileLayerExists,
useTiles,
useRemote,
useFeatures,
cqlFilter,
defaultMimeType);
Expand Down Expand Up @@ -1335,15 +1331,10 @@ private void generateWMTSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) {
setElevationParam(mapMLLayerMetadata, params, gstl);
setCustomDimensionParam(mapMLLayerMetadata, params, gstl);
setCqlFilterParam(mapMLLayerMetadata, params);
String urlTemplate = "";
try {
urlTemplate =
URLDecoder.decode(
ResponseUtils.buildURL(
baseUrlPattern, path, params, URLMangler.URLType.SERVICE),
"UTF-8");
} catch (UnsupportedEncodingException uee) {
}
MapMLRequestMangler mangler =
new MapMLRequestMangler(
mapContent, mapMLLayerMetadata, baseUrlPattern, path, params, proj);
String urlTemplate = mangler.getUrlTemplate();
tileLink.setTref(urlTemplate);
extentList.add(tileLink);
}
Expand Down Expand Up @@ -1473,15 +1464,10 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
params.put("transparent", Boolean.toString(mapMLLayerMetadata.isTransparent()));
params.put("width", "256");
params.put("height", "256");
String urlTemplate = "";
try {
urlTemplate =
URLDecoder.decode(
ResponseUtils.buildURL(
baseUrlPattern, path, params, URLMangler.URLType.SERVICE),
"UTF-8");
} catch (UnsupportedEncodingException uee) {
}
MapMLRequestMangler mangler =
new MapMLRequestMangler(
mapContent, mapMLLayerMetadata, baseUrlPattern, path, params, proj);
String urlTemplate = mangler.getUrlTemplate();
tileLink.setTref(urlTemplate);
extentList.add(tileLink);
}
Expand Down Expand Up @@ -1611,15 +1597,10 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) {
params.put("language", this.request.getLocale().getLanguage());
params.put("width", "{w}");
params.put("height", "{h}");
String urlTemplate = "";
try {
urlTemplate =
URLDecoder.decode(
ResponseUtils.buildURL(
baseUrlPattern, path, params, URLMangler.URLType.SERVICE),
"UTF-8");
} catch (UnsupportedEncodingException uee) {
}
MapMLRequestMangler mangler =
new MapMLRequestMangler(
mapContent, mapMLLayerMetadata, baseUrlPattern, path, params, proj);
String urlTemplate = mangler.getUrlTemplate();
imageLink.setTref(urlTemplate);
extentList.add(imageLink);
}
Expand Down Expand Up @@ -1660,21 +1641,6 @@ private void createMinAndMaxWidthHeight() {
* Generate inputs and links that the client will use to generate WMTS GetFeatureInfo requests
*/
private void generateWMTSQueryClientLinks(MapMLLayerMetadata mapMLLayerMetadata) {
// query i value (x)
Input input = new Input();
input.setName("i");
input.setType(InputType.LOCATION);
input.setUnits(UnitType.TILE);
input.setAxis(AxisType.I);
extentList.add(input);

// query j value (y)
input = new Input();
input.setName("j");
input.setType(InputType.LOCATION);
input.setUnits(UnitType.TILE);
input.setAxis(AxisType.J);
extentList.add(input);

// query link
Link queryLink = new Link();
Expand All @@ -1695,17 +1661,33 @@ private void generateWMTSQueryClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
params.put("infoformat", "text/mapml");
params.put("i", "{i}");
params.put("j", "{j}");
String urlTemplate = "";
try {
urlTemplate =
URLDecoder.decode(
ResponseUtils.buildURL(
baseUrlPattern, path, params, URLMangler.URLType.SERVICE),
"UTF-8");
} catch (UnsupportedEncodingException uee) {
MapMLRequestMangler mangler =
new MapMLRequestMangler(
mapContent, mapMLLayerMetadata, baseUrlPattern, path, params, proj);
String urlTemplate = mangler.getUrlTemplate();
// It may be that the mangler decided to not generate any query URL due
// to unsupported info formats from the remote layer. So we are not
// generating the query link.
if (urlTemplate != null) {
// query i value (x)
Input input = new Input();
input.setName("i");
input.setType(InputType.LOCATION);
input.setUnits(UnitType.TILE);
input.setAxis(AxisType.I);
extentList.add(input);

// query j value (y)
input = new Input();
input.setName("j");
input.setType(InputType.LOCATION);
input.setUnits(UnitType.TILE);
input.setAxis(AxisType.J);
extentList.add(input);

queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}
queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}

/** Generate inputs and links the client will use to create WMS GetFeatureInfo requests */
Expand All @@ -1714,21 +1696,6 @@ private void generateWMSQueryClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
if (mapMLLayerMetadata.isUseTiles()) {
units = UnitType.TILE;
}
// query i value (x)
Input input = new Input();
input.setName("i");
input.setType(InputType.LOCATION);
input.setUnits(units);
input.setAxis(AxisType.I);
extentList.add(input);

// query j value (y)
input = new Input();
input.setName("j");
input.setType(InputType.LOCATION);
input.setUnits(units);
input.setAxis(AxisType.J);
extentList.add(input);

// query link
Link queryLink = new Link();
Expand All @@ -1744,7 +1711,7 @@ private void generateWMSQueryClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
params.put("layers", mapMLLayerMetadata.getLayerName());
params.put("query_layers", mapMLLayerMetadata.getLayerName());
params.put("styles", mapMLLayerMetadata.getStyleName());
if (mapMLLayerMetadata.getCqlFilter() != null) {
if (StringUtils.isNotBlank(mapMLLayerMetadata.getCqlFilter())) {
params.put("cql_filter", mapMLLayerMetadata.getCqlFilter());
}
setTimeParam(mapMLLayerMetadata, params, null);
Expand All @@ -1764,17 +1731,33 @@ private void generateWMSQueryClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
params.put("transparent", Boolean.toString(mapMLLayerMetadata.isTransparent()));
params.put("x", "{i}");
params.put("y", "{j}");
String urlTemplate = "";
try {
urlTemplate =
URLDecoder.decode(
ResponseUtils.buildURL(
baseUrlPattern, path, params, URLMangler.URLType.SERVICE),
"UTF-8");
} catch (UnsupportedEncodingException uee) {
MapMLRequestMangler mangler =
new MapMLRequestMangler(
mapContent, mapMLLayerMetadata, baseUrlPattern, path, params, proj);
String urlTemplate = mangler.getUrlTemplate();
// It may be that the mangler decided to not generate any query URL due
// to unsupported info formats from the remote layer. So we are not
// generating the query link.
if (urlTemplate != null) {
// query i value (x)
Input input = new Input();
input.setName("i");
input.setType(InputType.LOCATION);
input.setUnits(units);
input.setAxis(AxisType.I);
extentList.add(input);

// query j value (y)
input = new Input();
input.setName("j");
input.setType(InputType.LOCATION);
input.setUnits(units);
input.setAxis(AxisType.J);
extentList.add(input);

queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}
queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}

private void setCqlFilterParam(
Expand Down Expand Up @@ -2333,6 +2316,7 @@ static class MapMLLayerMetadata {
private boolean tileLayerExists;

private boolean useTiles;
private boolean useRemote;

private boolean timeEnabled;
private boolean elevationEnabled;
Expand Down Expand Up @@ -2395,6 +2379,7 @@ public MapMLLayerMetadata(
String styleName,
boolean tileLayerExists,
boolean useTiles,
boolean useRemote,
boolean useFeatures,
String cqFilter,
String defaultMimeType) {
Expand All @@ -2412,6 +2397,7 @@ public MapMLLayerMetadata(
this.isTransparent = isTransparent;
this.tileLayerExists = tileLayerExists;
this.useTiles = useTiles;
this.useRemote = useRemote;
this.useFeatures = useFeatures;
this.cqlFilter = cqFilter;
this.defaultMimeType = defaultMimeType;
Expand Down Expand Up @@ -2738,6 +2724,24 @@ public void setUseTiles(boolean useTiles) {
this.useTiles = useTiles;
}

/**
* get if the layer uses remote
*
* @return boolean
*/
public boolean isUseRemote() {
return useRemote;
}

/**
* set if the layer uses remote
*
* @param useRemote boolean
*/
public void setUseRemote(boolean useRemote) {
this.useRemote = useRemote;
}

/**
* get the ReferencedEnvelope object
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ <h3>
</ul>
</fieldset>
</li>
<div wicket:id="RemoteClientRequestsConfiguration">
<li>
<fieldset>
<legend>
<span><wicket:message key="mapmlClientRequestsSection">Client Requests</wicket:message></span>
</legend>
<ul class="choiceList">
<li>
<input id="useRemote" wicket:id="useRemote" type="checkbox"></input>
<label for="useRemote">
<wicket:message key="mapmlUseRemote">Remote</wicket:message>
</label>
</li>
</ul>
</fieldset>
</li>
</div>
<li>
<fieldset>
<legend>
Expand Down
Loading
Loading