From 4a224e1bd575077b72726ab9edd1791e2089e495 Mon Sep 17 00:00:00 2001 From: Tom <58078313+reed-tom@users.noreply.github.com> Date: Thu, 20 Jan 2022 15:03:34 -0500 Subject: [PATCH] added vector tile layer handling to OLHelpers and BasemapSwitcher --- src/helpers/OLHelpers.js | 2000 ++++++++++++++-------------- src/map/BasemapSwitcher.jsx | 1239 ++++++++--------- src/map/basemapSwitcherConfig.json | 228 ++-- 3 files changed, 1761 insertions(+), 1706 deletions(-) diff --git a/src/helpers/OLHelpers.js b/src/helpers/OLHelpers.js index 6b693e1e..5a84c703 100644 --- a/src/helpers/OLHelpers.js +++ b/src/helpers/OLHelpers.js @@ -1,8 +1,10 @@ import * as helpers from "./helpers"; // OPEN LAYERS -import { Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer, Group as LayerGroup } from "ol/layer.js"; +import { Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer, Group as LayerGroup, VectorTile as VectorTileLayer } from "ol/layer.js"; import { ImageWMS, OSM, TileArcGISRest, ImageArcGISRest, TileWMS, TileImage, Vector, Stamen, XYZ, ImageStatic } from "ol/source.js"; import WMTS, { optionsFromCapabilities } from "ol/source/WMTS"; +import VectorTileSource from "ol/source/VectorTile"; +import stylefunction from "ol-mapbox-style/dist/stylefunction"; import GML3 from "ol/format/GML3.js"; import GML2 from "ol/format/GML2.js"; @@ -22,1006 +24,1038 @@ import TileGrid from "ol/tilegrid/TileGrid.js"; import { parseString } from "xml2js"; export const OL_LAYER_TYPES = { - Image: "Image", - Tile: "Tile", - Vector: "Vector", - Group: "Group", + Image: "Image", + Tile: "Tile", + Vector: "Vector", + Group: "Group", }; export const OL_DATA_TYPES = { - GML3: "GML3", - GML2: "GML2", - GPX: "GPX", - KML: "KML", - OSMXML: "OSMXML", - EsriJSON: "EsriJSON", - GeoJSON: "GeoJSON", - TopoJSON: "TopoJSON", - IGC: "IGC", - Polyline: "Polyline", - WKT: "WKT", - MVT: "MVT", - XYZ: "XYZ", - OSM: "OSM", - Vector: "Vector", - ImageWMS: "ImageWMS", - TileArcGISRest: "TileArcGISRest", - TileImage: "TileImage", - Stamen: "Stamen", - ImageStatic: "ImageStatic", - WMTS: "WMTS", - TileWMS: "TileWMS", - ImageArcGISRest: "ImageArcGISRest", - LayerGroup: "LayerGroup", + GML3: "GML3", + GML2: "GML2", + GPX: "GPX", + KML: "KML", + OSMXML: "OSMXML", + EsriJSON: "EsriJSON", + GeoJSON: "GeoJSON", + TopoJSON: "TopoJSON", + IGC: "IGC", + Polyline: "Polyline", + WKT: "WKT", + MVT: "MVT", + XYZ: "XYZ", + OSM: "OSM", + Vector: "Vector", + ImageWMS: "ImageWMS", + TileArcGISRest: "TileArcGISRest", + TileImage: "TileImage", + Stamen: "Stamen", + ImageStatic: "ImageStatic", + WMTS: "WMTS", + TileWMS: "TileWMS", + ImageArcGISRest: "ImageArcGISRest", + LayerGroup: "LayerGroup", + VectorTile: "VectorTile", }; export class FeatureHelpers { - static getVectorFormat(format, projection = "EPSG:3857") { - switch (format) { - case OL_DATA_TYPES.GML3: - return new GML3({ srsName: projection }); - case OL_DATA_TYPES.GML2: - return new GML2({ srsName: projection }); - case OL_DATA_TYPES.GPX: - return new GPX(); - case OL_DATA_TYPES.KML: - return new KML(); - case OL_DATA_TYPES.OSMXML: - return new OSMXML(); - case OL_DATA_TYPES.EsriJSON: - return new EsriJSON(); - case OL_DATA_TYPES.GeoJSON: - return new GeoJSON(); - case OL_DATA_TYPES.TopoJSON: - return new TopoJSON(); - case OL_DATA_TYPES.IGC: - return new IGC(); - case OL_DATA_TYPES.Polyline: - return new Polyline(); - case OL_DATA_TYPES.WKT: - return new WKT(); - case OL_DATA_TYPES.MVT: - return new MVT(); + static getVectorFormat(format, projection = "EPSG:3857") { + switch (format) { + case OL_DATA_TYPES.GML3: + return new GML3({ srsName: projection }); + case OL_DATA_TYPES.GML2: + return new GML2({ srsName: projection }); + case OL_DATA_TYPES.GPX: + return new GPX(); + case OL_DATA_TYPES.KML: + return new KML(); + case OL_DATA_TYPES.OSMXML: + return new OSMXML(); + case OL_DATA_TYPES.EsriJSON: + return new EsriJSON(); + case OL_DATA_TYPES.GeoJSON: + return new GeoJSON(); + case OL_DATA_TYPES.TopoJSON: + return new TopoJSON(); + case OL_DATA_TYPES.IGC: + return new IGC(); + case OL_DATA_TYPES.Polyline: + return new Polyline(); + case OL_DATA_TYPES.WKT: + return new WKT(); + case OL_DATA_TYPES.MVT: + return new MVT(); + case OL_DATA_TYPES.VectorTile: + return new VectorTileSource(); + default: + return; + } + } - default: - return; - } - } + static setFeatures(features, target_format = OL_DATA_TYPES.GeoJSON, dataProjection = null, featureProjection = null) { + if (features.length === 0) return; + const mapProjection = featureProjection || window.map.getView().getProjection(); + const parser = this.getVectorFormat(target_format); + let output = undefined; + try { + output = parser.writeFeatures(features, { + dataProjection: dataProjection || parser.readProjection(features), + featureProjection: mapProjection, + }); + } catch (err) { + helpers.showMessage("Error", "Unsupported Feature.", helpers.messageColors.red); + console.log(err); + } + return output; + } + static getFeatures(features, source_format = OL_DATA_TYPES.GeoJSON, projection = "EPSG:3857") { + if (features.length === 0) return; + const mapProjection = window.map.getView().getProjection(); + const parser = this.getVectorFormat(source_format, projection); + let output = undefined; - static setFeatures(features, target_format = OL_DATA_TYPES.GeoJSON, dataProjection = null, featureProjection = null) { - if (features.length === 0) return; - const mapProjection = featureProjection || window.map.getView().getProjection(); - const parser = this.getVectorFormat(target_format); - let output = undefined; - try { - output = parser.writeFeatures(features, { - dataProjection: dataProjection || parser.readProjection(features), - featureProjection: mapProjection, - }); - } catch (err) { - helpers.showMessage("Error", "Unsupported Feature.", helpers.messageColors.red); - console.log(err); - } - return output; - } - static getFeatures(features, source_format = OL_DATA_TYPES.GeoJSON, projection = "EPSG:3857") { - if (features.length === 0) return; - const mapProjection = window.map.getView().getProjection(); - const parser = this.getVectorFormat(source_format, projection); - let output = undefined; - - try { - output = parser.readFeatures(features, { - dataProjection: parser.readProjection(features) || projection, - featureProjection: mapProjection, - }); - } catch (err) { - helpers.showMessage("Error", "Unsupported Feature.", helpers.messageColors.red); - console.log(err); - } - return output; - } - static setGeometry(source_geometry, target_format = OL_DATA_TYPES.GeoJSON) { - const parser = this.getVectorFormat(target_format); - let output = undefined; - try { - output = parser.writeGeometry(source_geometry); - } catch (err) { - helpers.showMessage("Error", "Unsupported Geometry.", helpers.messageColors.red); - console.log(err); - } - return output; - } - static getGeometry(geometry, source_format = OL_DATA_TYPES.GeoJSON) { - const parser = this.getVectorFormat(source_format); - let output = undefined; - try { - output = parser.readGeometry(geometry); - } catch (err) { - helpers.showMessage("Error", "Unsupported Geometry.", helpers.messageColors.red); - console.log(err); - } - return output; - } + try { + output = parser.readFeatures(features, { + dataProjection: parser.readProjection(features) || projection, + featureProjection: mapProjection, + }); + } catch (err) { + helpers.showMessage("Error", "Unsupported Feature.", helpers.messageColors.red); + console.log(err); + } + return output; + } + static setGeometry(source_geometry, target_format = OL_DATA_TYPES.GeoJSON) { + const parser = this.getVectorFormat(target_format); + let output = undefined; + try { + output = parser.writeGeometry(source_geometry); + } catch (err) { + helpers.showMessage("Error", "Unsupported Geometry.", helpers.messageColors.red); + console.log(err); + } + return output; + } + static getGeometry(geometry, source_format = OL_DATA_TYPES.GeoJSON) { + const parser = this.getVectorFormat(source_format); + let output = undefined; + try { + output = parser.readGeometry(geometry); + } catch (err) { + helpers.showMessage("Error", "Unsupported Geometry.", helpers.messageColors.red); + console.log(err); + } + return output; + } } export class LayerHelpers { - static async identifyFeaturesWait(layer, coordinate, callback = undefined) { - const viewResolution = window.map.getView().getResolution(); - const isArcGISLayer = LayerHelpers.getLayerSourceType(layer.getSource()) === OL_DATA_TYPES.ImageArcGISRest; - var url = isArcGISLayer - ? layer.get("wfsUrl") - : layer.getSource().getFeatureInfoUrl(coordinate, viewResolution, "EPSG:3857", { - INFO_FORMAT: "application/json", - }); - const params = {}; - const secureKey = layer.get("secureKey"); - if (secureKey !== undefined) { - const headers = {}; - headers[secureKey] = "GIS"; - params["headers"] = headers; - } - if (isArcGISLayer) { - const arcgisResolution = `${window.map.getSize()[0]},${window.map.getSize()[1]},96`; - const extent = window.map.getView().calculateExtent(); - const zoom = window.map.getView().getZoom(); - const tolerance = 20 - zoom; - url = url - .replace("#GEOMETRY#", coordinate) - .replace("#TOLERANCE#", tolerance >= 10 ? tolerance : 10) - .replace("#EXTENT#", extent.join(",")) - .replace("#RESOLUTION#", arcgisResolution); - } - if (url) { - await helpers.getJSONWaitWithParams(url, params, (result) => { - let features = isArcGISLayer ? LayerHelpers.parseESRIIdentify(result) : new GeoJSON().readFeatures(result); - if (callback === undefined) { - return features.length > 0 ? features[0] : undefined; - } else { - callback(features.length > 0 ? features[0] : undefined); - } - }); - } - } - static identifyFeatures(layer, coordinate, callback) { - const viewResolution = window.map.getView().getResolution(); - const isArcGISLayer = LayerHelpers.getLayerSourceType(layer.getSource()) === OL_DATA_TYPES.ImageArcGISRest; - var url = isArcGISLayer - ? layer.get("wfsUrl") - : layer.getSource().getFeatureInfoUrl(coordinate, viewResolution, "EPSG:3857", { - INFO_FORMAT: "application/json", - }); - const params = {}; - const secureKey = layer.get("secureKey"); - if (secureKey !== undefined) { - const headers = {}; - headers[secureKey] = "GIS"; - params["headers"] = headers; - } - if (isArcGISLayer) { - const arcgisResolution = `${window.map.getSize()[0]},${window.map.getSize()[1]},96`; - const extent = window.map.getView().calculateExtent(); - const zoom = window.map.getView().getZoom(); - const tolerance = 20 - zoom; - url = url - .replace("#GEOMETRY#", coordinate) - .replace("#TOLERANCE#", tolerance >= 10 ? tolerance : 10) - .replace("#EXTENT#", extent.join(",")) - .replace("#RESOLUTION#", arcgisResolution); - } - if (url) { - helpers.getJSONWithParams(url, params, (result) => { - let features = isArcGISLayer ? LayerHelpers.parseESRIIdentify(result) : new GeoJSON().readFeatures(result); - callback(features.length > 0 ? features[0] : undefined); - }); - } - } - static parseESRIIdentify(data) { - let features = []; - if (data.results !== undefined) { - data.results.forEach((item) => { - item["dataProjection"] = item.geometry.spatialReference.latestWkid; - delete item.geometry.spatialReference; - delete item.geometryType; - let keys = Object.keys(item.attributes); - keys.forEach((key) => { - if (item.attributes[key] === "Null" || item.attributes[key] === "") delete item.attributes[key]; - }); + static async identifyFeaturesWait(layer, coordinate, callback = undefined) { + const viewResolution = window.map.getView().getResolution(); + const isArcGISLayer = LayerHelpers.getLayerSourceType(layer.getSource()) === OL_DATA_TYPES.ImageArcGISRest; + var url = isArcGISLayer + ? layer.get("wfsUrl") + : layer.getSource().getFeatureInfoUrl(coordinate, viewResolution, "EPSG:3857", { + INFO_FORMAT: "application/json", + }); + const params = {}; + const secureKey = layer.get("secureKey"); + if (secureKey !== undefined) { + const headers = {}; + headers[secureKey] = "GIS"; + params["headers"] = headers; + } + if (isArcGISLayer) { + const arcgisResolution = `${window.map.getSize()[0]},${window.map.getSize()[1]},96`; + const extent = window.map.getView().calculateExtent(); + const zoom = window.map.getView().getZoom(); + const tolerance = 20 - zoom; + url = url + .replace("#GEOMETRY#", coordinate) + .replace("#TOLERANCE#", tolerance >= 10 ? tolerance : 10) + .replace("#EXTENT#", extent.join(",")) + .replace("#RESOLUTION#", arcgisResolution); + } + if (url) { + await helpers.getJSONWaitWithParams(url, params, (result) => { + let features = isArcGISLayer ? LayerHelpers.parseESRIIdentify(result) : new GeoJSON().readFeatures(result); + if (callback === undefined) { + return features.length > 0 ? features[0] : undefined; + } else { + callback(features.length > 0 ? features[0] : undefined); + } + }); + } + } + static identifyFeatures(layer, coordinate, callback) { + const viewResolution = window.map.getView().getResolution(); + const isArcGISLayer = LayerHelpers.getLayerSourceType(layer.getSource()) === OL_DATA_TYPES.ImageArcGISRest; + var url = isArcGISLayer + ? layer.get("wfsUrl") + : layer.getSource().getFeatureInfoUrl(coordinate, viewResolution, "EPSG:3857", { + INFO_FORMAT: "application/json", + }); + const params = {}; + const secureKey = layer.get("secureKey"); + if (secureKey !== undefined) { + const headers = {}; + headers[secureKey] = "GIS"; + params["headers"] = headers; + } + if (isArcGISLayer) { + const arcgisResolution = `${window.map.getSize()[0]},${window.map.getSize()[1]},96`; + const extent = window.map.getView().calculateExtent(); + const zoom = window.map.getView().getZoom(); + const tolerance = 20 - zoom; + url = url + .replace("#GEOMETRY#", coordinate) + .replace("#TOLERANCE#", tolerance >= 10 ? tolerance : 10) + .replace("#EXTENT#", extent.join(",")) + .replace("#RESOLUTION#", arcgisResolution); + } + if (url) { + helpers.getJSONWithParams(url, params, (result) => { + let features = isArcGISLayer ? LayerHelpers.parseESRIIdentify(result) : new GeoJSON().readFeatures(result); + callback(features.length > 0 ? features[0] : undefined); + }); + } + } + static parseESRIIdentify(data) { + let features = []; + if (data.results !== undefined) { + data.results.forEach((item) => { + item["dataProjection"] = item.geometry.spatialReference.latestWkid; + delete item.geometry.spatialReference; + delete item.geometryType; + let keys = Object.keys(item.attributes); + keys.forEach((key) => { + if (item.attributes[key] === "Null" || item.attributes[key] === "") delete item.attributes[key]; + }); + + let tempFeature = new EsriJSON().readFeature(item); + tempFeature.setProperties({ displayFieldName: item.displayFieldName }); + tempFeature.setProperties({ displayFieldValue: item.value }); + features.push(tempFeature); + }); + } + return features; + } + static getCapabilities(options, callback) { + let { root_url, type } = options; - let tempFeature = new EsriJSON().readFeature(item); - tempFeature.setProperties({ displayFieldName: item.displayFieldName }); - tempFeature.setProperties({ displayFieldValue: item.value }); - features.push(tempFeature); - }); - } - return features; - } - static getCapabilities(options, callback) { - let { root_url, type } = options; + type = type.toLowerCase(); + var url = ""; + if (root_url.indexOf("GetCapabilities") === -1) { + url = /\?/.test(root_url) ? root_url.split("?")[0] + "?" : root_url + "?"; + } else { + url = root_url; + } + let layers = []; + var parser; + var response; + var service; + if (url.indexOf("Capabilities") === -1) { + switch (type) { + case "wmts": + service = "WMTS"; + url = url + "REQUEST=GetCapabilities&SERVICE=" + service; + break; + case "wms": + service = "WMS"; + url = url + "REQUEST=GetCapabilities&SERVICE=" + service; + break; + case "rest": + service = "json"; + url = root_url + "/layers?f=json"; + break; + default: + service = "WFS"; + url = url + "REQUEST=GetCapabilities&SERVICE=" + service; + break; + } + } + const params = {}; + if (options.requireToken) { + const headers = {}; + //headers["token"] = "GIS"; + params["headers"] = headers; + } + helpers.httpGetTextWithParams(url, params, (responseText) => { + if (responseText === null) { + callback([]); + return; + } + try { + switch (type) { + case "wmts": + parser = new WMTSCapabilities(); + response = parser.read(responseText); + response.Contents.Layer.forEach((layer) => { + layers.push({ + label: layer.Title, + value: helpers.getUID(), + style: this.getSytle(layer), + layer_name: layer.Identifier, + }); + }); + //fix to get react-select box to update on the fly + layers = layers.concat([]); + callback(layers); + break; + case "wms": + parser = new WMSCapabilities(); + response = parser.read(responseText); + let layerGroup = response.Capability.Layer.Layer; + if (layerGroup[0].Layer !== undefined) layerGroup = layerGroup[0].Layer; + layerGroup.forEach((layer) => { + this.getWMSLayers(layer, (item) => { + if (item !== undefined) { + item["url"] = root_url; + layers.push(item); + } + }); + }); + //fix to get react-select box to update on the fly + layers = layers.concat([]); + callback(layers); + break; + case "rest": + response = JSON.parse(responseText); + if (response.layers !== undefined) { + this.getESRILegend(`${root_url}/legend?f=json`, (legends) => { + response.layers.forEach((item) => { + if (item !== undefined) { + item["layer_name"] = item.name; + item["rootUrl"] = root_url; + item["originalMinScale"] = item.minScale; + item["originalMaxScale"] = item.maxScale; + item.minScale = item.originalMaxScale; + item.maxScale = item.originalMinScale; + if (item.minScale === item.maxScale) { + item.minScale = undefined; + item.maxScale = undefined; + } + item["value"] = helpers.getUID(); + item["label"] = item.name; + item["queryable"] = true; + item["legend"] = legends.filter((legend) => { + return legend.layerId === item.id; + })[0]; + if (item.drawingInfo !== undefined && item.drawingInfo.renderer !== undefined && item.drawingInfo.renderer.symbol !== undefined && item.legend === undefined) + item["style"] = `data:${item.drawingInfo.renderer.symbol.contentType};base64,${item.drawingInfo.renderer.symbol.imageData}`; + item["url"] = `${root_url}/${item.id}`; + layers.push(item); + } + }); + //fix to get react-select box to update on the fly + layers = layers.concat([]); + callback(layers); + }); + } else { + callback([]); + return; + } + break; + default: + parseString(responseText, function (err, result) { + result["wfs:WFS_Capabilities"].FeatureTypeList[0].FeatureType.forEach((layer) => { + var layerTitle = layer.Title[0]; + var layerName = layer.Name[0]; + if (layerTitle === undefined || layerTitle === "") layerTitle = layerName; + layers.push({ + label: layerTitle, + value: helpers.getUID(), + layer_name: layerName, + }); + }); + }); + //fix to get react-select box to update on the fly + layers = layers.concat([]); + callback(layers); + break; + } + } catch (error) { + console.warn("Unexpected error: " + error.message); + callback(layers); + } + }); + } + static getESRILegend(url, callback) { + helpers.httpGetText(url, (responseText) => { + var response = JSON.parse(responseText); + if (response.layers === undefined) callback(); + else callback(response.layers); + }); + } + static getWMSLayers(layer, callback) { + var label = layer.Title !== "" ? layer.Title : layer.Name; + var value = layer.Name; + var queryable = layer.queryable; + var opaque = layer.opaque; + var keywords = layer.KeywordList; + if (layer.Layer === undefined) { + callback({ + label: label, + value: helpers.getUID(), + layer_name: value, + style: this.getSytle(layer), + queryable: queryable, + opaque: opaque, + keywords: keywords, + }); + } else { + callback(); + } + } + static getAllWMSLayers(layer, callback) { + let layers = []; + var label = layer.Title !== "" ? layer.Title : layer.Name; + var value = layer.Name; + var queryable = layer.queryable; + var opaque = layer.opaque; + var keywords = layer.KeywordList; + if (layer.Layer === undefined) { + layers.push({ + label: label, + value: helpers.getUID(), + layer_name: value, + style: this.getSytle(layer), + queryable: queryable, + opaque: opaque, + keywords: keywords, + }); + } else { + layer.Layer.forEach((item) => { + this.getAllWMSLayers(item, (result) => { + layers = layers.concat(result); + }); + }); + } + layers = layers.concat([]); + callback(layers); + } - type = type.toLowerCase(); - var url = ""; - if (root_url.indexOf("GetCapabilities") === -1) { - url = /\?/.test(root_url) ? root_url.split("?")[0] + "?" : root_url + "?"; - } else { - url = root_url; - } - let layers = []; - var parser; - var response; - var service; - if (url.indexOf("Capabilities") === -1) { - switch (type) { - case "wmts": - service = "WMTS"; - url = url + "REQUEST=GetCapabilities&SERVICE=" + service; - break; - case "wms": - service = "WMS"; - url = url + "REQUEST=GetCapabilities&SERVICE=" + service; - break; - case "rest": - service = "json"; - url = root_url + "/layers?f=json"; - break; - default: - service = "WFS"; - url = url + "REQUEST=GetCapabilities&SERVICE=" + service; - break; - } - } - const params = {}; - if (options.requireToken) { - const headers = {}; - //headers["token"] = "GIS"; - params["headers"] = headers; - } - helpers.httpGetTextWithParams(url, params, (responseText) => { - if (responseText === null) { - callback([]); - return; - } - try { - switch (type) { - case "wmts": - parser = new WMTSCapabilities(); - response = parser.read(responseText); - response.Contents.Layer.forEach((layer) => { - layers.push({ - label: layer.Title, - value: helpers.getUID(), - style: this.getSytle(layer), - layer_name: layer.Identifier, - }); - }); - //fix to get react-select box to update on the fly - layers = layers.concat([]); - callback(layers); - break; - case "wms": - parser = new WMSCapabilities(); - response = parser.read(responseText); - let layerGroup = response.Capability.Layer.Layer; - if (layerGroup[0].Layer !== undefined) layerGroup = layerGroup[0].Layer; - layerGroup.forEach((layer) => { - this.getWMSLayers(layer, (item) => { - if (item !== undefined) { - item["url"] = root_url; - layers.push(item); - } - }); - }); - //fix to get react-select box to update on the fly - layers = layers.concat([]); - callback(layers); - break; - case "rest": - response = JSON.parse(responseText); - if (response.layers !== undefined) { - this.getESRILegend(`${root_url}/legend?f=json`, (legends) => { - response.layers.forEach((item) => { - if (item !== undefined) { - item["layer_name"] = item.name; - item["rootUrl"] = root_url; - item["originalMinScale"] = item.minScale; - item["originalMaxScale"] = item.maxScale; - item.minScale = item.originalMaxScale; - item.maxScale = item.originalMinScale; - if (item.minScale === item.maxScale) { - item.minScale = undefined; - item.maxScale = undefined; - } - item["value"] = helpers.getUID(); - item["label"] = item.name; - item["queryable"] = true; - item["legend"] = legends.filter((legend) => { - return legend.layerId === item.id; - })[0]; - if (item.drawingInfo !== undefined && item.drawingInfo.renderer !== undefined && item.drawingInfo.renderer.symbol !== undefined && item.legend === undefined) - item["style"] = `data:${item.drawingInfo.renderer.symbol.contentType};base64,${item.drawingInfo.renderer.symbol.imageData}`; - item["url"] = `${root_url}/${item.id}`; - layers.push(item); - } - }); - //fix to get react-select box to update on the fly - layers = layers.concat([]); - callback(layers); - }); - } else { - callback([]); - return; - } - break; - default: - parseString(responseText, function (err, result) { - result["wfs:WFS_Capabilities"].FeatureTypeList[0].FeatureType.forEach((layer) => { - var layerTitle = layer.Title[0]; - var layerName = layer.Name[0]; - if (layerTitle === undefined || layerTitle === "") layerTitle = layerName; - layers.push({ - label: layerTitle, - value: helpers.getUID(), - layer_name: layerName, - }); - }); - }); - //fix to get react-select box to update on the fly - layers = layers.concat([]); - callback(layers); - break; - } - } catch (error) { - console.warn("Unexpected error: " + error.message); - callback(layers); - } - }); - } - static getESRILegend(url, callback) { - helpers.httpGetText(url, (responseText) => { - var response = JSON.parse(responseText); - if (response.layers === undefined) callback(); - else callback(response.layers); - }); - } - static getWMSLayers(layer, callback) { - var label = layer.Title !== "" ? layer.Title : layer.Name; - var value = layer.Name; - var queryable = layer.queryable; - var opaque = layer.opaque; - var keywords = layer.KeywordList; - if (layer.Layer === undefined) { - callback({ - label: label, - value: helpers.getUID(), - layer_name: value, - style: this.getSytle(layer), - queryable: queryable, - opaque: opaque, - keywords: keywords, - }); - } else { - callback(); - } - } - static getAllWMSLayers(layer, callback) { - let layers = []; - var label = layer.Title !== "" ? layer.Title : layer.Name; - var value = layer.Name; - var queryable = layer.queryable; - var opaque = layer.opaque; - var keywords = layer.KeywordList; - if (layer.Layer === undefined) { - layers.push({ - label: label, - value: helpers.getUID(), - layer_name: value, - style: this.getSytle(layer), - queryable: queryable, - opaque: opaque, - keywords: keywords, - }); - } else { - layer.Layer.forEach((item) => { - this.getAllWMSLayers(item, (result) => { - layers = layers.concat(result); - }); - }); - } - layers = layers.concat([]); - callback(layers); - } + static getLayerType(layer) { + if (layer instanceof TileLayer) return OL_LAYER_TYPES.Tile; + if (layer instanceof ImageLayer) return OL_LAYER_TYPES.Image; + if (layer instanceof VectorLayer) return OL_LAYER_TYPES.Vector; + if (layer instanceof LayerGroup) return OL_LAYER_TYPES.Group; + return "unknown"; + } - static getLayerType(layer) { - if (layer instanceof TileLayer) return OL_LAYER_TYPES.Tile; - if (layer instanceof ImageLayer) return OL_LAYER_TYPES.Image; - if (layer instanceof VectorLayer) return OL_LAYER_TYPES.Vector; - if (layer instanceof LayerGroup) return OL_LAYER_TYPES.Group; - return "unknown"; - } + static getLayerSourceType(source) { + if (source instanceof GML3) return OL_DATA_TYPES.GML3; + if (source instanceof GML2) return OL_DATA_TYPES.GML2; + if (source instanceof GPX) return OL_DATA_TYPES.GPX; + if (source instanceof KML) return OL_DATA_TYPES.KML; + if (source instanceof OSMXML) return OL_DATA_TYPES.OSMXML; + if (source instanceof EsriJSON) return OL_DATA_TYPES.EsriJSON; + if (source instanceof GeoJSON) return OL_DATA_TYPES.GeoJSON; + if (source instanceof TopoJSON) return OL_DATA_TYPES.TopoJSON; + if (source instanceof IGC) return OL_DATA_TYPES.IGC; + if (source instanceof Polyline) return OL_DATA_TYPES.Polyline; + if (source instanceof WKT) return OL_DATA_TYPES.WKT; + if (source instanceof MVT) return OL_DATA_TYPES.MVT; + if (source instanceof XYZ) return OL_DATA_TYPES.XYZ; + if (source instanceof OSM) return OL_DATA_TYPES.OSM; + if (source instanceof Vector) return OL_DATA_TYPES.Vector; + if (source instanceof ImageWMS) return OL_DATA_TYPES.ImageWMS; + if (source instanceof TileArcGISRest) return OL_DATA_TYPES.TileArcGISRest; + if (source instanceof ImageArcGISRest) return OL_DATA_TYPES.ImageArcGISRest; + if (source instanceof TileImage) return OL_DATA_TYPES.TileImage; + if (source instanceof Stamen) return OL_DATA_TYPES.Stamen; + if (source instanceof ImageStatic) return OL_DATA_TYPES.ImageStatic; + if (source instanceof WMTS) return OL_DATA_TYPES.WMTS; + if (source instanceof TileWMS) return OL_DATA_TYPES.TileWMS; + if (source instanceof VectorTileSource) return OL_DATA_TYPES.VectorTile; - static getLayerSourceType(source) { - if (source instanceof GML3) return OL_DATA_TYPES.GML3; - if (source instanceof GML2) return OL_DATA_TYPES.GML2; - if (source instanceof GPX) return OL_DATA_TYPES.GPX; - if (source instanceof KML) return OL_DATA_TYPES.KML; - if (source instanceof OSMXML) return OL_DATA_TYPES.OSMXML; - if (source instanceof EsriJSON) return OL_DATA_TYPES.EsriJSON; - if (source instanceof GeoJSON) return OL_DATA_TYPES.GeoJSON; - if (source instanceof TopoJSON) return OL_DATA_TYPES.TopoJSON; - if (source instanceof IGC) return OL_DATA_TYPES.IGC; - if (source instanceof Polyline) return OL_DATA_TYPES.Polyline; - if (source instanceof WKT) return OL_DATA_TYPES.WKT; - if (source instanceof MVT) return OL_DATA_TYPES.MVT; - if (source instanceof XYZ) return OL_DATA_TYPES.XYZ; - if (source instanceof OSM) return OL_DATA_TYPES.OSM; - if (source instanceof Vector) return OL_DATA_TYPES.Vector; - if (source instanceof ImageWMS) return OL_DATA_TYPES.ImageWMS; - if (source instanceof TileArcGISRest) return OL_DATA_TYPES.TileArcGISRest; - if (source instanceof ImageArcGISRest) return OL_DATA_TYPES.ImageArcGISRest; - if (source instanceof TileImage) return OL_DATA_TYPES.TileImage; - if (source instanceof Stamen) return OL_DATA_TYPES.Stamen; - if (source instanceof ImageStatic) return OL_DATA_TYPES.ImageStatic; - if (source instanceof WMTS) return OL_DATA_TYPES.WMTS; - if (source instanceof TileWMS) return OL_DATA_TYPES.TileWMS; - return "unknown"; - } - static getSytle(layer) { - let style = ""; - try { - style = layer.Style[0].LegendURL[0].OnlineResource; - } catch {} - return style !== undefined ? style : ""; - } - static getGroupedLayer(options, callback) { - let layerOptions = options.layers; - let name = options.name !== undefined ? options.name : ""; - let layers = []; - const rebuildParams = { - name: name, - layers: layerOptions, - }; - layerOptions.forEach((layerOption) => { - this.getLayer( - { - sourceType: layerOption.sourceType, - source: "rest", - layerName: layerOption.name, - url: layerOption.url, - tiled: false, - extent: layerOption.extent, - name: layerOption.name, - }, - (layer) => { - layers.push(layer); - if (layers.length >= layerOptions.length) { - callback( - new LayerGroup({ - name: name, - rebuildParams: rebuildParams, - layers: layers, - }) - ); - } - } - ); - }); - } + return "unknown"; + } + static getSytle(layer) { + let style = ""; + try { + style = layer.Style[0].LegendURL[0].OnlineResource; + } catch {} + return style !== undefined ? style : ""; + } + static getGroupedLayer(options, callback) { + let layerOptions = options.layers; + let name = options.name !== undefined ? options.name : ""; + let layers = []; + const rebuildParams = { + name: name, + layers: layerOptions, + }; + layerOptions.forEach((layerOption) => { + this.getLayer( + { + sourceType: layerOption.sourceType, + source: "rest", + layerName: layerOption.name, + url: layerOption.url, + tiled: false, + extent: layerOption.extent, + name: layerOption.name, + }, + (layer) => { + layers.push(layer); + if (layers.length >= layerOptions.length) { + callback( + new LayerGroup({ + name: name, + rebuildParams: rebuildParams, + layers: layers, + }) + ); + } + } + ); + }); + } - static getLayer(options, callback) { - let sourceType = options.sourceType; - let source = options.source; - let projection = options.projection !== undefined ? options.projection : "EPSG:3857"; - let layerName = options.layerName; - let url = options.url; - let tiled = options.tiled !== undefined ? options.tiled : false; - let file = options.file; - let extent = options.extent !== undefined ? options.extent : []; - let name = options.name !== undefined ? options.name : ""; - let secureKey = options.secureKey; + static getLayer(options, callback) { + let sourceType = options.sourceType; + let source = options.source; + let projection = options.projection !== undefined ? options.projection : "EPSG:3857"; + let layerName = options.layerName; + let url = options.url; + let tiled = options.tiled !== undefined ? options.tiled : false; + let file = options.file; + let extent = options.extent !== undefined ? options.extent : []; + let name = options.name !== undefined ? options.name : ""; + let secureKey = options.secureKey; - const rebuildParams = { - sourceType: sourceType, - source: source, - projection: projection, - layerName: layerName, - url: url, - tiled: tiled, - file: file !== undefined ? "STORED FEATURES" : undefined, - extent: extent, - name: name, - }; - let Vector_FileLoader = undefined; - let style = undefined; + const rebuildParams = { + sourceType: sourceType, + source: source, + projection: projection, + layerName: layerName, + url: url, + tiled: tiled, + file: file !== undefined ? "STORED FEATURES" : undefined, + extent: extent, + name: name, + }; + let Vector_FileLoader = undefined; + let style = undefined; - // console.log(url); - switch (source) { - case "remote": - const featureParser = FeatureHelpers.getVectorFormat(sourceType, projection); - Vector_FileLoader = function (extent, resolution, proj) { - try { - console.log(extent, resolution, proj); - const mapProjection = window.map.getView().getProjection(); - var _this = this; - var remoteUrl = `${url}/query?f=json`; - remoteUrl += `&returnGeometry=true`; - remoteUrl += `&geometryType=esriGeometryEnvelope`; - remoteUrl += `&spatialRel=esriSpatialRelIntersects`; - remoteUrl += `&geometry=`; - remoteUrl += encodeURIComponent(`{"xmin":${proj.extent_[0]},"ymin":${proj.extent_[1]},"xmax":${proj.extent_[2]},"ymax":${proj.extent_[3]},"spatialReference":{"wkid":102100}}`); - remoteUrl += `&inSR=3857`; - remoteUrl += `&outFields=*`; - remoteUrl += `&outSR=3857`; - helpers.getJSON(remoteUrl, (response) => { - _this.addFeatures( - featureParser.readFeatures(response, { - dataProjection: featureParser.readProjection(response) || projection, - featureProjection: mapProjection, - }) - ); - }); - } catch (error) { - console.log(error); - } - }; - break; - case "file": - if (file === undefined) { - console.error("Missing File for Vector layer."); - return; - } - //return empty vector layer if file - else if (file === "STORED FEATURES") { - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - }), - }) - ); - return; - } else { - if (name.length < 1) name = file.name; - url = undefined; - const featureParser = FeatureHelpers.getVectorFormat(sourceType, projection); - Vector_FileLoader = function (extent, resolution, proj) { - try { - const mapProjection = window.map.getView().getProjection(); - var _this = this; - var fr = new FileReader(); - fr.onload = function (evt) { - var vectorData = evt.target.result; - _this.addFeatures( - featureParser.readFeatures(vectorData, { - dataProjection: featureParser.readProjection(vectorData) || projection, - featureProjection: mapProjection, - }) - ); - }; - fr.readAsText(file); - } catch (error) { - console.log(error); - } - }; - } - break; - case "wfs": - const type = sourceType === OL_DATA_TYPES.GeoJSON ? "application/json" : sourceType; - url = /^((http)|(https))(:\/\/)/.test(url) ? url : "https://" + url; - url = /\?/.test(url) ? url + "&" : url + "?"; - url = url + "SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAME=" + layerName + "&SRSNAME=" + projection + "&OUTPUTFORMAT=" + type; - if (tiled) - url = function (extent, resolution, proj) { - return url + "&bbox=" + extent.join(",") + "," + proj.getCode(); - }; - if (name.length < 1) { - name = layerName + " WFS"; - } - break; - default: - if (name.length < 1) name = layerName; - break; - } + // console.log(url); + switch (source) { + case "remote": + const featureParser = FeatureHelpers.getVectorFormat(sourceType, projection); + Vector_FileLoader = function (extent, resolution, proj) { + try { + console.log(extent, resolution, proj); + const mapProjection = window.map.getView().getProjection(); + var _this = this; + var remoteUrl = `${url}/query?f=json`; + remoteUrl += `&returnGeometry=true`; + remoteUrl += `&geometryType=esriGeometryEnvelope`; + remoteUrl += `&spatialRel=esriSpatialRelIntersects`; + remoteUrl += `&geometry=`; + remoteUrl += encodeURIComponent(`{"xmin":${proj.extent_[0]},"ymin":${proj.extent_[1]},"xmax":${proj.extent_[2]},"ymax":${proj.extent_[3]},"spatialReference":{"wkid":102100}}`); + remoteUrl += `&inSR=3857`; + remoteUrl += `&outFields=*`; + remoteUrl += `&outSR=3857`; + helpers.getJSON(remoteUrl, (response) => { + _this.addFeatures( + featureParser.readFeatures(response, { + dataProjection: featureParser.readProjection(response) || projection, + featureProjection: mapProjection, + }) + ); + }); + } catch (error) { + console.log(error); + } + }; + break; + case "file": + if (file === undefined) { + console.error("Missing File for Vector layer."); + return; + } + //return empty vector layer if file + else if (file === "STORED FEATURES") { + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + }), + }) + ); + return; + } else { + if (name.length < 1) name = file.name; + url = undefined; + const featureParser = FeatureHelpers.getVectorFormat(sourceType, projection); + Vector_FileLoader = function (extent, resolution, proj) { + try { + const mapProjection = window.map.getView().getProjection(); + var _this = this; + var fr = new FileReader(); + fr.onload = function (evt) { + var vectorData = evt.target.result; + _this.addFeatures( + featureParser.readFeatures(vectorData, { + dataProjection: featureParser.readProjection(vectorData) || projection, + featureProjection: mapProjection, + }) + ); + }; + fr.readAsText(file); + } catch (error) { + console.log(error); + } + }; + } + break; + case "wfs": + const type = sourceType === OL_DATA_TYPES.GeoJSON ? "application/json" : sourceType; + url = /^((http)|(https))(:\/\/)/.test(url) ? url : "https://" + url; + url = /\?/.test(url) ? url + "&" : url + "?"; + url = url + "SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAME=" + layerName + "&SRSNAME=" + projection + "&OUTPUTFORMAT=" + type; + if (tiled) + url = function (extent, resolution, proj) { + return url + "&bbox=" + extent.join(",") + "," + proj.getCode(); + }; + if (name.length < 1) { + name = layerName + " WFS"; + } + break; + default: + if (name.length < 1) name = layerName; + break; + } - switch (sourceType) { - case OL_DATA_TYPES.GML3: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new GML3({ srsName: projection }), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.GML2: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new GML2({ srsName: projection }), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.GPX: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new GPX(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.KML: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new KML(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.OSMXML: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new OSMXML(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.EsriJSON: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ tileSize: 512, maxZoom: 19 })) : LoadingStrategyAll, - format: new EsriJSON(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - style: style, - }) - ); - break; - case OL_DATA_TYPES.GeoJSON: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new GeoJSON(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.TopoJSON: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new TopoJSON(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.IGC: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new IGC(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.Polyline: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new Polyline(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.WKT: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new WKT(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.MVT: - callback( - new VectorLayer({ - rebuildParams: rebuildParams, - source: new Vector({ - name: name, - url: url, - strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, - format: new MVT(), - loader: Vector_FileLoader, - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.ImageWMS: - const securedImageWMS = function (image, src) { - var xhr = new XMLHttpRequest(); - xhr.open("GET", src); - xhr.responseType = "arraybuffer"; - if (secureKey !== undefined) xhr.setRequestHeader(secureKey, "GIS"); - xhr.onload = function () { - var arrayBufferView = new Uint8Array(this.response); - var blob = new Blob([arrayBufferView], { type: "image/png" }); - var urlCreator = window.URL || window.webkitURL; - var imageUrl = urlCreator.createObjectURL(blob); - image.getImage().src = imageUrl; - }; - xhr.send(); - }; - callback( - new ImageLayer({ - rebuildParams: rebuildParams, - name: name, - source: new ImageWMS({ - url: url, - params: { - VERSION: "1.3.0", - LAYERS: layerName, - cql_filter: null, - }, - ratio: 1, - serverType: "geoserver", - crossOrigin: "anonymous", - imageLoadFunction: securedImageWMS, - }), - }) - ); - break; - case OL_DATA_TYPES.TileWMS: - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - source: new TileWMS({ - url: url, - projection: projection, - params: { - VERSION: "1.3.0", - LAYERS: layerName, - tiled: true, - cql_filter: null, - }, - tileOptions: { crossOriginKeyword: "anonymous" }, - ratio: 1, - serverType: "geoserver", - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.ImageArcGISRest: - let urlArray = url.split("/"); - let url_layer = urlArray[urlArray.length - 1]; - urlArray.pop(); - url = urlArray.join("/"); - const sourceParams = { - url: url, - params: { LAYERS: `SHOW:${url_layer}` }, - ratio: 1, - projection: projection, - crossOrigin: "anonymous", - }; - if (extent !== undefined) sourceParams["extent"] = [extent.xmin, extent.ymin, extent.xmax, extent.ymax]; - callback( - new ImageLayer({ - rebuildParams: rebuildParams, - name: name, - source: new ImageArcGISRest(sourceParams), - }) - ); - break; - case OL_DATA_TYPES.WMTS: - const rootUrl = url.replace("1.0.0/WMTSCapabilities.xml", ""); - const convertExtent = (extent, sourceCoord, targetCoord) => { - return transform([extent[0], extent[1]], sourceCoord, targetCoord).concat(transform([extent[2], extent[3]], sourceCoord, targetCoord)); - }; - const wmtsCap = (url, callback) => { - helpers.httpGetText(url.indexOf("Capabilities") === -1 ? (/\?/.test(url) ? url + "&" : url + "?") + "REQUEST=GetCapabilities&SERVICE=WMTS" : url, (responseText) => { - try { - var parser = new WMTSCapabilities(); - callback(parser.read(responseText)); - } catch (error) { - console.warn("Unexpected error: " + error.message); - } - }); - }; + switch (sourceType) { + case OL_DATA_TYPES.GML3: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new GML3({ srsName: projection }), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.GML2: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new GML2({ srsName: projection }), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.GPX: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new GPX(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.KML: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new KML(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.OSMXML: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new OSMXML(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.EsriJSON: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ tileSize: 512, maxZoom: 19 })) : LoadingStrategyAll, + format: new EsriJSON(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + style: style, + }) + ); + break; + case OL_DATA_TYPES.GeoJSON: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new GeoJSON(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.TopoJSON: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new TopoJSON(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.IGC: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new IGC(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.Polyline: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new Polyline(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.WKT: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new WKT(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.MVT: + callback( + new VectorLayer({ + rebuildParams: rebuildParams, + source: new Vector({ + name: name, + url: url, + strategy: tiled ? LoadingStrategyTile(TileGrid.createXYZ({ maxZoom: 19 })) : LoadingStrategyAll, + format: new MVT(), + loader: Vector_FileLoader, + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.VectorTile: + let layer = new VectorTileLayer({ + rebuildParams: rebuildParams, + renderMode: "vector", + reload: Infinity, + declutter: true, + tilePixelRatio: 8, + source: new VectorTileSource({ + name: name, + format: new MVT(), + url: url + "/tile/{z}/{y}/{x}.pbf", + crossOrigin: "anonymous", + }), + }); + let rootPath = url + "/resources/styles/root.json"; + let spritePath = url + "/resources/sprites/sprite.json"; + let pngPath = url + "/resources/sprites/sprite.png"; + fetch(rootPath).then(function (response) { + response.json().then(function (glStyle) { + fetch(spritePath).then(function (response) { + response.json().then(function (spriteData) { + stylefunction(layer, glStyle, "esri", undefined, spriteData, pngPath); + }); + }); + }); + }); + callback(layer); + break; + case OL_DATA_TYPES.ImageWMS: + const securedImageWMS = function (image, src) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", src); + xhr.responseType = "arraybuffer"; + if (secureKey !== undefined) xhr.setRequestHeader(secureKey, "GIS"); + xhr.onload = function () { + var arrayBufferView = new Uint8Array(this.response); + var blob = new Blob([arrayBufferView], { type: "image/png" }); + var urlCreator = window.URL || window.webkitURL; + var imageUrl = urlCreator.createObjectURL(blob); + image.getImage().src = imageUrl; + }; + xhr.send(); + }; + callback( + new ImageLayer({ + rebuildParams: rebuildParams, + name: name, + source: new ImageWMS({ + url: url, + params: { + VERSION: "1.3.0", + LAYERS: layerName, + cql_filter: null, + }, + ratio: 1, + serverType: "geoserver", + crossOrigin: "anonymous", + imageLoadFunction: securedImageWMS, + }), + }) + ); + break; + case OL_DATA_TYPES.TileWMS: + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + source: new TileWMS({ + url: url, + projection: projection, + params: { + VERSION: "1.3.0", + LAYERS: layerName, + tiled: true, + cql_filter: null, + }, + tileOptions: { crossOriginKeyword: "anonymous" }, + ratio: 1, + serverType: "geoserver", + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.ImageArcGISRest: + let urlArray = url.split("/"); + let url_layer = urlArray[urlArray.length - 1]; + urlArray.pop(); + url = urlArray.join("/"); + const sourceParams = { + url: url, + params: { LAYERS: `SHOW:${url_layer}` }, + ratio: 1, + projection: projection, + crossOrigin: "anonymous", + }; + if (extent !== undefined) sourceParams["extent"] = [extent.xmin, extent.ymin, extent.xmax, extent.ymax]; + callback( + new ImageLayer({ + rebuildParams: rebuildParams, + name: name, + source: new ImageArcGISRest(sourceParams), + }) + ); + break; + case OL_DATA_TYPES.WMTS: + const rootUrl = url.replace("1.0.0/WMTSCapabilities.xml", ""); + const convertExtent = (extent, sourceCoord, targetCoord) => { + return transform([extent[0], extent[1]], sourceCoord, targetCoord).concat(transform([extent[2], extent[3]], sourceCoord, targetCoord)); + }; + const wmtsCap = (url, callback) => { + helpers.httpGetText(url.indexOf("Capabilities") === -1 ? (/\?/.test(url) ? url + "&" : url + "?") + "REQUEST=GetCapabilities&SERVICE=WMTS" : url, (responseText) => { + try { + var parser = new WMTSCapabilities(); + callback(parser.read(responseText)); + } catch (error) { + console.warn("Unexpected error: " + error.message); + } + }); + }; - wmtsCap(url, (capabilities) => { - var tileMatrixSet = capabilities.Contents.TileMatrixSet[0]; - var projection = "3857"; - if (!tileMatrixSet.SupportedCRS.split(":").includes("3857")) projection = tileMatrixSet.SupportedCRS.split(":")[1]; - helpers.registerCustomProjection(projection, () => { - var wmtsOptions = optionsFromCapabilities(capabilities, { - layer: layerName, - requestEncoding: "REST", - }); - if (!wmtsOptions) wmtsOptions = { layer: layerName, requestEncoding: "REST" }; - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - source: new WMTS(wmtsOptions), - }) - ); - }); - }); - break; - case OL_DATA_TYPES.Stamen: - if (name.length < 1) layerName = "Stamen " + layerName; - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - source: new Stamen({ layer: layerName }), - }) - ); - break; - case OL_DATA_TYPES.OSM: - if (name.length < 1) { - name = "OpenStreetMap"; - } - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - source: new OSM(), - }) - ); - break; - case OL_DATA_TYPES.XYZ: - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - source: new XYZ({ - url: url, - //projection: projection , - crossOrigin: "anonymous", - }), - }) - ); - break; - case OL_DATA_TYPES.TileImage: - const resolutions = [ - 305.74811314055756, 152.87405657041106, 76.43702828507324, 38.21851414253662, 19.10925707126831, 9.554628535634155, 4.77731426794937, 2.388657133974685, 1.1943285668550503, - 0.5971642835598172, 0.29858214164761665, 0.1492252984505969, - ]; - const projExtent_ti = window.map.getView().getProjection().getExtent(); - var tileGrid = new TileGrid({ - resolutions: resolutions, - tileSize: [256, 256], - origin: getTopLeft(projExtent_ti), - }); - let source = new TileImage({ - url: url, - tileGrid: tileGrid, - crossOrigin: "anonymous", - }); - // source.on("tileloaderror", function(event) { - // event.tile.getImage().src = ""; - // }); - callback( - new TileLayer({ - rebuildParams: rebuildParams, - name: name, - projection: projection, - source: source, - }) - ); - break; + wmtsCap(url, (capabilities) => { + var tileMatrixSet = capabilities.Contents.TileMatrixSet[0]; + var projection = "3857"; + if (!tileMatrixSet.SupportedCRS.split(":").includes("3857")) projection = tileMatrixSet.SupportedCRS.split(":")[1]; + helpers.registerCustomProjection(projection, () => { + var wmtsOptions = optionsFromCapabilities(capabilities, { + layer: layerName, + requestEncoding: "REST", + }); + if (!wmtsOptions) wmtsOptions = { layer: layerName, requestEncoding: "REST" }; + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + source: new WMTS(wmtsOptions), + }) + ); + }); + }); + break; + case OL_DATA_TYPES.Stamen: + if (name.length < 1) layerName = "Stamen " + layerName; + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + source: new Stamen({ layer: layerName }), + }) + ); + break; + case OL_DATA_TYPES.OSM: + if (name.length < 1) { + name = "OpenStreetMap"; + } + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + source: new OSM(), + }) + ); + break; + case OL_DATA_TYPES.XYZ: + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + source: new XYZ({ + url: url, + //projection: projection , + crossOrigin: "anonymous", + }), + }) + ); + break; + case OL_DATA_TYPES.TileImage: + const resolutions = [ + 305.74811314055756, 152.87405657041106, 76.43702828507324, 38.21851414253662, 19.10925707126831, 9.554628535634155, 4.77731426794937, 2.388657133974685, 1.1943285668550503, + 0.5971642835598172, 0.29858214164761665, 0.1492252984505969, + ]; + const projExtent_ti = window.map.getView().getProjection().getExtent(); + var tileGrid = new TileGrid({ + resolutions: resolutions, + tileSize: [256, 256], + origin: getTopLeft(projExtent_ti), + }); + let source = new TileImage({ + url: url, + tileGrid: tileGrid, + crossOrigin: "anonymous", + }); + // source.on("tileloaderror", function(event) { + // event.tile.getImage().src = ""; + // }); + callback( + new TileLayer({ + rebuildParams: rebuildParams, + name: name, + projection: projection, + source: source, + }) + ); + break; - case OL_DATA_TYPES.ImageStatic: - if (file === undefined) { - console.error("Missing File for Raster layer."); - return; - } else if (!file.type.match("image.*")) { - console.error("Warning! No raster file selected."); - return; - } - const StaticImage_FileLoader = function (image, src) { - try { - var fr = new FileReader(); - fr.onload = function (evt) { - image.getImage().src = evt.target.result; - }; - fr.readAsDataURL(file); - } catch (error) { - console.warn("Unexpected error: " + error.message); - } - }; - const projExtent = window.map.getView().getProjection().getExtent(); - if (extent === []) extent = projExtent; - callback( - new ImageLayer({ - rebuildParams: rebuildParams, - name: name, - source: new ImageStatic({ - url: "", - imageExtent: [extent[0], extent[1], extent[2], extent[3]], - projection: projection, - imageLoadFunction: StaticImage_FileLoader, - }), - }) - ); - break; - case OL_DATA_TYPES.LayerGroup: - this.getGroupedLayer(options, (newLayer) => { - callback(newLayer); - }); - break; - default: - return; - } - } + case OL_DATA_TYPES.ImageStatic: + if (file === undefined) { + console.error("Missing File for Raster layer."); + return; + } else if (!file.type.match("image.*")) { + console.error("Warning! No raster file selected."); + return; + } + const StaticImage_FileLoader = function (image, src) { + try { + var fr = new FileReader(); + fr.onload = function (evt) { + image.getImage().src = evt.target.result; + }; + fr.readAsDataURL(file); + } catch (error) { + console.warn("Unexpected error: " + error.message); + } + }; + const projExtent = window.map.getView().getProjection().getExtent(); + if (extent === []) extent = projExtent; + callback( + new ImageLayer({ + rebuildParams: rebuildParams, + name: name, + source: new ImageStatic({ + url: "", + imageExtent: [extent[0], extent[1], extent[2], extent[3]], + projection: projection, + imageLoadFunction: StaticImage_FileLoader, + }), + }) + ); + break; + case OL_DATA_TYPES.LayerGroup: + this.getGroupedLayer(options, (newLayer) => { + callback(newLayer); + }); + break; + default: + return; + } + } } diff --git a/src/map/BasemapSwitcher.jsx b/src/map/BasemapSwitcher.jsx index f3c3ba46..0aa20d50 100644 --- a/src/map/BasemapSwitcher.jsx +++ b/src/map/BasemapSwitcher.jsx @@ -9,623 +9,644 @@ import { Group as LayerGroup } from "ol/layer.js"; import xml2js from "xml2js"; class BasemapSwitcher extends Component { - constructor(props) { - super(props); - - this.state = { - imagerySliderMarks: this.getImagerySliderMarks(), - imagerySliderMin: 0, - imagerySliderMax: BasemapConfig.imageryServices.length - 1, - imagerySliderDefaultValue: BasemapConfig.imageryServices.length - 1, - imagerySliderValue: BasemapConfig.imageryServices.length - 1, - imageryLayers: [], - imageryPanelOpen: false, - streetsLayer: null, - streetsCheckbox: true, - containerCollapsed: false, - topoPanelOpen: false, - topoLayers: [], - topoActiveIndex: 0, - topoCheckbox: true, - topoOverlayLayers: [], - showBaseMapSwitcher: true, - activeButton: BasemapConfig.defaultButton, - }; - - // LISTEN FOR CONTROL VISIBILITY CHANGES - window.emitter.addListener("mapControlsChanged", (control, visible) => this.controlStateChange(control, visible)); - } - componentDidMount() { - this.setState({ showBaseMapSwitcher: window.mapControls.basemap }); - helpers.waitForLoad("map", Date.now(), 30, () => this.onMapLoad()); - } - // CREATE YEAR MARKS ON THE SLIDER - getImagerySliderMarks() { - const numServices = BasemapConfig.imageryServices.length; - if (numServices < 2) return {}; - - let marks = {}; - for (let index = 0; index < numServices; index++) { - marks[index] = BasemapConfig.imageryServices[index].name; - } - return marks; - } - - onMapLoad() { - // LOAD IMAGERY LAYERS - let layerList = []; - let index = 0; - - BasemapConfig.imageryServices.forEach((service) => { - // LayerHelpers.getCapabilities(service.url, "wmts", (layers) => { - // console.log(layers); - // }); - const serviceLayerType = service.type !== undefined ? service.type : OL_DATA_TYPES.TileImage; - - LayerHelpers.getLayer( - { - sourceType: serviceLayerType, - source: "WMS", - projection: "EPSG:4326", - layerName: service.name, - url: service.url, - tiled: true, - extent: service.fullExtent, - name: service.name, - }, - (newLayer) => { - // LAYER PROPS - newLayer.setProperties({ index: index, name: service.name }); - newLayer.setZIndex(index + 1); - newLayer.setVisible(false); - - // SET MAIN LAYER VISIBLE - if (BasemapConfig.imageryServices.length - 1 === index) { - newLayer.setVisible(true); - this.setState({ imagerySliderValue: index }); - } - - // ADD THE LAYER - window.map.addLayer(newLayer); - layerList.push(newLayer); - index++; - } - ); - }); - - this.setState({ imageryLayers: layerList }); - - // LOAD IMAGERY STREETS LAYER - if (BasemapConfig.streetService.url !== undefined) { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.TileImage, - source: "WMS", - layerName: "streetServiceBasemap", - url: BasemapConfig.streetService.url, - tiled: true, - name: "streetServiceBasemap", - }, - (newLayer) => { - //var streetsLayer = helpers.getSimcoeTileXYZLayer(BasemapConfig.streetService); - newLayer.setZIndex(BasemapConfig.imageryServices.length); - if (BasemapConfig.streetService.fullExtent) { - newLayer.setExtent(BasemapConfig.streetService.fullExtent); - } - window.map.addLayer(newLayer); - this.setState({ streetsLayer: newLayer }); - } - ); - } - - // LOAD BATHYMETRY LAYER - if (BasemapConfig.bathymetryService.url !== undefined) { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.TileImage, - source: "WMS", - layerName: "bathymetryServiceBasemap", - url: BasemapConfig.bathymetryService.url, - tiled: true, - name: "bathymetryServiceBasemap", - }, - (newLayer) => { - //var bathymetryLayer = helpers.getSimcoeTileXYZLayer(BasemapConfig.bathymetryService.url); - newLayer.setZIndex(0); - if (BasemapConfig.bathymetryService.fullExtent) { - newLayer.setExtent(BasemapConfig.bathymetryService.fullExtent); - } - - window.map.addLayer(newLayer); - this.setState({ bathymetryLayer: newLayer }); - } - ); - } - - // LOAD WORLD LAYER - if (BasemapConfig.worldImageryService !== undefined) { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.XYZ, - source: "WMS", - layerName: "worldImageryServiceBasemap", - url: BasemapConfig.worldImageryService, - tiled: true, - name: "worldImageryServiceBasemap", - }, - (newLayer) => { - //var worldImageryLayer = helpers.getESRITileXYZLayer(BasemapConfig.worldImageryService); - newLayer.setZIndex(0); - window.map.addLayer(newLayer); - this.setState({ worldImageryLayer: newLayer }); - } - ); - } - - // LOAD BASEMAP LAYERS - let basemapList = []; - //let basemapIndex = 0; - BasemapConfig.topoServices.forEach((serviceGroup) => { - index = 0; - let serviceLayers = []; - serviceGroup.layers.forEach((service) => { - // CREATE THE LAYER - //let layer = null; - let layerName = service.name; - if (layerName === undefined) layerName = helpers.getUID(); - if (service.type === "SIMCOE_TILED") { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.TileImage, - source: "WMS", - layerName: layerName, - url: service.url, - extent: service.fullExtent, - tiled: true, - name: layerName, - }, - (newLayer) => { - //layer = helpers.getSimcoeTileXYZLayer(service.url); - - newLayer.setProperties({ - index: index, - name: layerName, - isOverlay: false, - }); - serviceLayers.push(newLayer); - index++; - } - ); - } else if (service.type === "OSM") { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.OSM, - source: "WMS", - layerName: layerName, - tiled: true, - name: layerName, - }, - (newLayer) => { - //layer = helpers.getOSMLayer(); - //layer = helpers.getOSMTileXYZLayer("http://a.tile.openstreetmap.org"); - // LAYER PROPS - newLayer.setProperties({ - index: index, - name: layerName, - isOverlay: false, - }); - serviceLayers.push(newLayer); - index++; - } - ); - } else if (service.type === "ESRI_TILED") { - LayerHelpers.getLayer( - { - sourceType: OL_DATA_TYPES.XYZ, - source: "WMS", - layerName: layerName, - url: service.url, - tiled: true, - name: layerName, - }, - (newLayer) => { - // layer = helpers.getArcGISTiledLayer(service.url); - //layer = helpers.getESRITileXYZLayer(service.url); - // LAYER PROPS - newLayer.setProperties({ - index: index, - name: layerName, - isOverlay: false, - }); - serviceLayers.push(newLayer); - index++; - } - ); - } - }); - const geoserverPath = window.config.geoserverPath; - const groupUrl = serviceGroup.groupUrl; - if (groupUrl !== undefined) { - // GET XML - helpers.httpGetText(groupUrl, (result) => { - var parser = new xml2js.Parser(); - - // PARSE TO JSON - parser.parseString(result, (err, result) => { - const groupLayerList = result.WMS_Capabilities.Capability[0].Layer[0].Layer[0].Layer; - - index = groupLayerList.length + index; - let overlayIndex = index; - //index++; - - groupLayerList.forEach((layerInfo) => { - const keywords = layerInfo.KeywordList[0].Keyword; - const opacity = this.getOpacity(keywords); - const layerNameOnly = layerInfo.Name[0].split(":")[1]; - const serverUrl = groupUrl.split(`/${geoserverPath}/`)[0] + `/${geoserverPath}`; - - let groupLayer = helpers.getImageWMSLayer(serverUrl + "/wms", layerInfo.Name[0]); - groupLayer.setVisible(true); - groupLayer.setOpacity(opacity); - groupLayer.setZIndex(overlayIndex); - groupLayer.setProperties({ - index: overlayIndex, - name: layerNameOnly, - isOverlay: true, - }); - serviceLayers.push(groupLayer); - overlayIndex--; - }); - - // USING LAYER GROUPS FOR TOPO - let layerGroup = new LayerGroup({ - layers: serviceLayers, - visible: false, - }); - layerGroup.setProperties({ - index: serviceGroup.index, - name: serviceGroup.name, - }); - window.map.addLayer(layerGroup); - basemapList.push(layerGroup); - }); - }); - } else { - // USING LAYER GROUPS FOR TOPO - let layerGroup = new LayerGroup({ - layers: serviceLayers, - visible: false, - }); - layerGroup.setProperties({ - index: serviceGroup.index, - name: serviceGroup.name, - }); - window.map.addLayer(layerGroup); - basemapList.push(layerGroup); - //basemapIndex++; - } - }); - - this.setState({ topoLayers: basemapList }); - this.setState({ topoActiveIndex: 0 }); - - if (this.state.activeButton === "topo") { - this.enableTopo(); - } else { - this.enableImagery(); - } - // NEED TO WAIT A TAD FOR LAYERS TO INIT - setTimeout(() => { - this.handleURLParameters(); - }, 100); - } - - getOpacity(keywords) { - if (keywords === undefined) return 1; - const opacityKeyword = keywords.find(function (item) { - return item.indexOf("OPACITY") !== -1; - }); - if (opacityKeyword !== undefined) { - const val = opacityKeyword.split("=")[1]; - return parseFloat(val); - } else return 1; - } - - // HANDLE URL PARAMETERS - handleURLParameters = (value) => { - const basemap = helpers.getURLParameter("BASEMAP") !== null ? helpers.getURLParameter("BASEMAP").toUpperCase() : null; - const name = helpers.getURLParameter("NAME") !== null ? helpers.getURLParameter("NAME").toUpperCase() : null; - const imagerySliderOpen = helpers.getURLParameter("SLIDER_OPEN") !== null ? helpers.getURLParameter("SLIDER_OPEN").toUpperCase() : null; - - if (basemap === "IMAGERY") { - this.enableImagery(); - - if (imagerySliderOpen === "TRUE") this.setState({ imageryPanelOpen: true }); - - if (name !== undefined) { - for (let index = 0; index < this.state.imageryLayers.length; index++) { - const layer = this.state.imageryLayers[index]; - const layerName = layer.getProperties().name.toUpperCase(); - if (layerName === name) { - this.updateImageryLayers(index); - this.setState({ - imagerySliderValue: index, - imagerySliderDefaultValue: index, - }); - return; - } - } - } - } else if (basemap === "TOPO") { - this.disableImagery(); - this.enableTopo(); - - for (let index = 0; index < this.state.topoLayers.length; index++) { - let layer = this.state.topoLayers[index]; - const layerName = layer.getProperties().name; - if (layerName.toUpperCase() === name) { - this.setState({ topoActiveIndex: index }); - this.setTopoLayerVisiblity(index); - } - } - } - }; - - // CALLED WHEN SLIDING OR TO RESET - updateImageryLayers(value) { - for (let index = 0; index < this.state.imageryLayers.length; index++) { - let layer = this.state.imageryLayers[index]; - if (value === -1) layer.setVisible(false); - else { - const layerIndex = layer.getProperties().index; - const indexRatio = 1 - Math.abs(layerIndex - value); - if (layerIndex === value) { - layer.setOpacity(1); - layer.setVisible(true); - } else if (indexRatio <= 0) { - layer.setOpacity(0); - layer.setVisible(false); - } else { - layer.setOpacity(indexRatio); - layer.setVisible(true); - } - } - } - } - - // SLIDER CHANGE EVENT - onSliderChange = (value) => { - this.updateImageryLayers(value); - this.setState({ imagerySliderValue: value }); - }; - - // PANEL DROP DOWN BUTTON - onImageryArrowClick = (value) => { - // DISABLE TOPO - this.disableTopo(); - - // ENABLE IMAGERY - this.setState({ - topoPanelOpen: false, - activeButton: "imagery", - imageryPanelOpen: !this.state.imageryPanelOpen, - }); - this.updateImageryLayers(this.state.imagerySliderValue); - this.state.streetsLayer.setVisible(this.state.streetsCheckbox); - this.state.worldImageryLayer.setVisible(this.state.streetsCheckbox); - - // APP STATS - helpers.addAppStat("Imagery", "Arrow"); - }; - - onImageryButtonClick = (value) => { - // DISABLE TOPO - this.disableTopo(); - - // CLOSE PANEL, ONLY IF ALREADY OPEN - if (this.state.imageryPanelOpen) this.setState({ imageryPanelOpen: !this.state.imageryPanelOpen }); - - this.enableImagery(); - - // APP STATS - helpers.addAppStat("Imagery", "Button"); - }; - - enableImagery = (value) => { - // ENABLE IMAGERY - this.updateImageryLayers(this.state.imagerySliderValue); - - this.setState({ topoPanelOpen: false, activeButton: "imagery" }); - this.state.streetsLayer.setVisible(this.state.streetsCheckbox); - this.state.worldImageryLayer.setVisible(this.state.streetsCheckbox); - this.setTopoLayerVisiblity(-1); - - // EMIT A BASEMAP CHANGE - window.emitter.emit("basemapChanged", "IMAGERY"); - }; - - disableImagery = (value) => { - // DISABLE IMAGERY - this.state.streetsLayer.setVisible(false); - this.state.worldImageryLayer.setVisible(false); - this.setState({ imageryPanelOpen: false }); - this.updateImageryLayers(-1); - }; - - onStreetsCheckbox = (evt) => { - this.state.streetsLayer.setVisible(evt.target.checked); - this.setState({ streetsCheckbox: evt.target.checked }); - }; - - onTopoCheckbox = (evt) => { - //this.state.streetsLayer.setVisible(evt.target.checked); - this.setState({ topoCheckbox: evt.target.checked }, () => { - this.enableTopo(); - }); - }; - - onCollapsedClick = (evt) => { - // HIDE OPEN PANELS - if (this.state.containerCollapsed === false) { - this.setState({ imageryPanelOpen: false }); - this.setState({ topoPanelOpen: false }); - } - - this.setState({ containerCollapsed: !this.state.containerCollapsed }); - }; - - enableTopo = (value) => { - // DISABLE IMAGERY - this.disableImagery(); - - this.setState({ activeButton: "topo" }); - this.setTopoLayerVisiblity(this.state.topoActiveIndex); - - // EMIT A BASEMAP CHANGE - window.emitter.emit("basemapChanged", "TOPO"); - }; - - disableTopo = (value) => { - this.setTopoLayerVisiblity(-1); - }; - - // TOPO BUTTON - onTopoButtonClick = (evt) => { - // CLOSE PANEL ONLY IF ALREADY OPEN - if (this.state.topoPanelOpen) this.setState({ topoPanelOpen: !this.state.topoPanelOpen }); - - this.enableTopo(); - - // APP STATS - helpers.addAppStat("Topo", "Button"); - }; - - // PANEL DROP DOWN BUTTON - onTopoArrowClick = (evt) => { - this.enableTopo(); - this.setState({ topoPanelOpen: !this.state.topoPanelOpen }); - // APP STATS - helpers.addAppStat("Topo", "Arrow"); - }; - - // CLICK ON TOPO THUMBNAILS - onTopoItemClick = (activeIndex, name) => { - this.setState({ topoActiveIndex: activeIndex }); - this.setTopoLayerVisiblity(activeIndex); - this.setState({ topoPanelOpen: false }); - helpers.addAppStat("Basemap", name); - }; - - // ADJUST VISIBILITY - setTopoLayerVisiblity(activeIndex) { - for (let index = 0; index < this.state.topoLayers.length; index++) { - let layer = this.state.topoLayers[index]; - const layerIndex = layer.getProperties().index; - if (layerIndex === activeIndex) { - //let layers = layer.getLayers(); - - layer.getLayers().forEach((layer) => { - if (layer.get("isOverlay") && this.state.topoCheckbox) layer.setVisible(true); - else if (layer.get("isOverlay") && !this.state.topoCheckbox) layer.setVisible(false); - }); - - layer.setVisible(true); - } else { - layer.setVisible(false); - } - } - } - controlStateChange(control, state) { - switch (control) { - case "basemap": - this.setState({ showBaseMapSwitcher: state }); - break; - default: - break; - } - } - render() { - // STYLE USED BY SLIDER - const sliderWrapperStyle = { - width: 60, - marginLeft: 13, - height: 225, - marginTop: 8, - marginBottom: 15, - }; - - return ( -
-
-
-
- -
-
- -
-
-
- - -
-
- - {BasemapConfig.topoServices.map((service, index) => ( - - ))} -
-
- ); - } + constructor(props) { + super(props); + + this.state = { + imagerySliderMarks: this.getImagerySliderMarks(), + imagerySliderMin: 0, + imagerySliderMax: BasemapConfig.imageryServices.length - 1, + imagerySliderDefaultValue: BasemapConfig.imageryServices.length - 1, + imagerySliderValue: BasemapConfig.imageryServices.length - 1, + imageryLayers: [], + imageryPanelOpen: false, + streetsLayer: null, + streetsCheckbox: true, + containerCollapsed: false, + topoPanelOpen: false, + topoLayers: [], + topoActiveIndex: 0, + topoCheckbox: true, + topoOverlayLayers: [], + showBaseMapSwitcher: true, + activeButton: BasemapConfig.defaultButton, + }; + + // LISTEN FOR CONTROL VISIBILITY CHANGES + window.emitter.addListener("mapControlsChanged", (control, visible) => this.controlStateChange(control, visible)); + } + componentDidMount() { + this.setState({ showBaseMapSwitcher: window.mapControls.basemap }); + helpers.waitForLoad("map", Date.now(), 30, () => this.onMapLoad()); + } + // CREATE YEAR MARKS ON THE SLIDER + getImagerySliderMarks() { + const numServices = BasemapConfig.imageryServices.length; + if (numServices < 2) return {}; + + let marks = {}; + for (let index = 0; index < numServices; index++) { + marks[index] = BasemapConfig.imageryServices[index].name; + } + return marks; + } + + onMapLoad() { + // LOAD IMAGERY LAYERS + let layerList = []; + let index = 0; + + BasemapConfig.imageryServices.forEach((service) => { + // LayerHelpers.getCapabilities(service.url, "wmts", (layers) => { + // console.log(layers); + // }); + const serviceLayerType = service.type !== undefined ? service.type : OL_DATA_TYPES.TileImage; + + LayerHelpers.getLayer( + { + sourceType: serviceLayerType, + source: "WMS", + projection: "EPSG:4326", + layerName: service.name, + url: service.url, + tiled: true, + extent: service.fullExtent, + name: service.name, + }, + (newLayer) => { + // LAYER PROPS + newLayer.setProperties({ index: index, name: service.name }); + newLayer.setZIndex(index + 1); + newLayer.setVisible(false); + + // SET MAIN LAYER VISIBLE + if (BasemapConfig.imageryServices.length - 1 === index) { + newLayer.setVisible(true); + this.setState({ imagerySliderValue: index }); + } + + // ADD THE LAYER + window.map.addLayer(newLayer); + layerList.push(newLayer); + index++; + } + ); + }); + + this.setState({ imageryLayers: layerList }); + + // LOAD IMAGERY STREETS LAYER + if (BasemapConfig.streetService.url !== undefined) { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.TileImage, + source: "WMS", + layerName: "streetServiceBasemap", + url: BasemapConfig.streetService.url, + tiled: true, + name: "streetServiceBasemap", + }, + (newLayer) => { + //var streetsLayer = helpers.getSimcoeTileXYZLayer(BasemapConfig.streetService); + newLayer.setZIndex(BasemapConfig.imageryServices.length); + if (BasemapConfig.streetService.fullExtent) { + newLayer.setExtent(BasemapConfig.streetService.fullExtent); + } + window.map.addLayer(newLayer); + this.setState({ streetsLayer: newLayer }); + } + ); + } + + // LOAD BATHYMETRY LAYER + if (BasemapConfig.bathymetryService.url !== undefined) { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.TileImage, + source: "WMS", + layerName: "bathymetryServiceBasemap", + url: BasemapConfig.bathymetryService.url, + tiled: true, + name: "bathymetryServiceBasemap", + }, + (newLayer) => { + //var bathymetryLayer = helpers.getSimcoeTileXYZLayer(BasemapConfig.bathymetryService.url); + newLayer.setZIndex(0); + if (BasemapConfig.bathymetryService.fullExtent) { + newLayer.setExtent(BasemapConfig.bathymetryService.fullExtent); + } + + window.map.addLayer(newLayer); + this.setState({ bathymetryLayer: newLayer }); + } + ); + } + + // LOAD WORLD LAYER + if (BasemapConfig.worldImageryService !== undefined) { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.XYZ, + source: "WMS", + layerName: "worldImageryServiceBasemap", + url: BasemapConfig.worldImageryService, + tiled: true, + name: "worldImageryServiceBasemap", + }, + (newLayer) => { + //var worldImageryLayer = helpers.getESRITileXYZLayer(BasemapConfig.worldImageryService); + newLayer.setZIndex(0); + window.map.addLayer(newLayer); + this.setState({ worldImageryLayer: newLayer }); + } + ); + } + + // LOAD BASEMAP LAYERS + let basemapList = []; + //let basemapIndex = 0; + BasemapConfig.topoServices.forEach((serviceGroup) => { + index = 0; + let serviceLayers = []; + serviceGroup.layers.forEach((service) => { + // CREATE THE LAYER + //let layer = null; + let layerName = service.name; + if (layerName === undefined) layerName = helpers.getUID(); + if (service.type === "SIMCOE_TILED") { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.TileImage, + source: "WMS", + layerName: layerName, + url: service.url, + extent: service.fullExtent, + tiled: true, + name: layerName, + }, + (newLayer) => { + //layer = helpers.getSimcoeTileXYZLayer(service.url); + + newLayer.setProperties({ + index: index, + name: layerName, + isOverlay: false, + }); + serviceLayers.push(newLayer); + index++; + } + ); + } else if (service.type === "OSM") { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.OSM, + source: "WMS", + layerName: layerName, + tiled: true, + name: layerName, + }, + (newLayer) => { + //layer = helpers.getOSMLayer(); + //layer = helpers.getOSMTileXYZLayer("http://a.tile.openstreetmap.org"); + // LAYER PROPS + newLayer.setProperties({ + index: index, + name: layerName, + isOverlay: false, + }); + serviceLayers.push(newLayer); + index++; + } + ); + } else if (service.type === "ESRI_TILED") { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.XYZ, + source: "WMS", + layerName: layerName, + url: service.url, + tiled: true, + name: layerName, + }, + (newLayer) => { + // layer = helpers.getArcGISTiledLayer(service.url); + //layer = helpers.getESRITileXYZLayer(service.url); + // LAYER PROPS + newLayer.setProperties({ + index: index, + name: layerName, + isOverlay: false, + }); + serviceLayers.push(newLayer); + index++; + } + ); + } else if (service.type === "ESRI_VECTOR_TILED") { + LayerHelpers.getLayer( + { + sourceType: OL_DATA_TYPES.VectorTile, + source: "Vector", + layerName: layerName, + url: service.url, + tiled: true, + name: layerName, + }, + (newLayer) => { + // LAYER PROPS + newLayer.setProperties({ + index: index, + name: layerName, + isOverlay: false, + }); + serviceLayers.push(newLayer); + index++; + } + ); + } + }); + const geoserverPath = window.config.geoserverPath; + const groupUrl = serviceGroup.groupUrl; + if (groupUrl !== undefined) { + // GET XML + helpers.httpGetText(groupUrl, (result) => { + var parser = new xml2js.Parser(); + + // PARSE TO JSON + parser.parseString(result, (err, result) => { + const groupLayerList = result.WMS_Capabilities.Capability[0].Layer[0].Layer[0].Layer; + + index = groupLayerList.length + index; + let overlayIndex = index; + //index++; + + groupLayerList.forEach((layerInfo) => { + const keywords = layerInfo.KeywordList[0].Keyword; + const opacity = this.getOpacity(keywords); + const layerNameOnly = layerInfo.Name[0].split(":")[1]; + const serverUrl = groupUrl.split(`/${geoserverPath}/`)[0] + `/${geoserverPath}`; + + let groupLayer = helpers.getImageWMSLayer(serverUrl + "/wms", layerInfo.Name[0]); + groupLayer.setVisible(true); + groupLayer.setOpacity(opacity); + groupLayer.setZIndex(overlayIndex); + groupLayer.setProperties({ + index: overlayIndex, + name: layerNameOnly, + isOverlay: true, + }); + serviceLayers.push(groupLayer); + overlayIndex--; + }); + + // USING LAYER GROUPS FOR TOPO + let layerGroup = new LayerGroup({ + layers: serviceLayers, + visible: false, + }); + layerGroup.setProperties({ + index: serviceGroup.index, + name: serviceGroup.name, + }); + window.map.addLayer(layerGroup); + basemapList.push(layerGroup); + }); + }); + } else { + // USING LAYER GROUPS FOR TOPO + let layerGroup = new LayerGroup({ + layers: serviceLayers, + visible: false, + }); + layerGroup.setProperties({ + index: serviceGroup.index, + name: serviceGroup.name, + }); + window.map.addLayer(layerGroup); + basemapList.push(layerGroup); + //basemapIndex++; + } + }); + + this.setState({ topoLayers: basemapList }); + this.setState({ topoActiveIndex: 0 }); + + if (this.state.activeButton === "topo") { + this.enableTopo(); + } else { + this.enableImagery(); + } + // NEED TO WAIT A TAD FOR LAYERS TO INIT + setTimeout(() => { + this.handleURLParameters(); + }, 100); + } + + getOpacity(keywords) { + if (keywords === undefined) return 1; + const opacityKeyword = keywords.find(function (item) { + return item.indexOf("OPACITY") !== -1; + }); + if (opacityKeyword !== undefined) { + const val = opacityKeyword.split("=")[1]; + return parseFloat(val); + } else return 1; + } + + // HANDLE URL PARAMETERS + handleURLParameters = (value) => { + const basemap = helpers.getURLParameter("BASEMAP") !== null ? helpers.getURLParameter("BASEMAP").toUpperCase() : null; + const name = helpers.getURLParameter("NAME") !== null ? helpers.getURLParameter("NAME").toUpperCase() : null; + const imagerySliderOpen = helpers.getURLParameter("SLIDER_OPEN") !== null ? helpers.getURLParameter("SLIDER_OPEN").toUpperCase() : null; + + if (basemap === "IMAGERY") { + this.enableImagery(); + + if (imagerySliderOpen === "TRUE") this.setState({ imageryPanelOpen: true }); + + if (name !== undefined) { + for (let index = 0; index < this.state.imageryLayers.length; index++) { + const layer = this.state.imageryLayers[index]; + const layerName = layer.getProperties().name.toUpperCase(); + if (layerName === name) { + this.updateImageryLayers(index); + this.setState({ + imagerySliderValue: index, + imagerySliderDefaultValue: index, + }); + return; + } + } + } + } else if (basemap === "TOPO") { + this.disableImagery(); + this.enableTopo(); + + for (let index = 0; index < this.state.topoLayers.length; index++) { + let layer = this.state.topoLayers[index]; + const layerName = layer.getProperties().name; + if (layerName.toUpperCase() === name) { + this.setState({ topoActiveIndex: index }); + this.setTopoLayerVisiblity(index); + } + } + } + }; + + // CALLED WHEN SLIDING OR TO RESET + updateImageryLayers(value) { + for (let index = 0; index < this.state.imageryLayers.length; index++) { + let layer = this.state.imageryLayers[index]; + if (value === -1) layer.setVisible(false); + else { + const layerIndex = layer.getProperties().index; + const indexRatio = 1 - Math.abs(layerIndex - value); + if (layerIndex === value) { + layer.setOpacity(1); + layer.setVisible(true); + } else if (indexRatio <= 0) { + layer.setOpacity(0); + layer.setVisible(false); + } else { + layer.setOpacity(indexRatio); + layer.setVisible(true); + } + } + } + } + + // SLIDER CHANGE EVENT + onSliderChange = (value) => { + this.updateImageryLayers(value); + this.setState({ imagerySliderValue: value }); + }; + + // PANEL DROP DOWN BUTTON + onImageryArrowClick = (value) => { + // DISABLE TOPO + this.disableTopo(); + + // ENABLE IMAGERY + this.setState({ + topoPanelOpen: false, + activeButton: "imagery", + imageryPanelOpen: !this.state.imageryPanelOpen, + }); + this.updateImageryLayers(this.state.imagerySliderValue); + this.state.streetsLayer.setVisible(this.state.streetsCheckbox); + this.state.worldImageryLayer.setVisible(this.state.streetsCheckbox); + + // APP STATS + helpers.addAppStat("Imagery", "Arrow"); + }; + + onImageryButtonClick = (value) => { + // DISABLE TOPO + this.disableTopo(); + + // CLOSE PANEL, ONLY IF ALREADY OPEN + if (this.state.imageryPanelOpen) this.setState({ imageryPanelOpen: !this.state.imageryPanelOpen }); + + this.enableImagery(); + + // APP STATS + helpers.addAppStat("Imagery", "Button"); + }; + + enableImagery = (value) => { + // ENABLE IMAGERY + this.updateImageryLayers(this.state.imagerySliderValue); + + this.setState({ topoPanelOpen: false, activeButton: "imagery" }); + this.state.streetsLayer.setVisible(this.state.streetsCheckbox); + this.state.worldImageryLayer.setVisible(this.state.streetsCheckbox); + this.setTopoLayerVisiblity(-1); + + // EMIT A BASEMAP CHANGE + window.emitter.emit("basemapChanged", "IMAGERY"); + }; + + disableImagery = (value) => { + // DISABLE IMAGERY + this.state.streetsLayer.setVisible(false); + this.state.worldImageryLayer.setVisible(false); + this.setState({ imageryPanelOpen: false }); + this.updateImageryLayers(-1); + }; + + onStreetsCheckbox = (evt) => { + this.state.streetsLayer.setVisible(evt.target.checked); + this.setState({ streetsCheckbox: evt.target.checked }); + }; + + onTopoCheckbox = (evt) => { + //this.state.streetsLayer.setVisible(evt.target.checked); + this.setState({ topoCheckbox: evt.target.checked }, () => { + this.enableTopo(); + }); + }; + + onCollapsedClick = (evt) => { + // HIDE OPEN PANELS + if (this.state.containerCollapsed === false) { + this.setState({ imageryPanelOpen: false }); + this.setState({ topoPanelOpen: false }); + } + + this.setState({ containerCollapsed: !this.state.containerCollapsed }); + }; + + enableTopo = (value) => { + // DISABLE IMAGERY + this.disableImagery(); + + this.setState({ activeButton: "topo" }); + this.setTopoLayerVisiblity(this.state.topoActiveIndex); + + // EMIT A BASEMAP CHANGE + window.emitter.emit("basemapChanged", "TOPO"); + }; + + disableTopo = (value) => { + this.setTopoLayerVisiblity(-1); + }; + + // TOPO BUTTON + onTopoButtonClick = (evt) => { + // CLOSE PANEL ONLY IF ALREADY OPEN + if (this.state.topoPanelOpen) this.setState({ topoPanelOpen: !this.state.topoPanelOpen }); + + this.enableTopo(); + + // APP STATS + helpers.addAppStat("Topo", "Button"); + }; + + // PANEL DROP DOWN BUTTON + onTopoArrowClick = (evt) => { + this.enableTopo(); + this.setState({ topoPanelOpen: !this.state.topoPanelOpen }); + // APP STATS + helpers.addAppStat("Topo", "Arrow"); + }; + + // CLICK ON TOPO THUMBNAILS + onTopoItemClick = (activeIndex, name) => { + this.setState({ topoActiveIndex: activeIndex }); + this.setTopoLayerVisiblity(activeIndex); + this.setState({ topoPanelOpen: false }); + helpers.addAppStat("Basemap", name); + }; + + // ADJUST VISIBILITY + setTopoLayerVisiblity(activeIndex) { + for (let index = 0; index < this.state.topoLayers.length; index++) { + let layer = this.state.topoLayers[index]; + const layerIndex = layer.getProperties().index; + if (layerIndex === activeIndex) { + //let layers = layer.getLayers(); + + layer.getLayers().forEach((layer) => { + if (layer.get("isOverlay") && this.state.topoCheckbox) layer.setVisible(true); + else if (layer.get("isOverlay") && !this.state.topoCheckbox) layer.setVisible(false); + }); + + layer.setVisible(true); + } else { + layer.setVisible(false); + } + } + } + controlStateChange(control, state) { + switch (control) { + case "basemap": + this.setState({ showBaseMapSwitcher: state }); + break; + default: + break; + } + } + render() { + // STYLE USED BY SLIDER + const sliderWrapperStyle = { + width: 60, + marginLeft: 13, + height: 225, + marginTop: 8, + marginBottom: 15, + }; + + return ( +
+
+
+
+ +
+
+ +
+
+
+ + +
+
+ + {BasemapConfig.topoServices.map((service, index) => ( + + ))} +
+
+ ); + } } export default BasemapSwitcher; class BasemapItem extends Component { - state = {}; - render() { - return ( -
{ - this.props.onTopoItemClick(this.props.index, this.props.service.name); - }} - > - {this.props.service.name} - {this.props.service.image} -
- ); - } + state = {}; + render() { + return ( +
{ + this.props.onTopoItemClick(this.props.index, this.props.service.name); + }} + > + {this.props.service.name} + {this.props.service.image} +
+ ); + } } // IMPORT ALL IMAGES const images = importAllImages(require.context("./images", false, /\.(png|jpe?g|svg|gif)$/)); function importAllImages(r) { - let images = {}; - r.keys().map((item, index) => (images[item.replace("./", "")] = r(item))); - return images; + let images = {}; + r.keys().map((item, index) => (images[item.replace("./", "")] = r(item))); + return images; } diff --git a/src/map/basemapSwitcherConfig.json b/src/map/basemapSwitcherConfig.json index 3e0dbd84..f27020b8 100644 --- a/src/map/basemapSwitcherConfig.json +++ b/src/map/basemapSwitcherConfig.json @@ -1,116 +1,116 @@ { - "defaultButton": "topo", - "streetService": { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Streets_Cache/MapServer/tile/{z}/{y}/{x}", - "fullExtent": [-8938992.401246801, 5456230.285257593, -8801900.781241283, 5610242.681997935] - }, - "bathymetryService": { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Bathymetry_Cache/MapServer/tile/{z}/{y}/{x}", - "fullExtent": [-9118041.67548189, 5494116.533098262, -8805900.95513073, 5785509.4618044235] - }, - "worldImageryService": "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", - "topoServices": [ - { - "name": "Topographic", - "image": "esri-topo.png", - "index": 0, - "layers": [ - { - "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}", - "type": "ESRI_TILED" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Topo_Cache/MapServer/tile/{z}/{y}/{x}", - "type": "SIMCOE_TILED", - "fullExtent": [-9127039.9939, 5219474.5973000005, -8607132.7041, 5807644.523699999] - } - ], - "groupUrlDev": "https://opengis.simcoe.ca/geoserver/simcoe/Topo_Overlay/ows?service=wms&version=1.3.0&request=GetCapabilities" - }, - { - "name": "Streets", - "image": "esri-streets.png", - "index": 1, - "layers": [ - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Streets_Black_And_White_Cache/MapServer/tile/{z}/{y}/{x}", - "type": "SIMCOE_TILED", - "fullExtent": [-9127039.9939, 5219474.5973000005, -8607132.7041, 5807644.523699999] - } - ] - }, - { - "name": "Open Street Map", - "image": "osm-topo.jpg", - "index": 2, - "layers": [ - { - "url": "", - "type": "OSM" - } - ] - } - ], - "imageryServices": [ - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1954_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "1954", - "fullExtent": [-8939199.533337621, 5454802.440978845, -8801041.585877508, 5612748.673941727], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1978_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "1978", - "fullExtent": [-8939198.774465304, 5454802.850841734, -8801041.351645766, 5612747.926099348], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1989_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "1989", - "fullExtent": [-8939198.774465304, 5454802.850841734, -8801041.351645766, 5612747.926099348], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1997_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "1997", - "fullExtent": [-8939209.262138586, 5453383.540504173, -8799634.494968254, 5612747.404426142], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2002_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2002", - "fullExtent": [-8947220.760967761, 5448558.705193831, -8773607.10943329, 5611306.111624397], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2008_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2008", - "fullExtent": [-8947614.320379963, 5442293.149513868, -8801041.665360063, 5612817.832685983], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2012_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2012", - "fullExtent": [-8940584.631934738, 5454803.475123008, -8801041.532479912, 5612759.41073959], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2013_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2013", - "fullExtent": [-8939184.415645305, 5456195.94916096, -8801076.676160479, 5611330.116028212], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2016_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2016", - "fullExtent": [-8940584.631934738, 5454803.4751230525, -8801041.532479912, 5612759.410739558], - "type": "TileImage" - }, - { - "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2018_Cache/MapServer/tile/{z}/{y}/{x}", - "name": "2018", - "fullExtent": [-8939184.811223287, 5455923.230242465, -8801043.336866248, 5612747.0814112425], - "type": "TileImage" - } - ] + "defaultButton": "topo", + "streetService": { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Streets_Cache/MapServer/tile/{z}/{y}/{x}", + "fullExtent": [-8938992.401246801, 5456230.285257593, -8801900.781241283, 5610242.681997935] + }, + "bathymetryService": { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Bathymetry_Cache/MapServer/tile/{z}/{y}/{x}", + "fullExtent": [-9118041.67548189, 5494116.533098262, -8805900.95513073, 5785509.4618044235] + }, + "worldImageryService": "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", + "topoServices": [ + { + "name": "Topographic", + "image": "esri-topo.png", + "index": 0, + "layers": [ + { + "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}", + "type": "ESRI_TILED" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Topo_Cache/MapServer/tile/{z}/{y}/{x}", + "type": "SIMCOE_TILED", + "fullExtent": [-9127039.9939, 5219474.5973000005, -8607132.7041, 5807644.523699999] + } + ], + "groupUrlDev": "https://opengis.simcoe.ca/geoserver/simcoe/Topo_Overlay/ows?service=wms&version=1.3.0&request=GetCapabilities" + }, + { + "name": "Streets", + "image": "esri-streets.png", + "index": 1, + "layers": [ + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Streets_Black_And_White_Cache/MapServer/tile/{z}/{y}/{x}", + "type": "SIMCOE_TILED", + "fullExtent": [-9127039.9939, 5219474.5973000005, -8607132.7041, 5807644.523699999] + } + ] + }, + { + "name": "Open Street Map", + "image": "osm-topo.jpg", + "index": 2, + "layers": [ + { + "url": "", + "type": "OSM" + } + ] + } + ], + "imageryServices": [ + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1954_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "1954", + "fullExtent": [-8939199.533337621, 5454802.440978845, -8801041.585877508, 5612748.673941727], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1978_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "1978", + "fullExtent": [-8939198.774465304, 5454802.850841734, -8801041.351645766, 5612747.926099348], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1989_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "1989", + "fullExtent": [-8939198.774465304, 5454802.850841734, -8801041.351645766, 5612747.926099348], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_1997_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "1997", + "fullExtent": [-8939209.262138586, 5453383.540504173, -8799634.494968254, 5612747.404426142], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2002_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2002", + "fullExtent": [-8947220.760967761, 5448558.705193831, -8773607.10943329, 5611306.111624397], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2008_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2008", + "fullExtent": [-8947614.320379963, 5442293.149513868, -8801041.665360063, 5612817.832685983], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2012_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2012", + "fullExtent": [-8940584.631934738, 5454803.475123008, -8801041.532479912, 5612759.41073959], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2013_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2013", + "fullExtent": [-8939184.415645305, 5456195.94916096, -8801076.676160479, 5611330.116028212], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2016_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2016", + "fullExtent": [-8940584.631934738, 5454803.4751230525, -8801041.532479912, 5612759.410739558], + "type": "TileImage" + }, + { + "url": "https://maps.simcoe.ca/arcgis/rest/services/Public/Ortho_2018_Cache/MapServer/tile/{z}/{y}/{x}", + "name": "2018", + "fullExtent": [-8939184.811223287, 5455923.230242465, -8801043.336866248, 5612747.0814112425], + "type": "TileImage" + } + ] }