Skip to content

Commit

Permalink
Supporting mapml-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
dromagnoli committed Aug 27, 2024
1 parent 40cb15d commit 667ac05
Show file tree
Hide file tree
Showing 15 changed files with 4,174 additions and 54 deletions.
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 @@ -1695,15 +1676,10 @@ 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();
queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}
Expand Down Expand Up @@ -1744,7 +1720,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,15 +1740,10 @@ 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();
queryLink.setTref(urlTemplate);
extentList.add(queryLink);
}
Expand Down Expand Up @@ -2333,6 +2304,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 +2367,7 @@ public MapMLLayerMetadata(
String styleName,
boolean tileLayerExists,
boolean useTiles,
boolean useRemote,
boolean useFeatures,
String cqFilter,
String defaultMimeType) {
Expand All @@ -2412,6 +2385,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 +2712,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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.stream.Collectors;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.ListMultipleChoice;
Expand All @@ -38,6 +39,9 @@
import org.geoserver.catalog.PublishedType;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.catalog.WMTSStoreInfo;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.layer.GeoServerTileLayer;
import org.geoserver.gwc.layer.GeoServerTileLayerInfo;
Expand Down Expand Up @@ -110,6 +114,10 @@ protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) {
});
add(useTiles);

// Remote client requests
WebMarkupContainer remoteClientRequestContainer = setupRemoteClientRequestContainer(model);
add(remoteClientRequestContainer);

// add the checkbox to select features or not
MapModel<Boolean> useFeaturesModel =
new MapModel<>(
Expand Down Expand Up @@ -186,6 +194,21 @@ protected void onUpdate(AjaxRequestTarget target) {
add(featureCaptionTemplate);
}

private WebMarkupContainer setupRemoteClientRequestContainer(IModel<LayerInfo> model) {
WebMarkupContainer remoteClientRequestContainer =
new WebMarkupContainer("RemoteClientRequestsConfiguration");
LayerInfo layerInfo = model.getObject();
MapModel<Boolean> useRemoteModel =
new MapModel<>(
new PropertyModel<MetadataMap>(model, MapMLConstants.RESOURCE_METADATA),
MapMLConstants.MAPML_USE_REMOTE);
CheckBox useRemote = new CheckBox(MapMLConstants.USE_REMOTE, useRemoteModel);
remoteClientRequestContainer.setOutputMarkupId(true);
remoteClientRequestContainer.setVisible(isWMSOrWMTSStore(layerInfo));
remoteClientRequestContainer.add(useRemote);
return remoteClientRequestContainer;
}

/**
* Get the available mime types for the layer
*
Expand Down Expand Up @@ -298,4 +321,17 @@ private List<String> getAttributeNames(LayerInfo layer) {
return Collections.emptyList();
}
}

private boolean isWMSOrWMTSStore(LayerInfo layerInfo) {
if (layerInfo != null) {
ResourceInfo resourceInfo = layerInfo.getResource();
if (resourceInfo != null) {
StoreInfo storeInfo = resourceInfo.getStore();
if (storeInfo instanceof WMSStoreInfo || storeInfo instanceof WMTSStoreInfo) {
return true;
}
}
}
return false;
}
}
Loading

0 comments on commit 667ac05

Please sign in to comment.