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

Mapml vector tiles - early test #363

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/extension/mapml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.1</version>
<configuration>
<excludes>**/org/geoserver/mapml/xml/**/*</excludes>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.geoserver.mapml.xml.Link;
import org.geoserver.mapml.xml.Mapml;
import org.geoserver.mapml.xml.Meta;
import org.geoserver.mapml.xml.MimeType;
import org.geoserver.mapml.xml.Option;
import org.geoserver.mapml.xml.PositionType;
import org.geoserver.mapml.xml.ProjType;
Expand Down Expand Up @@ -134,7 +135,6 @@ public class MapMLDocumentBuilder {

private Input zoomInput;

private boolean useFeaturesAllLayers = true;
private List<MapMLLayerMetadata> mapMLLayerMetadataList = new ArrayList<>();

private Mapml mapml;
Expand Down Expand Up @@ -285,7 +285,6 @@ public void initialize() throws ServiceException {
MapMLLayerMetadata mapMLLayerMetadata = layersToOneMapMLLayerMetadata(layers);
mapMLLayerMetadataList.add(mapMLLayerMetadata);
}
useFeaturesAllLayers = allLayersUsingFeatures(layers);
// populate Map-wide variables using the first layer
if (!mapMLLayerMetadataList.isEmpty()) {
defaultStyle =
Expand Down Expand Up @@ -355,6 +354,12 @@ private MapMLLayerMetadata layersToOneMapMLLayerMetadata(List<RawLayer> layers)
MapMLLayerMetadata mapMLLayerMetadata = new MapMLLayerMetadata();
mapMLLayerMetadata.setLayerMeta(new MetadataMap());
mapMLLayerMetadata.setUseTiles(false);
boolean useFeatures = false;
if (layers.size() == 1) {
useFeatures =
useFeatures(layers.get(0), layers.get(0).getPublishedInfo().getMetadata());
}
mapMLLayerMetadata.setUseFeatures(useFeatures);
mapMLLayerMetadata.setLayerName(layersCommaDelimited);
mapMLLayerMetadata.setStyleName(stylesCommaDelimited);
mapMLLayerMetadata.setTimeEnabled(false);
Expand All @@ -369,24 +374,6 @@ private MapMLLayerMetadata layersToOneMapMLLayerMetadata(List<RawLayer> layers)
return mapMLLayerMetadata;
}

/**
* Check if all layers in the request use features
*
* @param layers List of RawLayer objects
* @return boolean
*/
private boolean allLayersUsingFeatures(List<RawLayer> layers) {
for (RawLayer layer : layers) {
Boolean useFeatures =
layer.getPublishedInfo().getMetadata().get(MAPML_USE_FEATURES, Boolean.class);
Boolean isVector = (PublishedType.VECTOR == layer.getPublishedInfo().getType());
if (useFeatures == null || isVector == null || !useFeatures || !isVector) {
return false;
}
}
return true;
}

/**
* Parses the projection into a ProjType, or throws a proper service exception indicating the
* unsupported CRS
Expand Down Expand Up @@ -561,7 +548,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 useFeatures = Boolean.TRUE.equals(layerMeta.get(MAPML_USE_FEATURES, Boolean.class));
boolean useFeatures = useFeatures(layer, layerMeta);

return new MapMLLayerMetadata(
layerInfo,
Expand All @@ -581,6 +568,11 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl
useFeatures);
}

private static boolean useFeatures(RawLayer layer, MetadataMap layerMeta) {
return (Boolean.TRUE.equals(layerMeta.get(MAPML_USE_FEATURES, Boolean.class)))
&& (PublishedType.VECTOR == layer.getPublishedInfo().getType());
}

/**
* Match the CRS of the layer to the CRS of the bbox
*
Expand Down Expand Up @@ -1026,7 +1018,8 @@ private void generateTemplatedLinks(MapMLLayerMetadata mapMLLayerMetadata) {

// query inputs
if (mapMLLayerMetadata.isQueryable()
&& !useFeaturesAllLayers) { // No query links for feature representations
&& !mapMLLayerMetadata
.isUseFeatures()) { // No query links for feature representations
if (mapMLLayerMetadata.isUseTiles() && mapMLLayerMetadata.isTileLayerExists()) {
generateWMTSQueryClientLinks(mapMLLayerMetadata);
} else {
Expand Down Expand Up @@ -1221,7 +1214,13 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata)
params.put("elevation", "{elevation}");
}
params.put("bbox", "{txmin},{tymin},{txmax},{tymax}");
params.put("format", imageFormat);
if (mapMLLayerMetadata.isUseFeatures()) {
params.put("format", MAPML_MIME_TYPE);
params.put("format_options", MAPML_FEATURE_FORMAT_OPTIONS);
tileLink.setType(MimeType.TEXT_MAPML);
} else {
params.put("format", imageFormat);
}
params.put("transparent", Boolean.toString(mapMLLayerMetadata.isTransparent()));
params.put("width", "256");
params.put("height", "256");
Expand Down Expand Up @@ -1349,7 +1348,7 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) {

// image link
Link imageLink = new Link();
if (useFeaturesAllLayers) {
if (mapMLLayerMetadata.isUseFeatures()) {
imageLink.setRel(RelType.FEATURES);
} else {
imageLink.setRel(RelType.IMAGE);
Expand All @@ -1369,7 +1368,7 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) {
params.put("elevation", "{elevation}");
}
params.put("bbox", "{xmin},{ymin},{xmax},{ymax}");
if (useFeaturesAllLayers) {
if (mapMLLayerMetadata.isUseFeatures()) {
params.put("format", MAPML_MIME_TYPE);
params.put("format_options", MAPML_FEATURE_FORMAT_OPTIONS);
} else {
Expand Down Expand Up @@ -1633,7 +1632,8 @@ public String getMapMLHTMLDocument() {
escapeHtml4(proj),
styleName,
format))
.append("\" checked></layer->\n")
.append("\" checked>")
.append("</layer->\n")
.append("</mapml-viewer>\n")
.append("</body>\n")
.append("</html>");
Expand All @@ -1657,11 +1657,11 @@ private String buildGetMap(
kvp.put("SRS", escapeHtml4(proj));
kvp.put("STYLES", escapeHtml4(styleName));
kvp.put("FORMAT", MAPML_MIME_TYPE);
kvp.put(
"format_options",
String formatOptions =
MapMLConstants.MAPML_WMS_MIME_TYPE_OPTION
+ ":"
+ escapeHtml4((String) format.orElse("image/png")));
+ escapeHtml4((String) format.orElse("image/png"));
kvp.put("format_options", formatOptions);
kvp.put("SERVICE", "WMS");
kvp.put("REQUEST", "GetMap");
kvp.put("VERSION", "1.3.0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.metadata.iso.citation.Citations;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Envelope;

public class MapMLFeatureUtil {
/**
* Convert a feature collection to a MapML document
*
* @param featureCollection the feature collection to be converted to MapML
* @param layerInfo metadata for the feature class
* @param clipBounds the bounds to clip the features to (or null if not clipping is desired)
* @param requestCRS the CRS requested by the client
* @param alternateProjections alternate projections for the feature collection
* @param numDecimals number of decimal places to use for coordinates
Expand All @@ -55,6 +57,7 @@ public class MapMLFeatureUtil {
public static Mapml featureCollectionToMapML(
FeatureCollection featureCollection,
LayerInfo layerInfo,
Envelope clipBounds,
CoordinateReferenceSystem requestCRS,
List<Link> alternateProjections,
int numDecimals,
Expand Down Expand Up @@ -89,6 +92,9 @@ public static Mapml featureCollectionToMapML(
if (alternateProjections != null) {
links.addAll(alternateProjections);
}
if (clipBounds != null) {
head.setStyle(".bbox{display:none}\n.polygon{fill:yellow; stroke: orange}");
}

String licenseLink = layerMeta.get("mapml.licenseLink", String.class);
String licenseTitle = layerMeta.get("mapml.licenseTitle", String.class);
Expand Down Expand Up @@ -116,13 +122,16 @@ public static Mapml featureCollectionToMapML(
featureBuilder.setNumDecimals(numDecimals);
featureBuilder.setForcedDecimal(forcedDecimal);
featureBuilder.setPadWithZeros(padWithZeros);
featureBuilder.setClipBounds(clipBounds);
try (SimpleFeatureIterator iterator = fc.features()) {
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
// convert feature to xml

Feature f = featureBuilder.buildFeature(feature, fCaptionTemplate);
features.add(f);
if (f != null) {
features.add(f);
}
}
}
return mapml;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.geoserver.wms.MapLayerInfo;
import org.geoserver.wms.WMSMapContent;
import org.geotools.api.data.FeatureSource;
import org.geotools.api.data.Query;
import org.geotools.api.feature.type.FeatureType;
import org.geotools.api.feature.type.GeometryDescriptor;
import org.geotools.api.referencing.FactoryException;
Expand All @@ -33,21 +34,23 @@ public class MapMLFeaturesBuilder {
private final GeoServer geoServer;
private final WMSMapContent mapContent;
private final GetMapRequest getMapRequest;
private final Query query;

/**
* Constructor
*
* @param mapContent the WMS map content
* @param geoServer the GeoServer
*/
public MapMLFeaturesBuilder(WMSMapContent mapContent, GeoServer geoServer) {
public MapMLFeaturesBuilder(WMSMapContent mapContent, GeoServer geoServer, Query query) {
this.geoServer = geoServer;
this.mapContent = mapContent;
this.getMapRequest = mapContent.getRequest();
featureSources =
mapContent.layers().stream()
.map(Layer::getFeatureSource)
.collect(Collectors.toList());
this.query = query;
}

/**
Expand All @@ -67,7 +70,12 @@ public Mapml getMapMLDocument() throws IOException {
throw new ServiceException(
"MapML WMS Feature format does not currently support non-vector layers.");
}
FeatureCollection featureCollection = featureSources.get(0).getFeatures();
FeatureCollection featureCollection = null;
if (query != null) {
featureCollection = featureSources.get(0).getFeatures(query);
} else {
featureCollection = featureSources.get(0).getFeatures();
}
if (!(featureCollection instanceof SimpleFeatureCollection)) {
throw new ServiceException(
"MapML WMS Feature format does not currently support Complex Features.");
Expand Down Expand Up @@ -104,6 +112,7 @@ public Mapml getMapMLDocument() throws IOException {
return MapMLFeatureUtil.featureCollectionToMapML(
reprojectedFeatureCollection,
layerInfo,
getMapRequest.getBbox(), // clip on bound
crs,
null, // for WMS GetMap we don't include alternate projections
getNumberOfDecimals(meta),
Expand Down
Loading
Loading