diff --git a/main.js b/main.js index c68591b..a18f0fa 100644 --- a/main.js +++ b/main.js @@ -6,10 +6,12 @@ import TileLayer from "ol/layer/Tile"; import getWMTSLayer from "./wmts"; import getWMSLayer from "./wms"; import initPopover from "./popover"; +import getWFSLayer from "./wfs"; // Create layer from imported functions const mastermapWMTS = await getWMTSLayer("os_licensed_background_colour"); const woodlandWMS = getWMSLayer("sf_nwss"); +const mastermapWFS = getWFSLayer("osmm:osmm_topographicarea") // Set up a new Tile Layer const openStreetMap = new TileLayer({ @@ -24,7 +26,8 @@ const map = new Map({ layers: [ // openStreetMap, mastermapWMTS, - woodlandWMS, + // woodlandWMS, + mastermapWFS, ], // A View object represents a simple 2D view of the map. // This is the object to act upon to change the center, resolution, and rotation of the map @@ -36,4 +39,4 @@ const map = new Map({ }), }); -initPopover(map, woodlandWMS); \ No newline at end of file +// initPopover(map, woodlandWMS); \ No newline at end of file diff --git a/wfs.js b/wfs.js new file mode 100644 index 0000000..b6affb8 --- /dev/null +++ b/wfs.js @@ -0,0 +1,82 @@ +import { bbox as bboxStrategy } from "ol/loadingstrategy"; +import { WFS } from "ol/format"; +import { Fill, Stroke, Style } from 'ol/style'; +import VectorLayer from "ol/layer/Vector"; +import VectorSource from "ol/source/Vector"; + +// Helper function get a WFS layer from the MapCloud +// Note: The details required to make this request are returned by the CustomerService API +// https://api.themapcloud.com/api/v2/customer-services/details/{mapservice_id} +const getWFSLayer = (layerName) => { + // Extract the featurePrefix and featureType from the full layer name + const [featurePrefix, featureType] = layerName.split(":") + // Create a new instance of the WFS class + // This is a feature format for reading and writing data in the WFS format + const formatWFS = new WFS(); + // Set up our Vector Source for the WFS layer + const sourceWFS = new VectorSource({ + // Define our loader function which will fetch features from our service + loader: (extent) => { + // Create an encoded WFS GetFeature request + const featureRequest = formatWFS.writeGetFeature({ + srsName: "EPSG:27700", + featureNS: `http://thinkwhere.com/${featurePrefix}`, + featurePrefix: featurePrefix, + featureTypes: [featureType], + bbox: extent, + // Geometry name can be variable, but hardcoded for this function + // See note above on how to get these details from tMC API + geometryName: "polygon", + maxFeatures: 1000, + }); + // Make a POST request to the WFS API endpoint + fetch( + `https://api.themapcloud.com/maps/wfs?token=${ + import.meta.env.VITE_TMC_TOKEN + }`, + { + method: "POST", + // Serialise our GetFeature request as a string + body: new XMLSerializer().serializeToString(featureRequest), + } + ) + .then((response) => response.text()) + .then((xml) => { + // Parse response and convert XML (GML) to OpenLayers features + // This is the step that requires the projectionGML object from earlier + let features = formatWFS.readFeatures(xml, { + dataProjection: "EPSG:27700", + featureProjection: "EPSG:27700", + }); + // Add our OL features to the source + sourceWFS.addFeatures(features); + }); + }, + // Define a loading stategy to use for fetching features + // OL has a few built in, or a custom strategy can be created + strategy: bboxStrategy, + }); + + // Define a style to apply to our layer + const wfsStyle = new Style({ + stroke: new Stroke({ + color: 'rgba(0, 0, 255, 1.0)', + width: 2, + }), + fill: new Fill({ + color: 'rgba(0, 0, 255, 0.3)' + }) + }); + + // Create a vector layer using our source and style + const vectorLayer = new VectorLayer({ + source: sourceWFS, + style: wfsStyle, + // A scale threshold is set to limit the number of features returned in one go + minZoom: 14, + }); + + return vectorLayer; +}; + +export default getWFSLayer; diff --git a/wmts.js b/wmts.js index 9534d62..27d245f 100644 --- a/wmts.js +++ b/wmts.js @@ -26,4 +26,4 @@ const getWMTSLayer = async (layerName) => { return wmtsLayer; }; -export default getWMTSLayer; \ No newline at end of file +export default getWMTSLayer;