Skip to content

Commit

Permalink
[GEOS-8891] Make it possible to configure coordinates measures encodi…
Browse files Browse the repository at this point in the history
…ng per layer
  • Loading branch information
Nuno Oliveira authored and aaime committed Aug 20, 2018
1 parent 62176a3 commit ae9528d
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 5 deletions.
2 changes: 2 additions & 0 deletions doc/en/user/source/data/webadmin/layers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ WFS Settings

The list will be used only for the capabilities document generation, but will not be used to limit the actual target SRS usage in GetFeature requests.

* **Encode coordinates measures**-Checking this setting will cause coordinate measures ("M") to be encoded in WFS output formats that support measures. The default (not checked) is to not encode coordinates measures.

WCS Settings
^^^^^^^^^^^^

Expand Down
19 changes: 19 additions & 0 deletions src/main/src/main/java/org/geoserver/catalog/FeatureTypeInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,23 @@ public interface FeatureTypeInfo extends ResourceInfo {
boolean isCircularArcPresent();

void setCircularArcPresent(boolean arcsPresent);

/**
* Controls if coordinates measures should be included in WFS outputs.
*
* @return TRUE if measures should be encoded, otherwise FALSE
*/
default boolean getEncodeMeasures() {
// by default coordinates measures are not encoded
return false;
}

/**
* Sets if coordinates measures should be included in WFS outputs.
*
* @param encodeMeasures TRUE if measures should be encoded, otherwise FALSE
*/
default void setEncodeMeasures(boolean encodeMeasures) {
// nothing to do
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class FeatureTypeInfoImpl extends ResourceInfoImpl implements FeatureType
boolean skipNumberMatched = false;
boolean circularArcPresent;

// we don't use the primitive because we need to detect the situation where no value was set
Boolean encodeMeasures;

public boolean isCircularArcPresent() {
return circularArcPresent;
}
Expand Down Expand Up @@ -239,4 +242,15 @@ public void setCqlFilter(String cqlFilter) {
this.cqlFilter = cqlFilter;
this.filter = null;
}

@Override
public boolean getEncodeMeasures() {
// by default encoding of coordinates measures is not activated
return encodeMeasures == null ? false : encodeMeasures;
}

@Override
public void setEncodeMeasures(boolean encodeMeasures) {
this.encodeMeasures = encodeMeasures;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,14 @@ public String getCqlFilter() {
public void setCqlFilter(String cqlFilter) {
delegate.setCqlFilter(cqlFilter);
}

@Override
public boolean getEncodeMeasures() {
return delegate.getEncodeMeasures();
}

@Override
public void setEncodeMeasures(boolean encodeMeasures) {
delegate.setEncodeMeasures(encodeMeasures);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ <h3><wicket:message key="wfsSettings">WFS Settings</wicket:message></h3>
</ul>
</fieldset>
</li>
<li>
<fieldset>
<legend>
<span><wicket:message key="coordinatesEncodingTitle">Coordinates Encoding</wicket:message></span>
<a href="#" wicket:id="coordinatesEncodingHelp" class="help-link"></a>
</legend>
<ul class="choiceList">
<li>
<input id="encodeMeasures" wicket:id="encodeMeasures" type="checkbox"/>
<label for="encodeMeasures"><wicket:message key="encodeMeasures">Encode coordinates measures</wicket:message></label>
</li>
</ul>
</fieldset>
</li>
</ul>
<div wicket:id="wfsDialog"></div>
</wicket:panel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public WFSLayerConfig(String id, IModel<LayerInfo> model) {
new PropertyModel<Boolean>(model, "resource.skipNumberMatched"));
add(skipNumberMatched);

// coordinates measures encoding
CheckBox encodeMeasures =
new CheckBox(
"encodeMeasures", new PropertyModel<>(model, "resource.encodeMeasures"));
add(encodeMeasures);

// other srs list
dialog = new GeoServerDialog("wfsDialog");
add(dialog);
Expand Down Expand Up @@ -112,5 +118,21 @@ public void onClick(AjaxRequestTarget target) {
"otherSRS.message", WFSLayerConfig.this, null));
}
});
add(
new AjaxLink<String>("coordinatesEncodingHelp") {
private static final long serialVersionUID = 926171216768726057L;

@Override
public void onClick(AjaxRequestTarget target) {
dialog.showInfo(
target,
new StringResourceModel(
"coordinatesEncodingTitle", WFSLayerConfig.this, null),
new StringResourceModel(
"coordinatesEncodingHelp.message",
WFSLayerConfig.this,
null));
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ WFSLayerConfig.otherSRS.message=A comma separated list of EPSG codes, e.g. 4326,
response. The list can be left empty to have no extra SRS declared for this specific type, in \
override to a list of values specified in the WFS service configuration.

WFSLayerConfig.coordinatesEncodingTitle=Coordinates Encoding
WFSLayerConfig.coordinatesEncodingHelp.message=lalala
WFSLayerConfig.encodeMeasures=Encode coordinates measures

SrsNameStyle.NORMAL=EPSG Code
SrsNameStyle.XML=OGC HTTP URL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.web;

import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.tester.FormTester;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.data.test.MockData;
import org.geoserver.web.ComponentBuilder;
import org.geoserver.web.FormTestPage;
import org.geoserver.web.GeoServerWicketTestSupport;
import org.geoserver.wfs.web.publish.WFSLayerConfig;
import org.junit.Test;

/** Contains tests related with WFS specific publishing configuration options * */
public final class WFSLayerConfigTest extends GeoServerWicketTestSupport {

@Test
public void testEncodeMeasuresCheckbox() {
// get a test layer and instantiate the model
final LayerInfo layer = getCatalog().getLayerByName(MockData.PONDS.getLocalPart());
Model<LayerInfo> model = new Model<>(layer);
FormTestPage page =
new FormTestPage((ComponentBuilder) id -> new WFSLayerConfig(id, model));
// let's start the page and check that the components are correctly instantiated
tester.startPage(page);
tester.assertRenderedPage(FormTestPage.class);
tester.assertComponent("form", Form.class);
// check that the checkbox is available
tester.assertComponent("form:panel:encodeMeasures", CheckBox.class);
// unselect the checkbox, no measures should be selected
FormTester ft = tester.newFormTester("form");
ft.setValue("panel:encodeMeasures", false);
ft.submit();
tester.assertModelValue("form:panel:encodeMeasures", false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,34 @@ protected int getNumDecimals(List featureCollections, GeoServer geoServer, Catal
return numDecimals;
}

/**
* Helper method that checks if coordinates measured values should be encoded for the provided
* feature collections. By default coordinates measures are not encoded.
*
* @param featureCollections features collections
* @param catalog GeoServer catalog
* @return TRUE if coordinates measures should be encoded, otherwise FALSE
*/
protected boolean encodeMeasures(List featureCollections, Catalog catalog) {
boolean encodeMeasures = true;
for (int i = 0; i < featureCollections.size(); i++) {
// get the feature type of the current collection
FeatureCollection features = (FeatureCollection) featureCollections.get(i);
FeatureType featureType = features.getSchema();
ResourceInfo resourceInfo =
catalog.getResourceByName(featureType.getName(), ResourceInfo.class);
// let's see if this is a feature type
if (resourceInfo instanceof FeatureTypeInfo) {
FeatureTypeInfo featureTypeInfo = (FeatureTypeInfo) resourceInfo;
if (!featureTypeInfo.getEncodeMeasures()) {
// no measures should be encoded
encodeMeasures = false;
}
}
}
return encodeMeasures;
}

/**
* Serializes the feature collection in the format declared.
*
Expand Down
22 changes: 17 additions & 5 deletions src/wfs/src/main/java/org/geoserver/wfs/xml/GML3OutputFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ protected void write(
Object gft = getFeature.getParameters()[0];

Configuration configuration = customizeConfiguration(this.configuration, ns2metas, gft);
setNumDecimals(configuration, numDecimals);
boolean encodeMeasures = encodeMeasures(featureCollections, catalog);
updateConfiguration(configuration, numDecimals, encodeMeasures);
Encoder encoder = createEncoder(configuration, ns2metas, gft);

encoder.setEncoding(Charset.forName(geoServer.getSettings().getCharset()));
Expand Down Expand Up @@ -308,10 +309,21 @@ protected void write(
}
}

protected void setNumDecimals(Configuration configuration, int numDecimals) {
GMLConfiguration gml = configuration.getDependency(GMLConfiguration.class);
if (gml != null) {
gml.setNumDecimals(numDecimals);
protected void updateConfiguration(
Configuration configuration, int numDecimals, boolean encodeMeasures) {
// GML 3.1. configuration
GMLConfiguration gml31 = configuration.getDependency(GMLConfiguration.class);
if (gml31 != null) {
gml31.setNumDecimals(numDecimals);
gml31.setEncodeMeasures(encodeMeasures);
return;
}
// GML 3.2 configuration
org.geotools.gml3.v3_2.GMLConfiguration gml32 =
configuration.getDependency(org.geotools.gml3.v3_2.GMLConfiguration.class);
if (gml32 != null) {
gml32.setNumDecimals(numDecimals);
gml32.setEncodeMeasures(encodeMeasures);
}
}

Expand Down

0 comments on commit ae9528d

Please sign in to comment.