From 360c426f14eb90035671e5e75e268a46deeedd03 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Wed, 6 Feb 2013 14:25:57 +0100 Subject: [PATCH 1/9] add WMS GetCapabilities parser for WMS 1.1.0, 1.1.1, 1.1.1 WMS-C profile and WMS 1.3.0 --- src/ol/parser/ogc/exceptionreport.js | 101 + src/ol/parser/ogc/versioned.js | 121 + src/ol/parser/ogc/wmscapabilities.exports | 2 + src/ol/parser/ogc/wmscapabilities.js | 52 + src/ol/parser/ogc/wmscapabilities_v1.js | 324 ++ src/ol/parser/ogc/wmscapabilities_v1_1.js | 99 + src/ol/parser/ogc/wmscapabilities_v1_1_0.js | 25 + src/ol/parser/ogc/wmscapabilities_v1_1_1.js | 21 + .../parser/ogc/wmscapabilities_v1_1_1_WMSC.js | 46 + src/ol/parser/ogc/wmscapabilities_v1_3_0.js | 106 + src/ol/parser/xml.js | 148 + .../ol/parser/ogc/exceptionreport.test.js | 101 + test/spec/ol/parser/ogc/versioned.test.js | 28 + .../ol/parser/ogc/wmscapabilities.test.js | 45 + .../parser/ogc/wmscapabilities_v1_1_1.test.js | 444 ++ .../ogc/wmscapabilities_v1_1_1_WMSC.test.js | 74 + .../parser/ogc/wmscapabilities_v1_3_0.test.js | 297 ++ .../ogc/xml/exceptionreport/ows1_0_0.xml | 9 + .../ogc/xml/exceptionreport/ows1_1_0.xml | 9 + .../ogc/xml/exceptionreport/wms1_3_0.xml | 16 + .../exceptionsample.xml | 4 + .../xml/wmscapabilities_v1_1_1/gssample.xml | 4497 +++++++++++++++++ .../xml/wmscapabilities_v1_1_1/ogcsample.xml | 283 ++ .../wmscapabilities_v1_1_1_WMSC/fallback.xml | 124 + .../xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml | 178 + .../exceptionsample.xml | 17 + .../xml/wmscapabilities_v1_3_0/ogcsample.xml | 284 ++ 27 files changed, 7455 insertions(+) create mode 100644 src/ol/parser/ogc/exceptionreport.js create mode 100644 src/ol/parser/ogc/versioned.js create mode 100644 src/ol/parser/ogc/wmscapabilities.exports create mode 100644 src/ol/parser/ogc/wmscapabilities.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1_1.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1_1_0.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1_1_1.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js create mode 100644 src/ol/parser/ogc/wmscapabilities_v1_3_0.js create mode 100644 src/ol/parser/xml.js create mode 100644 test/spec/ol/parser/ogc/exceptionreport.test.js create mode 100644 test/spec/ol/parser/ogc/versioned.test.js create mode 100644 test/spec/ol/parser/ogc/wmscapabilities.test.js create mode 100644 test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js create mode 100644 test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js create mode 100644 test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js create mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml create mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml create mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml create mode 100644 test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml diff --git a/src/ol/parser/ogc/exceptionreport.js b/src/ol/parser/ogc/exceptionreport.js new file mode 100644 index 0000000000..45f53b2226 --- /dev/null +++ b/src/ol/parser/ogc/exceptionreport.js @@ -0,0 +1,101 @@ +goog.provide('ol.parser.ogc.ExceptionReport'); +goog.require('goog.dom.xml'); +goog.require('ol.parser.XML'); + + + +/** + * @constructor + * @extends {ol.parser.XML} + */ +ol.parser.ogc.ExceptionReport = function() { + this.defaultPrefix = 'ogc'; + this.namespaces = {}; + this.namespaces['ogc'] = 'http://www.opengis.net/ogc'; + this.namespaces['ows'] = 'http://www.opengis.net/ows'; + this.namespaces['ows11'] = 'http://www.opengis.net/ows/1.1'; + var exceptionReader = function(node, exceptionReport) { + var exception = { + code: node.getAttribute('exceptionCode'), + locator: node.getAttribute('locator'), + texts: [] + }; + exceptionReport.exceptions.push(exception); + this.readChildNodes(node, exception); + }; + var exceptionTextReader = function(node, exception) { + var text = this.getChildValue(node); + exception.texts.push(text); + }; + this.readers = { + 'ogc': { + 'ServiceExceptionReport': function(node, obj) { + obj['exceptionReport'] = {}; + obj['exceptionReport']['exceptions'] = []; + this.readChildNodes(node, obj['exceptionReport']); + }, + 'ServiceException': function(node, exceptionReport) { + var exception = {}; + exception['code'] = node.getAttribute('code'); + exception['locator'] = node.getAttribute('locator'); + exception['text'] = this.getChildValue(node); + exceptionReport['exceptions'].push(exception); + } + }, + 'ows': { + 'ExceptionReport': function(node, obj) { + obj.success = false; + obj.exceptionReport = { + version: node.getAttribute('version'), + language: node.getAttribute('language'), + exceptions: [] + }; + this.readChildNodes(node, obj.exceptionReport); + }, + 'Exception': function(node, exceptionReport) { + exceptionReader.apply(this, arguments); + }, + 'ExceptionText': function(node, exception) { + exceptionTextReader.apply(this, arguments); + } + }, + 'ows11': { + 'ExceptionReport': function(node, obj) { + obj.exceptionReport = { + version: node.getAttribute('version'), + language: node.getAttribute('xml:lang'), + exceptions: [] + }; + this.readChildNodes(node, obj.exceptionReport); + }, + 'Exception': function(node, exceptionReport) { + exceptionReader.apply(this, arguments); + }, + 'ExceptionText': function(node, exception) { + exceptionTextReader.apply(this, arguments); + } + } + }; + goog.base(this); +}; +goog.inherits(ol.parser.ogc.ExceptionReport, ol.parser.XML); + + +/** + * Read OGC exception report data from a string, and return an object with + * information about the exceptions. + * + * @param {string|Document} data to read/parse. + * @return {Object} Information about the exceptions that occurred. + */ +ol.parser.ogc.ExceptionReport.prototype.read = function(data) { + if (typeof data == 'string') { + data = goog.dom.xml.loadXml(data); + } + var exceptionInfo = {}; + exceptionInfo['exceptionReport'] = null; + if (data) { + this.readChildNodes(data, exceptionInfo); + } + return exceptionInfo; +}; diff --git a/src/ol/parser/ogc/versioned.js b/src/ol/parser/ogc/versioned.js new file mode 100644 index 0000000000..0f22bfe273 --- /dev/null +++ b/src/ol/parser/ogc/versioned.js @@ -0,0 +1,121 @@ +goog.provide('ol.parser.ogc.Versioned'); +goog.require('goog.dom.xml'); +goog.require('ol.parser.ogc.ExceptionReport'); + + + +/** + * @constructor + * @param {Object} formatOptions Options which will be set on this object. + */ +ol.parser.ogc.Versioned = function(formatOptions) { + formatOptions = formatOptions || {}; + this.options = formatOptions; + this.defaultVersion = formatOptions.defaultVersion || null; + this.version = formatOptions.version; + this.profile = formatOptions.profile; + if (formatOptions.allowFallback !== undefined) { + this.allowFallback = formatOptions.allowFallback; + } else { + this.allowFallback = false; + } + if (formatOptions.stringifyOutput !== undefined) { + this.stringifyOutput = formatOptions.stringifyOutput; + } else { + this.stringifyOutput = false; + } +}; + + +/** + * @param {Element} root root element. + * @param {Object=} opt_options optional configuration object. + * @return {string} the version to use. + */ +ol.parser.ogc.Versioned.prototype.getVersion = function(root, opt_options) { + var version; + // read + if (root) { + version = this.version; + if (!version) { + version = root.getAttribute('version'); + if (!version) { + version = this.defaultVersion; + } + } + } else { + // write + version = (opt_options && opt_options.version) || + this.version || this.defaultVersion; + } + return version; +}; + + +/** + * @param {string} version the version to use. + * @return {Object} the parser to use. + */ +ol.parser.ogc.Versioned.prototype.getParser = function(version) { + version = version || this.defaultVersion; + var profile = this.profile ? '_' + this.profile : ''; + if (!this.parser || this.parser.VERSION != version) { + var format = this.parsers['v' + version.replace(/\./g, '_') + profile]; + if (!format) { + if (profile !== '' && this.allowFallback) { + // fallback to the non-profiled version of the parser + profile = ''; + format = this.parsers['v' + version.replace(/\./g, '_') + profile]; + } + if (!format) { + throw 'Can\'t find a parser for version ' + + version + profile; + } + } + this.parser = new format(this.options); + } + return this.parser; +}; + + +/** + * Write a document. + * + * @param {Object} obj An object representing the document. + * @param {Object=} opt_options Optional configuration object. + * @return {Element|string} the XML created. + */ +ol.parser.ogc.Versioned.prototype.write = function(obj, opt_options) { + var version = this.getVersion(null, opt_options); + this.parser = this.getParser(version); + var root = this.parser.write(obj, opt_options); + if (this.stringifyOutput === false) { + return root; + } else { + return goog.dom.xml.serialize(root); + } +}; + + +/** + * @param {string|Document} data Data to read. + * @param {Object=} opt_options Options for the reader. + * @return {Object} An object representing the document. + */ +ol.parser.ogc.Versioned.prototype.read = function(data, opt_options) { + if (typeof data == 'string') { + data = goog.dom.xml.loadXml(data); + } + var root = data.documentElement; + var version = this.getVersion(root); + this.parser = this.getParser(version); + var obj = this.parser.read(data, opt_options); + var errorProperty = this.parser.errorProperty || null; + if (errorProperty !== null && obj[errorProperty] === undefined) { + // an error must have happened, so parse it and report back + var format = new ol.parser.ogc.ExceptionReport(); + obj.error = format.read(data); + } + obj.version = version; + return obj; +}; diff --git a/src/ol/parser/ogc/wmscapabilities.exports b/src/ol/parser/ogc/wmscapabilities.exports new file mode 100644 index 0000000000..2552ec6664 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities.exports @@ -0,0 +1,2 @@ +@exportSymbol ol.parser.ogc.WMSCapabilities +@exportProperty ol.parser.ogc.WMSCapabilities.prototype.read diff --git a/src/ol/parser/ogc/wmscapabilities.js b/src/ol/parser/ogc/wmscapabilities.js new file mode 100644 index 0000000000..5d12af2b43 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities.js @@ -0,0 +1,52 @@ +goog.provide('ol.parser.ogc.WMSCapabilities'); +goog.require('ol.parser.ogc.Versioned'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1_0'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_3_0'); + +/** + * @define {boolean} Whether to enable WMS Capabilities version 1.1.0. + */ +ol.ENABLE_WMSCAPS_1_1_0 = true; + +/** + * @define {boolean} Whether to enable WMS Capabilities version 1.1.1. + */ +ol.ENABLE_WMSCAPS_1_1_1 = true; + +/** + * @define {boolean} Whether to enable WMS Capabilities version 1.3.0. + */ +ol.ENABLE_WMSCAPS_1_3_0 = true; + +/** + * @define {boolean} Whether to enable WMS Capabilities version 1.1.1 + * WMSC profile. + */ +ol.ENABLE_WMSCAPS_1_1_1_WMSC = true; + +/** + * @constructor + * @param {Object} formatOptions Options which will be set on this object. + * @extends {ol.parser.ogc.Versioned} + */ +ol.parser.ogc.WMSCapabilities = function(formatOptions) { + formatOptions = formatOptions || {}; + formatOptions['defaultVersion'] = '1.1.1'; + this.parsers = {}; + if (ol.ENABLE_WMSCAPS_1_1_0) { + this.parsers['v1_1_0'] = ol.parser.ogc.WMSCapabilities_v1_1_0; + } + if (ol.ENABLE_WMSCAPS_1_1_1) { + this.parsers['v1_1_1'] = ol.parser.ogc.WMSCapabilities_v1_1_1; + } + if (ol.ENABLE_WMSCAPS_1_1_1_WMSC) { + this.parsers['v1_1_1_WMSC'] = ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC; + } + if (ol.ENABLE_WMSCAPS_1_3_0) { + this.parsers['v1_3_0'] = ol.parser.ogc.WMSCapabilities_v1_3_0; + } + goog.base(this, formatOptions); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities, ol.parser.ogc.Versioned); diff --git a/src/ol/parser/ogc/wmscapabilities_v1.js b/src/ol/parser/ogc/wmscapabilities_v1.js new file mode 100644 index 0000000000..02fedc289b --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1.js @@ -0,0 +1,324 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1'); +goog.require('goog.dom.xml'); +goog.require('goog.object'); +goog.require('ol.parser.XML'); + + + +/** + * @constructor + * @extends {ol.parser.XML} + */ +ol.parser.ogc.WMSCapabilities_v1 = function() { + this.defaultPrefix = 'wms'; + this.errorProperty = 'service'; + this.namespaces = {}; + this.namespaces['wms'] = 'http://www.opengis.net/wms'; + this.namespaces['xlink'] = 'http://www.w3.org/1999/xlink'; + this.namespaces['xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'; + this.readers = { + 'wms': { + 'Service': function(node, obj) { + obj['service'] = {}; + this.readChildNodes(node, obj['service']); + }, + 'Name': function(node, obj) { + obj.name = this.getChildValue(node); + }, + 'Title': function(node, obj) { + obj.title = this.getChildValue(node); + }, + 'Abstract': function(node, obj) { + obj['abstract'] = this.getChildValue(node); + }, + 'BoundingBox': function(node, obj) { + var bbox = {}; + bbox.bbox = [ + parseFloat(node.getAttribute('minx')), + parseFloat(node.getAttribute('miny')), + parseFloat(node.getAttribute('maxx')), + parseFloat(node.getAttribute('maxy')) + ]; + var res = { + x: parseFloat(node.getAttribute('resx')), + y: parseFloat(node.getAttribute('resy')) + }; + if (! (isNaN(res.x) && isNaN(res.y))) { + bbox.res = res; + } + // return the bbox so that descendant classes can set the + // CRS and SRS and add it to the obj + return bbox; + }, + 'OnlineResource': function(node, obj) { + obj.href = this.getAttributeNS(node, this.namespaces['xlink'], + 'href'); + }, + 'ContactInformation': function(node, obj) { + obj.contactInformation = {}; + this.readChildNodes(node, obj.contactInformation); + }, + 'ContactPersonPrimary': function(node, obj) { + obj.personPrimary = {}; + this.readChildNodes(node, obj.personPrimary); + }, + 'ContactPerson': function(node, obj) { + obj.person = this.getChildValue(node); + }, + 'ContactOrganization': function(node, obj) { + obj.organization = this.getChildValue(node); + }, + 'ContactPosition': function(node, obj) { + obj.position = this.getChildValue(node); + }, + 'ContactAddress': function(node, obj) { + obj.contactAddress = {}; + this.readChildNodes(node, obj.contactAddress); + }, + 'AddressType': function(node, obj) { + obj.type = this.getChildValue(node); + }, + 'Address': function(node, obj) { + obj.address = this.getChildValue(node); + }, + 'City': function(node, obj) { + obj.city = this.getChildValue(node); + }, + 'StateOrProvince': function(node, obj) { + obj.stateOrProvince = this.getChildValue(node); + }, + 'PostCode': function(node, obj) { + obj.postcode = this.getChildValue(node); + }, + 'Country': function(node, obj) { + obj.country = this.getChildValue(node); + }, + 'ContactVoiceTelephone': function(node, obj) { + obj.phone = this.getChildValue(node); + }, + 'ContactFacsimileTelephone': function(node, obj) { + obj.fax = this.getChildValue(node); + }, + 'ContactElectronicMailAddress': function(node, obj) { + obj.email = this.getChildValue(node); + }, + 'Fees': function(node, obj) { + var fees = this.getChildValue(node); + if (fees && fees.toLowerCase() != 'none') { + obj.fees = fees; + } + }, + 'AccessConstraints': function(node, obj) { + var constraints = this.getChildValue(node); + if (constraints && constraints.toLowerCase() != 'none') { + obj.accessConstraints = constraints; + } + }, + 'Capability': function(node, obj) { + obj.capability = { + nestedLayers: [], + layers: [] + }; + this.readChildNodes(node, obj.capability); + }, + 'Request': function(node, obj) { + obj.request = {}; + this.readChildNodes(node, obj.request); + }, + 'GetCapabilities': function(node, obj) { + obj.getcapabilities = {formats: []}; + this.readChildNodes(node, obj.getcapabilities); + }, + 'Format': function(node, obj) { + if (goog.isArray(obj.formats)) { + obj.formats.push(this.getChildValue(node)); + } else { + obj.format = this.getChildValue(node); + } + }, + 'DCPType': function(node, obj) { + this.readChildNodes(node, obj); + }, + 'HTTP': function(node, obj) { + this.readChildNodes(node, obj); + }, + 'Get': function(node, obj) { + obj.get = {}; + this.readChildNodes(node, obj.get); + // backwards compatibility + if (!obj.href) { + obj.href = obj.get.href; + } + }, + 'Post': function(node, obj) { + obj.post = {}; + this.readChildNodes(node, obj.post); + // backwards compatibility + if (!obj.href) { + obj.href = obj.get.href; + } + }, + 'GetMap': function(node, obj) { + obj.getmap = {formats: []}; + this.readChildNodes(node, obj.getmap); + }, + 'GetFeatureInfo': function(node, obj) { + obj.getfeatureinfo = {formats: []}; + this.readChildNodes(node, obj.getfeatureinfo); + }, + 'Exception': function(node, obj) { + obj.exception = {formats: []}; + this.readChildNodes(node, obj.exception); + }, + 'Layer': function(node, obj) { + var parentLayer, capability; + if (obj.capability) { + capability = obj.capability; + parentLayer = obj; + } else { + capability = obj; + } + var attrNode = node.getAttributeNode('queryable'); + var queryable = (attrNode && attrNode.specified) ? + node.getAttribute('queryable') : null; + attrNode = node.getAttributeNode('cascaded'); + var cascaded = (attrNode && attrNode.specified) ? + node.getAttribute('cascaded') : null; + attrNode = node.getAttributeNode('opaque'); + var opaque = (attrNode && attrNode.specified) ? + node.getAttribute('opaque') : null; + var noSubsets = node.getAttribute('noSubsets'); + var fixedWidth = node.getAttribute('fixedWidth'); + var fixedHeight = node.getAttribute('fixedHeight'); + var parent = parentLayer || {}; + var layer = { + nestedLayers: [], + styles: parentLayer ? [].concat(parentLayer.styles) : [], + srs: {}, + metadataURLs: [], + bbox: {}, + llbbox: parent.llbbox, + dimensions: {}, + authorityURLs: {}, + identifiers: {}, + keywords: [], + queryable: (queryable && queryable !== '') ? + (queryable === '1' || queryable === 'true') : + (parent.queryable || false), + cascaded: (cascaded !== null) ? parseInt(cascaded, 10) : + (parent.cascaded || 0), + opaque: opaque ? + (opaque === '1' || opaque === 'true') : + (parent.opaque || false), + noSubsets: (noSubsets !== null) ? + (noSubsets === '1' || noSubsets === 'true') : + (parent.noSubsets || false), + fixedWidth: (fixedWidth !== null) ? + parseInt(fixedWidth, 10) : (parent.fixedWidth || 0), + fixedHeight: (fixedHeight !== null) ? + parseInt(fixedHeight, 10) : (parent.fixedHeight || 0), + minScale: parent.minScale, + maxScale: parent.maxScale, + attribution: parent.attribution + }; + if (parentLayer) { + goog.object.extend(layer.srs, parent.srs); + goog.object.extend(layer.bbox, parent.bbox); + goog.object.extend(layer.dimensions, parent.dimensions); + goog.object.extend(layer.authorityURLs, parent.authorityURLs); + } + obj.nestedLayers.push(layer); + layer.capability = capability; + this.readChildNodes(node, layer); + delete layer.capability; + if (layer.name) { + var parts = layer.name.split(':'), + request = capability.request, + gfi = request.getfeatureinfo; + if (parts.length > 0) { + layer.prefix = parts[0]; + } + capability.layers.push(layer); + if (layer.formats === undefined) { + layer.formats = request.getmap.formats; + } + if (layer.infoFormats === undefined && gfi) { + layer.infoFormats = gfi.formats; + } + } + }, + 'Attribution': function(node, obj) { + obj.attribution = {}; + this.readChildNodes(node, obj.attribution); + }, + 'LogoURL': function(node, obj) { + obj.logo = { + width: node.getAttribute('width'), + height: node.getAttribute('height') + }; + this.readChildNodes(node, obj.logo); + }, + 'Style': function(node, obj) { + var style = {}; + obj.styles.push(style); + this.readChildNodes(node, style); + }, + 'LegendURL': function(node, obj) { + var legend = { + width: node.getAttribute('width'), + height: node.getAttribute('height') + }; + obj.legend = legend; + this.readChildNodes(node, legend); + }, + 'MetadataURL': function(node, obj) { + var metadataURL = {type: node.getAttribute('type')}; + obj.metadataURLs.push(metadataURL); + this.readChildNodes(node, metadataURL); + }, + 'DataURL': function(node, obj) { + obj.dataURL = {}; + this.readChildNodes(node, obj.dataURL); + }, + 'FeatureListURL': function(node, obj) { + obj.featureListURL = {}; + this.readChildNodes(node, obj.featureListURL); + }, + 'AuthorityURL': function(node, obj) { + var name = node.getAttribute('name'); + var authority = {}; + this.readChildNodes(node, authority); + obj.authorityURLs[name] = authority.href; + }, + 'Identifier': function(node, obj) { + var authority = node.getAttribute('authority'); + obj.identifiers[authority] = this.getChildValue(node); + }, + 'KeywordList': function(node, obj) { + this.readChildNodes(node, obj); + }, + 'SRS': function(node, obj) { + obj.srs[this.getChildValue(node)] = true; + } + } + }; + goog.base(this); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1, ol.parser.XML); + + +/** + * @param {string|Document|Element} data Data to read. + * @return {Object} An object representing the document. + */ +ol.parser.ogc.WMSCapabilities_v1.prototype.read = function(data) { + if (typeof data == 'string') { + data = goog.dom.xml.loadXml(data); + } + if (data && data.nodeType == 9) { + data = data.documentElement; + } + var obj = {}; + this.readNode(data, obj); + return obj; +}; diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1.js b/src/ol/parser/ogc/wmscapabilities_v1_1.js new file mode 100644 index 0000000000..c451e73955 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1_1.js @@ -0,0 +1,99 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1_1'); +goog.require('ol.parser.ogc.WMSCapabilities_v1'); + + + +/** + * @constructor + * @extends {ol.parser.ogc.WMSCapabilities_v1} + */ +ol.parser.ogc.WMSCapabilities_v1_1 = function() { + goog.base(this); + var bboxreader = this.readers['wms']['BoundingBox']; + goog.object.extend(this.readers['wms'], { + 'WMT_MS_Capabilities': function(node, obj) { + this.readChildNodes(node, obj); + }, + 'Keyword': function(node, obj) { + if (obj.keywords) { + obj.keywords.push({value: this.getChildValue(node)}); + } + }, + 'DescribeLayer': function(node, obj) { + obj.describelayer = {formats: []}; + this.readChildNodes(node, obj.describelayer); + }, + 'GetLegendGraphic': function(node, obj) { + obj.getlegendgraphic = {formats: []}; + this.readChildNodes(node, obj.getlegendgraphic); + }, + 'GetStyles': function(node, obj) { + obj.getstyles = {formats: []}; + this.readChildNodes(node, obj.getstyles); + }, + 'PutStyles': function(node, obj) { + obj.putstyles = {formats: []}; + this.readChildNodes(node, obj.putstyles); + }, + 'UserDefinedSymbolization': function(node, obj) { + var userSymbols = { + supportSLD: parseInt(node.getAttribute('SupportSLD'), 10) == 1, + userLayer: parseInt(node.getAttribute('UserLayer'), 10) == 1, + userStyle: parseInt(node.getAttribute('UserStyle'), 10) == 1, + remoteWFS: parseInt(node.getAttribute('RemoteWFS'), 10) == 1 + }; + obj.userSymbols = userSymbols; + }, + 'LatLonBoundingBox': function(node, obj) { + obj.llbbox = [ + parseFloat(node.getAttribute('minx')), + parseFloat(node.getAttribute('miny')), + parseFloat(node.getAttribute('maxx')), + parseFloat(node.getAttribute('maxy')) + ]; + }, + 'BoundingBox': function(node, obj) { + var bbox = bboxreader.apply(this, arguments); + bbox.srs = node.getAttribute('SRS'); + obj.bbox[bbox.srs] = bbox; + }, + 'ScaleHint': function(node, obj) { + var min = parseFloat(node.getAttribute('min')); + var max = parseFloat(node.getAttribute('max')); + var rad2 = Math.pow(2, 0.5); + var dpi = (25.4 / 0.28); + var ipm = 39.37; + if (min !== 0) { + obj.maxScale = parseFloat((min / rad2) * ipm * dpi); + } + if (max != Number.POSITIVE_INFINITY) { + obj.minScale = parseFloat((max / rad2) * ipm * dpi); + } + }, + 'Dimension': function(node, obj) { + var name = node.getAttribute('name').toLowerCase(); + var dim = { + name: name, + units: node.getAttribute('units'), + unitsymbol: node.getAttribute('unitSymbol') + }; + obj.dimensions[dim.name] = dim; + }, + 'Extent': function(node, obj) { + var name = node.getAttribute('name').toLowerCase(); + if (name in obj['dimensions']) { + var extent = obj.dimensions[name]; + extent.nearestVal = + node.getAttribute('nearestValue') === '1'; + extent.multipleVal = + node.getAttribute('multipleValues') === '1'; + extent.current = node.getAttribute('current') === '1'; + extent['default'] = node.getAttribute('default') || ''; + var values = this.getChildValue(node); + extent.values = values.split(','); + } + } + }); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1, + ol.parser.ogc.WMSCapabilities_v1); diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_0.js b/src/ol/parser/ogc/wmscapabilities_v1_1_0.js new file mode 100644 index 0000000000..56f5e6c973 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_0.js @@ -0,0 +1,25 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_0'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1'); + + + +/** + * @constructor + * @extends {ol.parser.ogc.WMSCapabilities_v1_1} + */ +ol.parser.ogc.WMSCapabilities_v1_1_0 = function() { + goog.base(this); + this.version = '1.1.0'; + goog.object.extend(this.readers['wms'], { + 'SRS': function(node, obj) { + var srs = this.getChildValue(node); + var values = srs.split(/ +/); + for (var i = 0, len = values.length; i < len; i++) { + obj.srs[values[i]] = true; + } + } + }); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_0, + ol.parser.ogc.WMSCapabilities_v1_1); + diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_1.js b/src/ol/parser/ogc/wmscapabilities_v1_1_1.js new file mode 100644 index 0000000000..9dc0db672b --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_1.js @@ -0,0 +1,21 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_1'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1'); + + + +/** + * @constructor + * @extends {ol.parser.ogc.WMSCapabilities_v1_1} + */ +ol.parser.ogc.WMSCapabilities_v1_1_1 = function() { + goog.base(this); + this.version = '1.1.1'; + goog.object.extend(this.readers['wms'], { + 'SRS': function(node, obj) { + obj.srs[this.getChildValue(node)] = true; + } + }); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_1, + ol.parser.ogc.WMSCapabilities_v1_1); + diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js b/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js new file mode 100644 index 0000000000..eca49226e6 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js @@ -0,0 +1,46 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC'); +goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1'); + + + +/** + * @constructor + * @extends {ol.parser.ogc.WMSCapabilities_v1_1_1} + */ +ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC = function() { + goog.base(this); + this.profile = 'WMSC'; + goog.object.extend(this.readers['wms'], { + 'VendorSpecificCapabilities': function(node, obj) { + obj.vendorSpecific = {tileSets: []}; + this.readChildNodes(node, obj.vendorSpecific); + }, + 'TileSet': function(node, vendorSpecific) { + var tileset = {srs: {}, bbox: {}, resolutions: []}; + this.readChildNodes(node, tileset); + vendorSpecific.tileSets.push(tileset); + }, + 'Resolutions': function(node, tileset) { + var res = this.getChildValue(node).split(' '); + for (var i = 0, len = res.length; i < len; i++) { + if (res[i] !== '') { + tileset.resolutions.push(parseFloat(res[i])); + } + } + }, + 'Width': function(node, tileset) { + tileset.width = parseInt(this.getChildValue(node), 10); + }, + 'Height': function(node, tileset) { + tileset.height = parseInt(this.getChildValue(node), 10); + }, + 'Layers': function(node, tileset) { + tileset.layers = this.getChildValue(node); + }, + 'Styles': function(node, tileset) { + tileset.styles = this.getChildValue(node); + } + }); +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC, + ol.parser.ogc.WMSCapabilities_v1_1_1); diff --git a/src/ol/parser/ogc/wmscapabilities_v1_3_0.js b/src/ol/parser/ogc/wmscapabilities_v1_3_0.js new file mode 100644 index 0000000000..e3ac7ea2a0 --- /dev/null +++ b/src/ol/parser/ogc/wmscapabilities_v1_3_0.js @@ -0,0 +1,106 @@ +goog.provide('ol.parser.ogc.WMSCapabilities_v1_3_0'); +goog.require('ol.parser.ogc.WMSCapabilities_v1'); + + + +/** + * @constructor + * @extends {ol.parser.ogc.WMSCapabilities_v1} + */ +ol.parser.ogc.WMSCapabilities_v1_3_0 = function() { + goog.base(this); + var bboxreader = this.readers['wms']['BoundingBox']; + goog.object.extend(this.readers['wms'], { + 'WMS_Capabilities': function(node, obj) { + this.readChildNodes(node, obj); + }, + 'LayerLimit': function(node, obj) { + obj.layerLimit = parseInt(this.getChildValue(node), 10); + }, + 'MaxWidth': function(node, obj) { + obj.maxWidth = parseInt(this.getChildValue(node), 10); + }, + 'MaxHeight': function(node, obj) { + obj.maxHeight = parseInt(this.getChildValue(node), 10); + }, + 'BoundingBox': function(node, obj) { + var bbox = bboxreader.apply(this, arguments); + bbox.srs = node.getAttribute('CRS'); + obj.bbox[bbox.srs] = bbox; + }, + 'CRS': function(node, obj) { + // CRS is the synonym of SRS + this.readers['wms']['SRS'].apply(this, arguments); + }, + 'EX_GeographicBoundingBox': function(node, obj) { + // replacement of LatLonBoundingBox + obj.llbbox = []; + this.readChildNodes(node, obj.llbbox); + }, + 'westBoundLongitude': function(node, obj) { + obj[0] = this.getChildValue(node); + }, + 'eastBoundLongitude': function(node, obj) { + obj[2] = this.getChildValue(node); + }, + 'southBoundLatitude': function(node, obj) { + obj[1] = this.getChildValue(node); + }, + 'northBoundLatitude': function(node, obj) { + obj[3] = this.getChildValue(node); + }, + 'MinScaleDenominator': function(node, obj) { + obj.maxScale = parseFloat(this.getChildValue(node)).toPrecision(16); + }, + 'MaxScaleDenominator': function(node, obj) { + obj.minScale = parseFloat(this.getChildValue(node)).toPrecision(16); + }, + 'Dimension': function(node, obj) { + // dimension has extra attributes: default, multipleValues, + // nearestValue, current which used to be part of Extent. It now + // also contains the values. + var name = node.getAttribute('name').toLowerCase(); + var dim = { + name: name, + units: node.getAttribute('units'), + unitsymbol: node.getAttribute('unitSymbol'), + nearestVal: node.getAttribute('nearestValue') === '1', + multipleVal: node.getAttribute('multipleValues') === '1', + 'default': node.getAttribute('default') || '', + current: node.getAttribute('current') === '1', + values: this.getChildValue(node).split(',') + }; + // Theoretically there can be more dimensions with the same + // name, but with a different unit. Until we meet such a case, + // let's just keep the same structure as the WMS 1.1 + // GetCapabilities parser uses. We will store the last + // one encountered. + obj.dimensions[dim.name] = dim; + }, + 'Keyword': function(node, obj) { + var keyword = {value: this.getChildValue(node), + vocabulary: node.getAttribute('vocabulary')}; + if (obj.keywords) { + obj.keywords.push(keyword); + } + } + }); + this.readers['sld'] = { + 'UserDefinedSymbolization': function(node, obj) { + this.readers.wms.UserDefinedSymbolization.apply(this, arguments); + // add the two extra attributes + var value = node.getAttribute('InlineFeature'); + obj['userSymbols'].inlineFeature = parseInt(value, 10) == 1; + value = node.getAttribute('RemoteWCS'); + obj['userSymbols'].remoteWCS = parseInt(value, 10) == 1; + }, + 'DescribeLayer': function(node, obj) { + this.readers.wms.DescribeLayer.apply(this, arguments); + }, + 'GetLegendGraphic': function(node, obj) { + this.readers.wms.GetLegendGraphic.apply(this, arguments); + } + }; +}; +goog.inherits(ol.parser.ogc.WMSCapabilities_v1_3_0, + ol.parser.ogc.WMSCapabilities_v1); diff --git a/src/ol/parser/xml.js b/src/ol/parser/xml.js new file mode 100644 index 0000000000..269efff7ed --- /dev/null +++ b/src/ol/parser/xml.js @@ -0,0 +1,148 @@ +goog.provide('ol.parser.XML'); +goog.require('goog.object'); + + + +/** + * @constructor + */ +ol.parser.XML = function() { + // clone the namespaces object and set all namespace aliases + this.namespaces = goog.object.clone(this.namespaces); + this.namespaceAlias = {}; + for (var alias in this.namespaces) { + this.namespaceAlias[this.namespaces[alias]] = alias; + } +}; + + +/** + * Shorthand for applying one of the named readers given the node + * namespace and local name. Readers take two args (node, obj) and + * generally extend or modify the second. + * + * @param {Element|Document} node The node to be read (required). + * @param {Object} obj The object to be modified (optional). + * @return {Object} The input object, modified (or a new one if none was + * provided). + */ +ol.parser.XML.prototype.readNode = function(node, obj) { + if (!obj) { + obj = {}; + } + var group = this.readers[node.namespaceURI ? + this.namespaceAlias[node.namespaceURI] : this.defaultPrefix]; + if (group) { + var local = node.localName || node.nodeName.split(':').pop(); + var reader = group[local] || group['*']; + if (reader) { + reader.apply(this, [node, obj]); + } + } + return obj; +}; + + +/** + * Shorthand for applying the named readers to all children of a node. + * For each child of type 1 (element), is called. + * + * @param {Element|Document} node The node to be read (required). + * @param {Object} obj The object to be modified (optional). + * @return {Object} The input object, modified. + */ +ol.parser.XML.prototype.readChildNodes = function(node, obj) { + if (!obj) { + obj = {}; + } + var children = node.childNodes; + var child; + for (var i = 0, len = children.length; i < len; ++i) { + child = children[i]; + if (child.nodeType == 1) { + this.readNode(child, obj); + } + } + return obj; +}; + + +/** + * Get the textual value of the node if it exists, or return an + * optional default string. Returns an empty string if no first child + * exists and no default value is supplied. + * + * @param {Element} node The element used to look for a first child value. + * @param {string} def Optional string to return in the event that no + * first child value exists. + * @return {string} The value of the first child of the given node. + */ +ol.parser.XML.prototype.getChildValue = function(node, def) { + var value = def || ''; + if (node) { + for (var child = node.firstChild; child; child = child.nextSibling) { + switch (child.nodeType) { + case 3: // text node + case 4: // cdata section + value += child.nodeValue; + break; + default: + break; + } + } + } + return value; +}; + + +/** + * Get an attribute node given the namespace URI and local name. + * + * @param {Element} node Node on which to search for attribute nodes. + * @param {string} uri Namespace URI. + * @param {string} name Local name of the attribute (without the prefix). + * @return {?Element} An attribute node or null if none found. + */ +ol.parser.XML.prototype.getAttributeNodeNS = function(node, uri, name) { + var attributeNode = null; + if (node.getAttributeNodeNS) { + attributeNode = node.getAttributeNodeNS(uri, name); + } else { + var attributes = node.attributes; + var potentialNode, fullName; + for (var i = 0, len = attributes.length; i < len; ++i) { + potentialNode = attributes[i]; + if (potentialNode.namespaceURI == uri) { + fullName = (potentialNode.prefix) ? + (potentialNode.prefix + ':' + name) : name; + if (fullName == potentialNode.nodeName) { + attributeNode = potentialNode; + break; + } + } + } + } + return attributeNode; +}; + + +/** + * Get an attribute value given the namespace URI and local name. + * + * @param {Element} node Node on which to search for an attribute. + * @param {string} uri Namespace URI. + * @param {string} name Local name of the attribute (without the prefix). + * @return {string} An attribute value or and empty string if none found. + */ +ol.parser.XML.prototype.getAttributeNS = function(node, uri, name) { + var attributeValue = ''; + if (node.getAttributeNS) { + attributeValue = node.getAttributeNS(uri, name) || ''; + } else { + var attributeNode = this.getAttributeNodeNS(node, uri, name); + if (attributeNode) { + attributeValue = attributeNode.nodeValue; + } + } + return attributeValue; +}; diff --git a/test/spec/ol/parser/ogc/exceptionreport.test.js b/test/spec/ol/parser/ogc/exceptionreport.test.js new file mode 100644 index 0000000000..069aef371c --- /dev/null +++ b/test/spec/ol/parser/ogc/exceptionreport.test.js @@ -0,0 +1,101 @@ +goog.provide('ol.test.parser.ogc.ExceptionReport'); + +describe('ol.parser.ogc.exceptionreport', function() { + + var parser = new ol.parser.ogc.ExceptionReport(); + + describe('test read exception', function() { + var result, exceptions; + var url = 'spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + result = parser.read(xhr.getResponseXml()); + exceptions = result.exceptionReport.exceptions; + }); + it('OCG WMS 1.3.0 exceptions', function() { + expect(exceptions.length).toBe(4); + var str = 'Plain text message about an error.'; + expect(goog.string.trim(exceptions[0].text)).toBe(str); + expect(exceptions[1].code).toBe('InvalidUpdateSequence'); + str = ' Another error message, this one with a service exception ' + + 'code supplied. '; + expect(exceptions[1].text).toBe(str); + str = 'Error in module , line 42A message that includes angle ' + + 'brackets in text must be enclosed in a Character Data Section as ' + + 'in this example. All XML-like markup is ignored except for this ' + + 'sequence of three closing characters:'; + expect(goog.string.trim(exceptions[2].text), str); + str = 'foo.c An error occurred ' + + 'Similarly, actual XML can be enclosed in a CDATA ' + + 'section. A generic parser will ignore that XML, but ' + + 'application-specific software may choose to process it.' + + ''; + expect(goog.string.trim(exceptions[3].text), str); + }); + }); + + describe('test read exception OWSCommon 1.0.0', function() { + var result, report, exception; + var url = 'spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + result = parser.read(xhr.getResponseXml()); + report = result.exceptionReport; + exception = report.exceptions[0]; + }); + it('Version parsed correctly', function() { + expect(report.version).toEqual('1.0.0'); + }); + it('Language parsed correctly', function() { + expect(report.language).toEqual('en'); + }); + it('exceptionCode properly parsed', function() { + expect(exception.code).toEqual('InvalidParameterValue'); + }); + it('locator properly parsed', function() { + expect(exception.locator).toEqual('foo'); + }); + it('ExceptionText correctly parsed', function() { + var msg = 'Update error: Error occured updating features'; + expect(exception.texts[0]).toEqual(msg); + }); + it('Second ExceptionText correctly parsed', function() { + var msg = 'Second exception line'; + expect(exception.texts[1]).toEqual(msg); + }); + }); + + describe('test read exception OWSCommon 1.1.0', function() { + var result, report, exception; + var url = 'spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + result = parser.read(xhr.getResponseXml()); + report = result.exceptionReport; + exception = report.exceptions[0]; + }); + it('Version parsed correctly', function() { + expect(report.version).toEqual('1.1.0'); + }); + it('Language parsed correctly', function() { + expect(report.language).toEqual('en'); + }); + it('exceptionCode properly parsed', function() { + expect(exception.code).toEqual('InvalidParameterValue'); + }); + it('locator properly parsed', function() { + expect(exception.locator).toEqual('foo'); + }); + it('ExceptionText correctly parsed', function() { + var msg = 'Update error: Error occured updating features'; + expect(exception.texts[0]).toEqual(msg); + }); + it('Second ExceptionText correctly parsed', function() { + expect(exception.texts[1]).toEqual('Second exception line'); + }); + }); +}); + +goog.require('goog.net.XhrIo'); +goog.require('goog.string'); +goog.require('ol.parser.ogc.ExceptionReport'); diff --git a/test/spec/ol/parser/ogc/versioned.test.js b/test/spec/ol/parser/ogc/versioned.test.js new file mode 100644 index 0000000000..25728b98d0 --- /dev/null +++ b/test/spec/ol/parser/ogc/versioned.test.js @@ -0,0 +1,28 @@ +goog.provide('ol.test.parser.ogc.Versioned'); + +describe('ol.parser.ogc.versioned', function() { + + var snippet = ''; + var snippet2 = ''; + + describe('test constructor', function() { + var parser = new ol.parser.ogc.Versioned({version: '1.0.0'}); + it('new OpenLayers.Format.XML.VersionedOGC returns object', function() { + expect(parser instanceof ol.parser.ogc.Versioned).toBeTruthy(); + }); + it('constructor sets version correctly', function() { + expect(parser.version).toEqual('1.0.0'); + }); + it('defaultVersion should be null if not specified', function() { + expect(parser.defaultVersion).toBeNull(); + }); + it('format has a read function', function() { + expect(typeof(parser.read)).toEqual('function'); + }); + it('format has a write function', function() { + expect(typeof(parser.write)).toEqual('function'); + }); + }); +}); + +goog.require('ol.parser.ogc.Versioned'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities.test.js b/test/spec/ol/parser/ogc/wmscapabilities.test.js new file mode 100644 index 0000000000..579898a1f4 --- /dev/null +++ b/test/spec/ol/parser/ogc/wmscapabilities.test.js @@ -0,0 +1,45 @@ +goog.provide('ol.test.parser.ogc.WMSCapabilities'); + +describe('test WMSCapabilities', function() { + describe('test getVersion', function() { + var snippet = '' + + ''; + var snippet2 = '' + + ''; + it('Version taken from document', function() { + var parser = new ol.parser.ogc.WMSCapabilities(); + var data = parser.read(snippet); + expect(data.version).toEqual('1.3.0'); + }); + it('Version taken from parser takes preference', function() { + var parser = new ol.parser.ogc.WMSCapabilities({version: '1.1.0'}); + var data = parser.read(snippet); + expect(data.version).toEqual('1.1.0'); + }); + it('If nothing else is set, defaultVersion should be returned', function() { + var parser = new ol.parser.ogc.WMSCapabilities({defaultVersion: '1.1.1'}); + var data = parser.read(snippet2); + expect(data.version).toEqual('1.1.1'); + }); + var parser = new ol.parser.ogc.WMSCapabilities({defaultVersion: '1.1.1'}); + it('Version from options returned', function() { + var version = parser.getVersion(null, {version: '1.3.0'}); + expect(version).toEqual('1.3.0'); + }); + var msg = 'defaultVersion returned if no version specified in options ' + + 'and no version on the format'; + it(msg, function() { + var version = parser.getVersion(null); + expect(version).toEqual('1.1.1'); + }); + msg = 'version returned of the Format if no version specified in options'; + it(msg, function() { + parser.version = '1.1.0'; + var version = parser.getVersion(null); + expect(version).toEqual('1.1.0'); + }); + }); +}); + +goog.require('ol.parser.ogc.WMSCapabilities'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js new file mode 100644 index 0000000000..bf453a971e --- /dev/null +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js @@ -0,0 +1,444 @@ +goog.provide('ol.test.parser.ogc.WMSCapabilities_v1_1_1'); + +describe('ol.parser.ogc.wmscapabilities_v1_1_1', function() { + + var parser = new ol.parser.ogc.WMSCapabilities(); + + describe('test read exception', function() { + var obj, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + }); + it('Error reported correctly', function() { + expect(!!obj.error).toBeTruthy(); + }); + }); + + describe('test read', function() { + var obj, capability, getmap, describelayer, getfeatureinfo, layer, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + capability = obj.capability; + getmap = capability.request.getmap; + describelayer = capability.request.describelayer; + getfeatureinfo = capability.request.getfeatureinfo; + layer = capability.layers[2]; + }); + it('object contains capability property', function() { + expect(capability).toBeTruthy(); + }); + it('getmap formats parsed', function() { + expect(getmap.formats.length).toEqual(28); + }); + it('getmap href parsed', function() { + var url = 'http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&'; + expect(getmap.href).toEqual(url); + }); + it('getmap.get.href parsed', function() { + expect(getmap.get.href).toEqual(getmap.href); + }); + it('getmap.post not available', function() { + expect(getmap.post).toBeUndefined(); + }); + it('describelayer href parsed', function() { + var url = 'http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&'; + expect(describelayer.href).toEqual(url); + }); + it('describelayer.get.href parsed', function() { + expect(describelayer.get.href).toEqual(describelayer.href); + }); + it('describelayer.post not available', function() { + expect(describelayer.post).toBeUndefined(); + }); + it('getfeatureinfo href parsed', function() { + var url = 'http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&'; + expect(getfeatureinfo.href).toEqual(url); + }); + it('getmap.get.href parsed', function() { + expect(getfeatureinfo.get.href).toEqual(getfeatureinfo.href); + }); + it('getfeatureinfo.post set correctly', function() { + var url = 'http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&'; + expect(getfeatureinfo.post.href).toEqual(url); + }); + it('layers parsed', function() { + expect(capability.layers).toBeTruthy(); + }); + it('correct number of layers parsed', function() { + expect(capability.layers.length).toEqual(22); + }); + it('infoFormats set on layer', function() { + var infoFormats = ['text/plain', 'text/html', 'application/vnd.ogc.gml']; + expect(layer.infoFormats).toEqual(infoFormats); + }); + it('[2] correct layer name', function() { + expect(layer.name).toEqual('tiger:tiger_roads'); + }); + it('[2] correct layer prefix', function() { + expect(layer.prefix).toEqual('tiger'); + }); + it('[2] correct layer title', function() { + expect(layer.title).toEqual('Manhattan (NY) roads'); + }); + it('[2] correct layer abstract', function() { + var abstr = 'Highly simplified road layout of Manhattan in New York..'; + expect(layer['abstract']).toEqual(abstr); + }); + it('[2] correct layer bbox', function() { + var bbox = [-74.08769307536667, 40.660618924633326, + -73.84653192463333, 40.90178007536667]; + expect(layer.llbbox).toEqual(bbox); + }); + it('[2] correct styles length', function() { + expect(layer.styles.length).toEqual(1); + }); + it('[2] correct style name', function() { + expect(layer.styles[0].name).toEqual('tiger_roads'); + }); + it('[2] correct legend url', function() { + var url = 'http://publicus.opengeo.org:80/geoserver/wms/' + + 'GetLegendGraphic?VERSION=1.0.0&FORMAT=image/png&WIDTH=20&' + + 'HEIGHT=20&LAYER=tiger:tiger_roads'; + expect(layer.styles[0].legend.href).toEqual(url); + }); + it('[2] correct legend format', function() { + expect(layer.styles[0].legend.format).toEqual('image/png'); + }); + it('[2] correct queryable attribute', function() { + expect(layer.queryable).toBeTruthy(); + }); + }); + + describe('test layers', function() { + var obj, capability, layers = {}, rootlayer, identifiers, authorities; + var featurelist, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + capability = obj.capability; + for (var i = 0, len = capability.layers.length; i < len; i++) { + if ('name' in capability.layers[i]) { + layers[capability.layers[i].name] = capability.layers[i]; + } + } + rootlayer = capability.layers[capability.layers.length - 1]; + identifiers = layers['ROADS_RIVERS'].identifiers; + authorities = layers['ROADS_RIVERS'].authorityURLs; + featurelist = layers['ROADS_RIVERS'].featureListURL; + }); + it('SRS parsed correctly for root layer', function() { + expect(rootlayer.srs).toEqual({'EPSG:4326': true}); + }); + it('Inheritance of SRS handled correctly when adding SRSes', function() { + var srs = {'EPSG:4326': true, 'EPSG:26986': true}; + expect(layers['ROADS_RIVERS'].srs).toEqual(srs); + }); + var msg = 'Inheritance of SRS handled correctly when redeclaring an ' + + 'inherited SRS'; + it(msg, function() { + expect(layers['Temperature'].srs).toEqual({'EPSG:4326': true}); + }); + it('Correct bbox and res from BoundingBox', function() { + var bbox = layers['ROADS_RIVERS'].bbox['EPSG:26986']; + expect(bbox.bbox).toEqual([189000, 834000, 285000, 962000]); + expect(bbox.res).toEqual({x: 1, y: 1}); + }); + it('Correct bbox and res from BoundingBox (override)', function() { + bbox = layers['ROADS_RIVERS'].bbox['EPSG:4326']; + expect(bbox.bbox).toEqual([-71.63, 41.75, -70.78, 42.90]); + expect(bbox.res).toEqual({x: 0.01, y: 0.01}); + }); + it('Correctly inherited bbox and resolution', function() { + bbox = layers['ROADS_1M'].bbox['EPSG:26986']; + expect(bbox.bbox).toEqual([189000, 834000, 285000, 962000]); + expect(bbox.res).toEqual({x: 1, y: 1}); + }); + it('got identifiers from layer ROADS_RIVERS', function() { + expect(identifiers).toBeTruthy(); + }); + it('authority attribute from Identifiers parsed correctly', function() { + expect('DIF_ID' in identifiers).toBeTruthy(); + }); + it('Identifier value parsed correctly', function() { + expect(identifiers['DIF_ID']).toEqual('123456'); + }); + it('AuthorityURLs parsed and inherited correctly', function() { + expect('DIF_ID' in authorities).toBeTruthy(); + }); + it('OnlineResource in AuthorityURLs parsed correctly', function() { + var url = 'http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html'; + expect(authorities['DIF_ID']).toEqual(url); + }); + it('layer has FeatureListURL', function() { + expect(featurelist).toBeTruthy(); + }); + it('FeatureListURL format parsed correctly', function() { + expect(featurelist.format).toEqual('application/vnd.ogc.se_xml'); + }); + it('FeatureListURL OnlineResource parsed correctly', function() { + var url = 'http://www.university.edu/data/roads_rivers.gml'; + expect(featurelist.href).toEqual(url); + }); + it('queryable property inherited correctly', function() { + expect(layers['Pressure'].queryable).toBeTruthy(); + }); + it('queryable property has correct default value', function() { + expect(layers['ozone_image'].queryable).toBeFalsy(); + }); + it('cascaded property parsed correctly', function() { + expect(layers['population'].cascaded).toEqual(1); + }); + it('fixedWidth property correctly parsed', function() { + expect(layers['ozone_image'].fixedWidth).toEqual(512); + }); + it('fixedHeight property correctly parsed', function() { + expect(layers['ozone_image'].fixedHeight).toEqual(256); + }); + it('opaque property parsed correctly', function() { + expect(layers['ozone_image'].opaque).toBeTruthy(); + }); + it('noSubsets property parsed correctly', function() { + expect(layers['ozone_image'].noSubsets).toBeTruthy(); + }); + }); + + describe('test dimensions', function() { + var obj, capability, layers = {}, time, elevation, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + capability = obj.capability; + for (var i = 0, len = capability.layers.length; i < len; i++) { + if ('name' in capability.layers[i]) { + layers[capability.layers[i].name] = capability.layers[i]; + } + } + time = layers['Clouds'].dimensions.time; + elevation = layers['Pressure'].dimensions.elevation; + }); + it('Default time value parsed correctly', function() { + expect(time['default']).toEqual('2000-08-22'); + }); + it('Currect number of time extent values/periods', function() { + expect(time.values.length).toEqual(1); + }); + it('Time extent values parsed correctly', function() { + expect(time.values[0]).toEqual('1999-01-01/2000-08-22/P1D'); + }); + it('Dimension units parsed correctly', function() { + expect(elevation.units).toEqual('EPSG:5030'); + }); + it('Default elevation value parsed correctly', function() { + expect(elevation['default']).toEqual('0'); + }); + it('NearestValue parsed correctly', function() { + expect(elevation.nearestVal).toBeTruthy(); + }); + it('Absense of MultipleValues handled correctly', function() { + expect(elevation.multipleVal).toBeFalsy(); + }); + it('Parsing of comma-separated values done correctly', function() { + expect(elevation.values).toEqual(['0', '1000', '3000', '5000', '10000']); + }); + }); + + describe('test contact info', function() { + var obj, service, contactinfo, personPrimary, addr, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + service = obj.service; + contactinfo = service.contactInformation; + personPrimary = contactinfo.personPrimary; + addr = contactinfo.contactAddress; + }); + it('object contains contactInformation property', function() { + expect(contactinfo).toBeTruthy(); + }); + it('object contains personPrimary property', function() { + expect(personPrimary).toBeTruthy(); + }); + it('ContactPerson parsed correctly', function() { + expect(personPrimary.person).toEqual('Jeff deLaBeaujardiere'); + }); + it('ContactOrganization parsed correctly', function() { + expect(personPrimary.organization).toEqual('NASA'); + }); + it('ContactPosition parsed correctly', function() { + expect(contactinfo.position).toEqual('Computer Scientist'); + }); + it('object contains contactAddress property', function() { + expect(addr).toBeTruthy(); + }); + it('AddressType parsed correctly', function() { + expect(addr.type).toEqual('postal'); + }); + it('Address parsed correctly', function() { + var address = 'NASA Goddard Space Flight Center, Code 933'; + expect(addr.address).toEqual(address); + }); + it('City parsed correctly', function() { + expect(addr.city).toEqual('Greenbelt'); + }); + it('StateOrProvince parsed correctly', function() { + expect(addr.stateOrProvince).toEqual('MD'); + }); + it('PostCode parsed correctly', function() { + expect(addr.postcode).toEqual('20771'); + }); + it('Country parsed correctly', function() { + expect(addr.country).toEqual('USA'); + }); + it('ContactVoiceTelephone parsed correctly', function() { + expect(contactinfo.phone).toEqual('+1 301 286-1569'); + }); + it('ContactFacsimileTelephone parsed correctly', function() { + expect(contactinfo.fax).toEqual('+1 301 286-1777'); + }); + it('ContactElectronicMailAddress parsed correctly', function() { + expect(contactinfo.email).toEqual('delabeau@iniki.gsfc.nasa.gov'); + }); + }); + + describe('Test fees and constraints', function() { + var obj, service, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + service = obj.service; + }); + it('Fees=none handled correctly', function() { + expect('fees' in service).toBeFalsy(); + }); + it('AccessConstraints=none handled correctly', function() { + expect('accessConstraints' in service).toBeFalsy(); + }); + }); + + describe('Test requests', function() { + var obj, request, exception, userSymbols, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + request = obj.capability.request; + exception = obj.capability.exception; + userSymbols = obj.capability.userSymbols; + }); + it('request property exists', function() { + expect(request).toBeTruthy(); + }); + it('got GetMap request', function() { + expect('getmap' in request).toBeTruthy(); + }); + it('got GetFeatureInfo request', function() { + expect('getfeatureinfo' in request).toBeTruthy(); + }); + it('GetFeatureInfo formats correctly parsed', function() { + var formats = ['text/plain', 'text/html', 'application/vnd.ogc.gml']; + expect(request.getfeatureinfo.formats).toEqual(formats); + }); + it('got DescribeLayer request', function() { + expect('describelayer' in request).toBeTruthy(); + }); + it('got GetLegendGraphic request', function() { + expect('getlegendgraphic' in request).toBeTruthy(); + }); + it('exception property exists', function() { + expect(exception).toBeTruthy(); + }); + it('Exception Format parsed', function() { + expect(exception.formats).toEqual(['application/vnd.ogc.se_xml']); + }); + it('userSymbols property exists', function() { + expect(userSymbols).toBeTruthy(); + }); + it('supportSLD parsed', function() { + expect(userSymbols.supportSLD).toBeTruthy(); + }); + it('userLayer parsed', function() { + expect(userSymbols.userLayer).toBeTruthy(); + }); + it('userStyle parsed', function() { + expect(userSymbols.userStyle).toBeTruthy(); + }); + it('remoteWFS parsed', function() { + expect(userSymbols.remoteWFS).toBeTruthy(); + }); + }); + + describe('test ogc', function() { + var obj, capability, attribution, keywords, metadataURLs, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + capability = obj.capability; + attribution = capability.layers[2].attribution; + keywords = capability.layers[0].keywords; + metadataURLs = capability.layers[0].metadataURLs; + }); + it('attribution title parsed correctly.', function() { + expect(attribution.title).toEqual('State College University'); + }); + it('attribution href parsed correctly.', function() { + expect(attribution.href).toEqual('http://www.university.edu/'); + }); + it('attribution logo url parsed correctly.', function() { + var url = 'http://www.university.edu/icons/logo.gif'; + expect(attribution.logo.href).toEqual(url); + }); + it('attribution logo format parsed correctly.', function() { + expect(attribution.logo.format).toEqual('image/gif'); + }); + it('attribution logo width parsed correctly.', function() { + expect(attribution.logo.width).toEqual('100'); + }); + it('attribution logo height parsed correctly.', function() { + expect(attribution.logo.height).toEqual('100'); + }); + it('layer has 3 keywords.', function() { + expect(keywords.length).toEqual(3); + }); + it('1st keyword parsed correctly.', function() { + expect(keywords[0].value).toEqual('road'); + }); + it('layer has 2 metadata urls.', function() { + expect(metadataURLs.length).toEqual(2); + }); + it('type parsed correctly.', function() { + expect(metadataURLs[0].type).toEqual('FGDC'); + }); + it('format parsed correctly.', function() { + expect(metadataURLs[0].format).toEqual('text/plain'); + }); + it('href parsed correctly.', function() { + var href = 'http://www.university.edu/metadata/roads.txt'; + expect(metadataURLs[0].href).toEqual(href); + }); + it('layer.minScale is correct', function() { + expect(Math.round(capability.layers[0].minScale)).toEqual(250000); + }); + it('layer.maxScale is correct', function() { + expect(Math.round(capability.layers[0].maxScale)).toEqual(1000); + }); + it('layer.minScale for max="Infinity" is correct', function() { + expect(capability.layers[1].minScale).toBeUndefined(); + }); + it('layer.maxScale for min="0" is correct', function() { + expect(capability.layers[1].maxScale).toBeUndefined(); + }); + }); + +}); + +goog.require('goog.net.XhrIo'); +goog.require('ol.parser.ogc.WMSCapabilities'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js new file mode 100644 index 0000000000..38146d6edc --- /dev/null +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js @@ -0,0 +1,74 @@ +goog.provide('ol.test.parser.ogc.WMSCapabilities_v1_1_1_WMSC'); + +describe('ol.parser.ogc.wmscapabilities_v1_1_1_wmsc', function() { + + var parser = new ol.parser.ogc.WMSCapabilities({ + profile: 'WMSC', + allowFallback: true + }); + + describe('test read', function() { + var obj, tilesets, tileset, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + tilesets = obj.capability.vendorSpecific.tileSets; + tileset = tilesets[0]; + }); + it('We expect 2 tilesets to be parsed', function() { + expect(tilesets.length).toEqual(2); + }); + it('BBOX correctly parsed', function() { + var bbox = [-13697515.466796875, 5165920.118906248, + -13619243.94984375, 5244191.635859374]; + expect(tileset.bbox['EPSG:900913'].bbox).toEqual(bbox); + }); + it('Format correctly parsed', function() { + expect(tileset.format).toEqual('image/png'); + }); + it('Height correctly parsed', function() { + expect(tileset.height).toEqual(256); + }); + it('Width correctly parsed', function() { + expect(tileset.width).toEqual(256); + }); + it('Layers correctly parsed', function() { + expect(tileset.layers).toEqual('medford:hydro'); + }); + it('SRS correctly parsed', function() { + expect(tileset.srs['EPSG:900913']).toBeTruthy(); + }); + it('Resolutions correctly parsed', function() { + var resolutions = [156543.03390625, 78271.516953125, 39135.7584765625, + 19567.87923828125, 9783.939619140625, 4891.9698095703125, + 2445.9849047851562, 1222.9924523925781, 611.4962261962891, + 305.74811309814453, 152.87405654907226, 76.43702827453613, + 38.218514137268066, 19.109257068634033, 9.554628534317017, + 4.777314267158508, 2.388657133579254, 1.194328566789627, + 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, + 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, + 0.009330691928043961, 0.004665345964021981]; + expect(tileset.resolutions).toEqual(resolutions); + }); + it('Styles correctly parsed', function() { + expect(tileset.styles).toEqual(''); + }); + }); + + describe('test fallback', function() { + var obj, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + }); + it('layers parsed with allowFallback true', function() { + expect(obj.capability.layers.length).toEqual(2); + }); + }); + +}); + +goog.require('goog.net.XhrIo'); +goog.require('ol.parser.ogc.WMSCapabilities'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js new file mode 100644 index 0000000000..2aab980278 --- /dev/null +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js @@ -0,0 +1,297 @@ +goog.provide('ol.test.parser.ogc.WMSCapabilities_v1_3_0'); + +describe('ol.parser.ogc.wmscapabilities_v1_3_0', function() { + + var parser = new ol.parser.ogc.WMSCapabilities(); + + var obj, capability, layers = {}, rootlayer, identifiers, authorities; + var featurelist, time, elevation, service, contactinfo, personPrimary, addr; + var request, exception, attribution, keywords, metadataURLs, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + capability = obj.capability; + for (var i = 0, len = capability.layers.length; i < len; i++) { + if ('name' in capability.layers[i]) { + layers[capability.layers[i].name] = capability.layers[i]; + } + } + rootlayer = capability.layers[capability.layers.length - 1]; + identifiers = layers['ROADS_RIVERS'].identifiers; + authorities = layers['ROADS_RIVERS'].authorityURLs; + featurelist = layers['ROADS_RIVERS'].featureListURL; + time = layers['Clouds'].dimensions.time; + elevation = layers['Pressure'].dimensions.elevation; + service = obj.service; + contactinfo = service.contactInformation; + personPrimary = contactinfo.personPrimary; + addr = contactinfo.contactAddress; + request = obj.capability.request; + exception = obj.capability.exception; + attribution = capability.layers[2].attribution; + keywords = capability.layers[0].keywords; + metadataURLs = capability.layers[0].metadataURLs; + }); + + describe('test read exception', function() { + var result, url; + url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + result = parser.read(xhr.getResponseXml()); + }); + it('Error reported correctly', function() { + expect(!!result.error).toBe(true); + }); + }); + + describe('test layers', function() { + it('SRS parsed correctly for root layer', function() { + expect(rootlayer.srs).toEqual({'CRS:84': true}); + }); + it('Inheritance of SRS handled correctly when adding SRSes', function() { + var srs = {'CRS:84': true, 'EPSG:26986': true}; + expect(layers['ROADS_RIVERS'].srs).toEqual(srs); + }); + it('Inheritance of SRS handled correctly when redeclaring an' + + ' inherited SRS', function() { + expect(layers['Temperature'].srs).toEqual({'CRS:84': true}); + }); + it('infoFormats set correctly on layer', function() { + var infoFormats = ['text/xml', 'text/plain', 'text/html']; + expect(layers['Temperature'].infoFormats).toEqual(infoFormats); + }); + it('Correct resolution and bbox from BoundingBox', function() { + var bbox = layers['ROADS_RIVERS'].bbox['EPSG:26986']; + expect(bbox.bbox).toEqual([189000, 834000, 285000, 962000]); + expect(bbox.res).toEqual({x: 1, y: 1}); + }); + it('Correct resolution and bbox from BoundingBox (override)', function() { + var bbox = layers['ROADS_RIVERS'].bbox['CRS:84']; + expect(bbox.bbox).toEqual([-71.63, 41.75, -70.78, 42.90]); + expect(bbox.res).toEqual({x: 0.01, y: 0.01}); + }); + it('Correctly inherited bbox and resolution', function() { + var bbox = layers['ROADS_1M'].bbox['EPSG:26986']; + expect(bbox.bbox).toEqual([189000, 834000, 285000, 962000]); + expect(bbox.res).toEqual({x: 1, y: 1}); + }); + it('got identifiers from layer ROADS_RIVERS', function() { + expect(identifiers).toBeTruthy(); + }); + it('authority attribute from Identifiers parsed correctly', function() { + expect('DIF_ID' in identifiers).toBeTruthy(); + }); + it('Identifier value parsed correctly', function() { + expect(identifiers['DIF_ID']).toEqual('123456'); + }); + it('AuthorityURLs parsed and inherited correctly', function() { + expect('DIF_ID' in authorities).toBeTruthy(); + }); + it('OnlineResource in AuthorityURLs parsed correctly', function() { + var url = 'http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html'; + expect(authorities['DIF_ID']).toEqual(url); + }); + it('layer has FeatureListURL', function() { + expect(featurelist).toBeTruthy(); + }); + it('FeatureListURL format parsed correctly', function() { + expect(featurelist.format).toEqual('XML'); + }); + it('FeatureListURL OnlineResource parsed correctly', function() { + var url = 'http://www.university.edu/data/roads_rivers.gml'; + expect(featurelist.href).toEqual(url); + }); + it('queryable property inherited correctly', function() { + expect(layers['Pressure'].queryable).toBeTruthy(); + }); + it('queryable property has correct default value', function() { + expect(layers['ozone_image'].queryable).toBeFalsy(); + }); + it('cascaded property parsed correctly', function() { + expect(layers['population'].cascaded).toEqual(1); + }); + it('fixedWidth property correctly parsed', function() { + expect(layers['ozone_image'].fixedWidth).toEqual(512); + }); + it('fixedHeight property correctly parsed', function() { + expect(layers['ozone_image'].fixedHeight).toEqual(256); + }); + it('opaque property parsed correctly', function() { + expect(layers['ozone_image'].opaque).toBeTruthy(); + }); + it('noSubsets property parsed correctly', function() { + expect(layers['ozone_image'].noSubsets).toBeTruthy(); + }); + }); + + describe('test dimensions', function() { + it('Default time value parsed correctly', function() { + expect(time['default']).toEqual('2000-08-22'); + }); + it('Currect number of time extent values/periods', function() { + expect(time.values.length).toEqual(1); + }); + it('Time extent values parsed correctly', function() { + expect(time.values[0]).toEqual('1999-01-01/2000-08-22/P1D'); + }); + it('Dimension units parsed correctly', function() { + expect(elevation.units).toEqual('CRS:88'); + }); + it('Default elevation value parsed correctly', function() { + expect(elevation['default']).toEqual('0'); + }); + it('NearestValue parsed correctly', function() { + expect(elevation.nearestVal).toBeTruthy(); + }); + it('Absense of MultipleValues handled correctly', function() { + expect(elevation.multipleVal).toBeFalsy(); + }); + it('Parsing of comma-separated values done correctly', function() { + expect(elevation.values).toEqual(['0', '1000', '3000', '5000', '10000']); + }); + }); + + describe('test contact info', function() { + it('object contains contactInformation property', function() { + expect(contactinfo).toBeTruthy(); + }); + it('object contains personPrimary property', function() { + expect(personPrimary).toBeTruthy(); + }); + it('ContactPerson parsed correctly', function() { + expect(personPrimary.person).toEqual('Jeff Smith'); + }); + it('ContactOrganization parsed correctly', function() { + expect(personPrimary.organization).toEqual('NASA'); + }); + it('ContactPosition parsed correctly', function() { + expect(contactinfo.position).toEqual('Computer Scientist'); + }); + it('object contains contactAddress property', function() { + expect(addr).toBeTruthy(); + }); + it('AddressType parsed correctly', function() { + expect(addr.type).toEqual('postal'); + }); + it('Address parsed correctly', function() { + expect(addr.address).toEqual('NASA Goddard Space Flight Center'); + }); + it('City parsed correctly', function() { + expect(addr.city).toEqual('Greenbelt'); + }); + it('StateOrProvince parsed correctly', function() { + expect(addr.stateOrProvince).toEqual('MD'); + }); + it('PostCode parsed correctly', function() { + expect(addr.postcode).toEqual('20771'); + }); + it('Country parsed correctly', function() { + expect(addr.country).toEqual('USA'); + }); + it('ContactVoiceTelephone parsed correctly', function() { + expect(contactinfo.phone).toEqual('+1 301 555-1212'); + }); + it('ContactElectronicMailAddress parsed correctly', function() { + expect(contactinfo.email).toEqual('user@host.com'); + }); + }); + + describe('test fees and constraints', function() { + it('Fees=none handled correctly', function() { + expect('fees' in service).toBeFalsy(); + }); + it('AccessConstraints=none handled correctly', function() { + expect('accessConstraints' in service).toBeFalsy(); + }); + }); + + describe('test requests', function() { + it('request property exists', function() { + expect(request).toBeTruthy(); + }); + it('got GetMap request', function() { + expect('getmap' in request).toBeTruthy(); + }); + it('got GetFeatureInfo request', function() { + expect('getfeatureinfo' in request).toBeTruthy(); + }); + it('GetFeatureInfo formats correctly parsed', function() { + var formats = ['text/xml', 'text/plain', 'text/html']; + expect(request.getfeatureinfo.formats).toEqual(formats); + }); + it('exception property exists', function() { + expect(exception).toBeTruthy(); + }); + it('Exception Format parsed', function() { + var formats = ['XML', 'INIMAGE', 'BLANK']; + expect(exception.formats).toEqual(formats); + }); + }); + + describe('test ogc', function() { + it('attribution title parsed correctly.', function() { + expect(attribution.title).toEqual('State College University'); + }); + it('attribution href parsed correctly.', function() { + expect(attribution.href).toEqual('http://www.university.edu/'); + }); + it('attribution logo url parsed correctly.', function() { + var url = 'http://www.university.edu/icons/logo.gif'; + expect(attribution.logo.href).toEqual(url); + }); + it('attribution logo format parsed correctly.', function() { + expect(attribution.logo.format).toEqual('image/gif'); + }); + it('attribution logo width parsed correctly.', function() { + expect(attribution.logo.width).toEqual('100'); + }); + it('attribution logo height parsed correctly.', function() { + expect(attribution.logo.height).toEqual('100'); + }); + it('layer has 3 keywords.', function() { + expect(keywords.length).toEqual(3); + }); + it('1st keyword parsed correctly.', function() { + expect(keywords[0].value).toEqual('road'); + }); + it('layer has 2 metadata urls.', function() { + expect(metadataURLs.length).toEqual(2); + }); + it('type parsed correctly.', function() { + expect(metadataURLs[0].type).toEqual('FGDC:1998'); + }); + it('format parsed correctly.', function() { + expect(metadataURLs[0].format).toEqual('text/plain'); + }); + it('href parsed correctly.', function() { + var url = 'http://www.university.edu/metadata/roads.txt'; + expect(metadataURLs[0].href).toEqual(url); + }); + it('layer.minScale is correct', function() { + var minScale = 250000; + expect(capability.layers[0].minScale).toEqual(minScale.toPrecision(16)); + }); + it('layer.maxScale is correct', function() { + var maxScale = 1000; + expect(capability.layers[0].maxScale).toEqual(maxScale.toPrecision(16)); + }); + }); + + describe('test WMS 1.3 specials', function() { + it('LayerLimit parsed correctly', function() { + expect(obj.service.layerLimit).toEqual(16); + }); + it('MaxHeight parsed correctly', function() { + expect(obj.service.maxHeight).toEqual(2048); + }); + it('MaxWidth parsed correctly', function() { + expect(obj.service.maxWidth).toEqual(2048); + }); + }); + +}); + +goog.require('goog.net.XhrIo'); +goog.require('ol.parser.ogc.WMSCapabilities'); diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml new file mode 100644 index 0000000000..141558d04d --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml @@ -0,0 +1,9 @@ + + + + Update error: Error occured updating features + Second exception line + + diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml new file mode 100644 index 0000000000..9fed1376dd --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml @@ -0,0 +1,9 @@ + + + + Update error: Error occured updating features + Second exception line + + diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml new file mode 100644 index 0000000000..631d67064a --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml @@ -0,0 +1,16 @@ + + + Plain text message about an error. + Another error message, this one with a service exception code supplied. + + , line 42 +A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' + +]]> + + + foo.c An error occurred Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it. ]]> + + diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml new file mode 100644 index 0000000000..cecac48414 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml @@ -0,0 +1,4 @@ + + + Plain text message about an error. + diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml new file mode 100644 index 0000000000..75399ff196 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml @@ -0,0 +1,4497 @@ + + + + + OGC:WMS + GeoServer Web Map Service + A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS + + WFS + WMS + GEOSERVER + + + + + Claudius Ptolomaeus + The ancient geographes INC + + Chief geographer + + Work +
+ Alexandria + + + Egypt + + + + claudius.ptolomaeus@gmail.com + + NONE + NONE + + + + + application/vnd.ogc.wms_xml + + + + + + + + + + + + + image/png + application/atom xml + application/atom+xml + application/openlayers + application/pdf + application/rss xml + application/rss+xml + application/vnd.google-earth.kml + application/vnd.google-earth.kml xml + application/vnd.google-earth.kml+xml + application/vnd.google-earth.kmz + application/vnd.google-earth.kmz xml + application/vnd.google-earth.kmz+xml + atom + image/geotiff + image/geotiff8 + image/gif + image/jpeg + image/png8 + image/svg + image/svg xml + image/svg+xml + image/tiff + image/tiff8 + kml + kmz + openlayers + rss + + + + + + + + + + text/plain + text/html + application/vnd.ogc.gml + + + + + + + + + + + + + application/vnd.ogc.wms_xml + + + + + + + + + + image/png + image/jpeg + image/gif + + + + + + + + + + + application/vnd.ogc.se_xml + + + + GeoServer Web Map Service + A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS + EPSG:WGS84(DD) + EPSG:2000 + EPSG:2001 + EPSG:2002 + EPSG:2003 + EPSG:2004 + EPSG:2005 + EPSG:2006 + EPSG:2007 + EPSG:2008 + EPSG:2009 + EPSG:2010 + EPSG:2011 + EPSG:2012 + EPSG:2013 + EPSG:2014 + EPSG:2015 + EPSG:2016 + EPSG:2017 + EPSG:2018 + EPSG:2019 + EPSG:2020 + EPSG:2021 + EPSG:2022 + EPSG:2023 + EPSG:2024 + EPSG:2025 + EPSG:2026 + EPSG:2027 + EPSG:2028 + EPSG:2029 + EPSG:2030 + EPSG:2031 + EPSG:2032 + EPSG:2033 + EPSG:2034 + EPSG:2035 + EPSG:2036 + EPSG:2037 + EPSG:2038 + EPSG:2039 + EPSG:2040 + EPSG:2041 + EPSG:2042 + EPSG:2043 + EPSG:2044 + EPSG:2045 + EPSG:2046 + EPSG:2047 + EPSG:2048 + EPSG:2049 + EPSG:2050 + EPSG:2051 + EPSG:2052 + EPSG:2053 + EPSG:2054 + EPSG:2055 + EPSG:2056 + EPSG:2057 + EPSG:2058 + EPSG:2059 + EPSG:2060 + EPSG:2061 + EPSG:2062 + EPSG:2063 + EPSG:2064 + EPSG:2065 + EPSG:2066 + EPSG:2067 + EPSG:2068 + EPSG:2069 + EPSG:2070 + EPSG:2071 + EPSG:2072 + EPSG:2073 + EPSG:2074 + EPSG:2075 + EPSG:2076 + EPSG:2077 + EPSG:2078 + EPSG:2079 + EPSG:2080 + EPSG:2081 + EPSG:2082 + EPSG:2083 + EPSG:2084 + EPSG:2085 + EPSG:2086 + EPSG:2087 + EPSG:2088 + EPSG:2089 + EPSG:2090 + EPSG:2091 + EPSG:2092 + EPSG:2093 + EPSG:2094 + EPSG:2095 + EPSG:2096 + EPSG:2097 + EPSG:2098 + EPSG:2099 + EPSG:2100 + EPSG:2101 + EPSG:2102 + EPSG:2103 + EPSG:2104 + EPSG:2105 + EPSG:2106 + EPSG:2107 + EPSG:2108 + EPSG:2109 + EPSG:2110 + EPSG:2111 + EPSG:2112 + EPSG:2113 + EPSG:2114 + EPSG:2115 + EPSG:2116 + EPSG:2117 + EPSG:2118 + EPSG:2119 + EPSG:2120 + EPSG:2121 + EPSG:2122 + EPSG:2123 + EPSG:2124 + EPSG:2125 + EPSG:2126 + EPSG:2127 + EPSG:2128 + EPSG:2129 + EPSG:2130 + EPSG:2131 + EPSG:2132 + EPSG:2133 + EPSG:2134 + EPSG:2135 + EPSG:2136 + EPSG:2137 + EPSG:2138 + EPSG:2139 + EPSG:2140 + EPSG:2141 + EPSG:2142 + EPSG:2143 + EPSG:2144 + EPSG:2145 + EPSG:2146 + EPSG:2147 + EPSG:2148 + EPSG:2149 + EPSG:2150 + EPSG:2151 + EPSG:2152 + EPSG:2153 + EPSG:2154 + EPSG:2155 + EPSG:2156 + EPSG:2157 + EPSG:2158 + EPSG:2159 + EPSG:2160 + EPSG:2161 + EPSG:2162 + EPSG:2163 + EPSG:2164 + EPSG:2165 + EPSG:2166 + EPSG:2167 + EPSG:2168 + EPSG:2169 + EPSG:2170 + EPSG:2171 + EPSG:2172 + EPSG:2173 + EPSG:2174 + EPSG:2175 + EPSG:2176 + EPSG:2177 + EPSG:2178 + EPSG:2179 + EPSG:2180 + EPSG:2188 + EPSG:2189 + EPSG:2190 + EPSG:2191 + EPSG:2192 + EPSG:2193 + EPSG:2194 + EPSG:2195 + EPSG:2196 + EPSG:2197 + EPSG:2198 + EPSG:2199 + EPSG:2200 + EPSG:2201 + EPSG:2202 + EPSG:2203 + EPSG:2204 + EPSG:2205 + EPSG:2206 + EPSG:2207 + EPSG:2208 + EPSG:2209 + EPSG:2210 + EPSG:2211 + EPSG:2212 + EPSG:2213 + EPSG:2214 + EPSG:2215 + EPSG:2216 + EPSG:2217 + EPSG:2218 + EPSG:2219 + EPSG:2220 + EPSG:2221 + EPSG:2222 + EPSG:2223 + EPSG:2224 + EPSG:2225 + EPSG:2226 + EPSG:2227 + EPSG:2228 + EPSG:2229 + EPSG:2230 + EPSG:2231 + EPSG:2232 + EPSG:2233 + EPSG:2234 + EPSG:2235 + EPSG:2236 + EPSG:2237 + EPSG:2238 + EPSG:2239 + EPSG:2240 + EPSG:2241 + EPSG:2242 + EPSG:2243 + EPSG:2244 + EPSG:2245 + EPSG:2246 + EPSG:2247 + EPSG:2248 + EPSG:2249 + EPSG:2250 + EPSG:2251 + EPSG:2252 + EPSG:2253 + EPSG:2254 + EPSG:2255 + EPSG:2256 + EPSG:2257 + EPSG:2258 + EPSG:2259 + EPSG:2260 + EPSG:2261 + EPSG:2262 + EPSG:2263 + EPSG:2264 + EPSG:2265 + EPSG:2266 + EPSG:2267 + EPSG:2268 + EPSG:2269 + EPSG:2270 + EPSG:2271 + EPSG:2272 + EPSG:2273 + EPSG:2274 + EPSG:2275 + EPSG:2276 + EPSG:2277 + EPSG:2278 + EPSG:2279 + EPSG:2280 + EPSG:2281 + EPSG:2282 + EPSG:2283 + EPSG:2284 + EPSG:2285 + EPSG:2286 + EPSG:2287 + EPSG:2288 + EPSG:2289 + EPSG:2290 + EPSG:2291 + EPSG:2292 + EPSG:2294 + EPSG:2295 + EPSG:2296 + EPSG:2297 + EPSG:2298 + EPSG:2299 + EPSG:2300 + EPSG:2301 + EPSG:2302 + EPSG:2303 + EPSG:2304 + EPSG:2305 + EPSG:2306 + EPSG:2307 + EPSG:2308 + EPSG:2309 + EPSG:2310 + EPSG:2311 + EPSG:2312 + EPSG:2313 + EPSG:2314 + EPSG:2315 + EPSG:2316 + EPSG:2317 + EPSG:2318 + EPSG:2319 + EPSG:2320 + EPSG:2321 + EPSG:2322 + EPSG:2323 + EPSG:2324 + EPSG:2325 + EPSG:2326 + EPSG:2327 + EPSG:2328 + EPSG:2329 + EPSG:2330 + EPSG:2331 + EPSG:2332 + EPSG:2333 + EPSG:2334 + EPSG:2335 + EPSG:2336 + EPSG:2337 + EPSG:2338 + EPSG:2339 + EPSG:2340 + EPSG:2341 + EPSG:2342 + EPSG:2343 + EPSG:2344 + EPSG:2345 + EPSG:2346 + EPSG:2347 + EPSG:2348 + EPSG:2349 + EPSG:2350 + EPSG:2351 + EPSG:2352 + EPSG:2353 + EPSG:2354 + EPSG:2355 + EPSG:2356 + EPSG:2357 + EPSG:2358 + EPSG:2359 + EPSG:2360 + EPSG:2361 + EPSG:2362 + EPSG:2363 + EPSG:2364 + EPSG:2365 + EPSG:2366 + EPSG:2367 + EPSG:2368 + EPSG:2369 + EPSG:2370 + EPSG:2371 + EPSG:2372 + EPSG:2373 + EPSG:2374 + EPSG:2375 + EPSG:2376 + EPSG:2377 + EPSG:2378 + EPSG:2379 + EPSG:2380 + EPSG:2381 + EPSG:2382 + EPSG:2383 + EPSG:2384 + EPSG:2385 + EPSG:2386 + EPSG:2387 + EPSG:2388 + EPSG:2389 + EPSG:2390 + EPSG:2391 + EPSG:2392 + EPSG:2393 + EPSG:2394 + EPSG:2395 + EPSG:2396 + EPSG:2397 + EPSG:2398 + EPSG:2399 + EPSG:2400 + EPSG:2401 + EPSG:2402 + EPSG:2403 + EPSG:2404 + EPSG:2405 + EPSG:2406 + EPSG:2407 + EPSG:2408 + EPSG:2409 + EPSG:2410 + EPSG:2411 + EPSG:2412 + EPSG:2413 + EPSG:2414 + EPSG:2415 + EPSG:2416 + EPSG:2417 + EPSG:2418 + EPSG:2419 + EPSG:2420 + EPSG:2421 + EPSG:2422 + EPSG:2423 + EPSG:2424 + EPSG:2425 + EPSG:2426 + EPSG:2427 + EPSG:2428 + EPSG:2429 + EPSG:2430 + EPSG:2431 + EPSG:2432 + EPSG:2433 + EPSG:2434 + EPSG:2435 + EPSG:2436 + EPSG:2437 + EPSG:2438 + EPSG:2439 + EPSG:2440 + EPSG:2441 + EPSG:2442 + EPSG:2443 + EPSG:2444 + EPSG:2445 + EPSG:2446 + EPSG:2447 + EPSG:2448 + EPSG:2449 + EPSG:2450 + EPSG:2451 + EPSG:2452 + EPSG:2453 + EPSG:2454 + EPSG:2455 + EPSG:2456 + EPSG:2457 + EPSG:2458 + EPSG:2459 + EPSG:2460 + EPSG:2461 + EPSG:2462 + EPSG:2463 + EPSG:2464 + EPSG:2465 + EPSG:2466 + EPSG:2467 + EPSG:2468 + EPSG:2469 + EPSG:2470 + EPSG:2471 + EPSG:2472 + EPSG:2473 + EPSG:2474 + EPSG:2475 + EPSG:2476 + EPSG:2477 + EPSG:2478 + EPSG:2479 + EPSG:2480 + EPSG:2481 + EPSG:2482 + EPSG:2483 + EPSG:2484 + EPSG:2485 + EPSG:2486 + EPSG:2487 + EPSG:2488 + EPSG:2489 + EPSG:2490 + EPSG:2491 + EPSG:2492 + EPSG:2493 + EPSG:2494 + EPSG:2495 + EPSG:2496 + EPSG:2497 + EPSG:2498 + EPSG:2499 + EPSG:2500 + EPSG:2501 + EPSG:2502 + EPSG:2503 + EPSG:2504 + EPSG:2505 + EPSG:2506 + EPSG:2507 + EPSG:2508 + EPSG:2509 + EPSG:2510 + EPSG:2511 + EPSG:2512 + EPSG:2513 + EPSG:2514 + EPSG:2515 + EPSG:2516 + EPSG:2517 + EPSG:2518 + EPSG:2519 + EPSG:2520 + EPSG:2521 + EPSG:2522 + EPSG:2523 + EPSG:2524 + EPSG:2525 + EPSG:2526 + EPSG:2527 + EPSG:2528 + EPSG:2529 + EPSG:2530 + EPSG:2531 + EPSG:2532 + EPSG:2533 + EPSG:2534 + EPSG:2535 + EPSG:2536 + EPSG:2537 + EPSG:2538 + EPSG:2539 + EPSG:2540 + EPSG:2541 + EPSG:2542 + EPSG:2543 + EPSG:2544 + EPSG:2545 + EPSG:2546 + EPSG:2547 + EPSG:2548 + EPSG:2549 + EPSG:2550 + EPSG:2551 + EPSG:2552 + EPSG:2553 + EPSG:2554 + EPSG:2555 + EPSG:2556 + EPSG:2557 + EPSG:2558 + EPSG:2559 + EPSG:2560 + EPSG:2561 + EPSG:2562 + EPSG:2563 + EPSG:2564 + EPSG:2565 + EPSG:2566 + EPSG:2567 + EPSG:2568 + EPSG:2569 + EPSG:2570 + EPSG:2571 + EPSG:2572 + EPSG:2573 + EPSG:2574 + EPSG:2575 + EPSG:2576 + EPSG:2577 + EPSG:2578 + EPSG:2579 + EPSG:2580 + EPSG:2581 + EPSG:2582 + EPSG:2583 + EPSG:2584 + EPSG:2585 + EPSG:2586 + EPSG:2587 + EPSG:2588 + EPSG:2589 + EPSG:2590 + EPSG:2591 + EPSG:2592 + EPSG:2593 + EPSG:2594 + EPSG:2595 + EPSG:2596 + EPSG:2597 + EPSG:2598 + EPSG:2599 + EPSG:2600 + EPSG:2601 + EPSG:2602 + EPSG:2603 + EPSG:2604 + EPSG:2605 + EPSG:2606 + EPSG:2607 + EPSG:2608 + EPSG:2609 + EPSG:2610 + EPSG:2611 + EPSG:2612 + EPSG:2613 + EPSG:2614 + EPSG:2615 + EPSG:2616 + EPSG:2617 + EPSG:2618 + EPSG:2619 + EPSG:2620 + EPSG:2621 + EPSG:2622 + EPSG:2623 + EPSG:2624 + EPSG:2625 + EPSG:2626 + EPSG:2627 + EPSG:2628 + EPSG:2629 + EPSG:2630 + EPSG:2631 + EPSG:2632 + EPSG:2633 + EPSG:2634 + EPSG:2635 + EPSG:2636 + EPSG:2637 + EPSG:2638 + EPSG:2639 + EPSG:2640 + EPSG:2641 + EPSG:2642 + EPSG:2643 + EPSG:2644 + EPSG:2645 + EPSG:2646 + EPSG:2647 + EPSG:2648 + EPSG:2649 + EPSG:2650 + EPSG:2651 + EPSG:2652 + EPSG:2653 + EPSG:2654 + EPSG:2655 + EPSG:2656 + EPSG:2657 + EPSG:2658 + EPSG:2659 + EPSG:2660 + EPSG:2661 + EPSG:2662 + EPSG:2663 + EPSG:2664 + EPSG:2665 + EPSG:2666 + EPSG:2667 + EPSG:2668 + EPSG:2669 + EPSG:2670 + EPSG:2671 + EPSG:2672 + EPSG:2673 + EPSG:2674 + EPSG:2675 + EPSG:2676 + EPSG:2677 + EPSG:2678 + EPSG:2679 + EPSG:2680 + EPSG:2681 + EPSG:2682 + EPSG:2683 + EPSG:2684 + EPSG:2685 + EPSG:2686 + EPSG:2687 + EPSG:2688 + EPSG:2689 + EPSG:2690 + EPSG:2691 + EPSG:2692 + EPSG:2693 + EPSG:2694 + EPSG:2695 + EPSG:2696 + EPSG:2697 + EPSG:2698 + EPSG:2699 + EPSG:2700 + EPSG:2701 + EPSG:2702 + EPSG:2703 + EPSG:2704 + EPSG:2705 + EPSG:2706 + EPSG:2707 + EPSG:2708 + EPSG:2709 + EPSG:2710 + EPSG:2711 + EPSG:2712 + EPSG:2713 + EPSG:2714 + EPSG:2715 + EPSG:2716 + EPSG:2717 + EPSG:2718 + EPSG:2719 + EPSG:2720 + EPSG:2721 + EPSG:2722 + EPSG:2723 + EPSG:2724 + EPSG:2725 + EPSG:2726 + EPSG:2727 + EPSG:2728 + EPSG:2729 + EPSG:2730 + EPSG:2731 + EPSG:2732 + EPSG:2733 + EPSG:2734 + EPSG:2735 + EPSG:2736 + EPSG:2737 + EPSG:2738 + EPSG:2739 + EPSG:2740 + EPSG:2741 + EPSG:2742 + EPSG:2743 + EPSG:2744 + EPSG:2745 + EPSG:2746 + EPSG:2747 + EPSG:2748 + EPSG:2749 + EPSG:2750 + EPSG:2751 + EPSG:2752 + EPSG:2753 + EPSG:2754 + EPSG:2755 + EPSG:2756 + EPSG:2757 + EPSG:2758 + EPSG:2759 + EPSG:2760 + EPSG:2761 + EPSG:2762 + EPSG:2763 + EPSG:2764 + EPSG:2765 + EPSG:2766 + EPSG:2767 + EPSG:2768 + EPSG:2769 + EPSG:2770 + EPSG:2771 + EPSG:2772 + EPSG:2773 + EPSG:2774 + EPSG:2775 + EPSG:2776 + EPSG:2777 + EPSG:2778 + EPSG:2779 + EPSG:2780 + EPSG:2781 + EPSG:2782 + EPSG:2783 + EPSG:2784 + EPSG:2785 + EPSG:2786 + EPSG:2787 + EPSG:2788 + EPSG:2789 + EPSG:2790 + EPSG:2791 + EPSG:2792 + EPSG:2793 + EPSG:2794 + EPSG:2795 + EPSG:2796 + EPSG:2797 + EPSG:2798 + EPSG:2799 + EPSG:2800 + EPSG:2801 + EPSG:2802 + EPSG:2803 + EPSG:2804 + EPSG:2805 + EPSG:2806 + EPSG:2807 + EPSG:2808 + EPSG:2809 + EPSG:2810 + EPSG:2811 + EPSG:2812 + EPSG:2813 + EPSG:2814 + EPSG:2815 + EPSG:2816 + EPSG:2817 + EPSG:2818 + EPSG:2819 + EPSG:2820 + EPSG:2821 + EPSG:2822 + EPSG:2823 + EPSG:2824 + EPSG:2825 + EPSG:2826 + EPSG:2827 + EPSG:2828 + EPSG:2829 + EPSG:2830 + EPSG:2831 + EPSG:2832 + EPSG:2833 + EPSG:2834 + EPSG:2835 + EPSG:2836 + EPSG:2837 + EPSG:2838 + EPSG:2839 + EPSG:2840 + EPSG:2841 + EPSG:2842 + EPSG:2843 + EPSG:2844 + EPSG:2845 + EPSG:2846 + EPSG:2847 + EPSG:2848 + EPSG:2849 + EPSG:2850 + EPSG:2851 + EPSG:2852 + EPSG:2853 + EPSG:2854 + EPSG:2855 + EPSG:2856 + EPSG:2857 + EPSG:2858 + EPSG:2859 + EPSG:2860 + EPSG:2861 + EPSG:2862 + EPSG:2863 + EPSG:2864 + EPSG:2865 + EPSG:2866 + EPSG:2867 + EPSG:2868 + EPSG:2869 + EPSG:2870 + EPSG:2871 + EPSG:2872 + EPSG:2873 + EPSG:2874 + EPSG:2875 + EPSG:2876 + EPSG:2877 + EPSG:2878 + EPSG:2879 + EPSG:2880 + EPSG:2881 + EPSG:2882 + EPSG:2883 + EPSG:2884 + EPSG:2885 + EPSG:2886 + EPSG:2887 + EPSG:2888 + EPSG:2889 + EPSG:2890 + EPSG:2891 + EPSG:2892 + EPSG:2893 + EPSG:2894 + EPSG:2895 + EPSG:2896 + EPSG:2897 + EPSG:2898 + EPSG:2899 + EPSG:2900 + EPSG:2901 + EPSG:2902 + EPSG:2903 + EPSG:2904 + EPSG:2905 + EPSG:2906 + EPSG:2907 + EPSG:2908 + EPSG:2909 + EPSG:2910 + EPSG:2911 + EPSG:2912 + EPSG:2913 + EPSG:2914 + EPSG:2915 + EPSG:2916 + EPSG:2917 + EPSG:2918 + EPSG:2919 + EPSG:2920 + EPSG:2921 + EPSG:2922 + EPSG:2923 + EPSG:2924 + EPSG:2925 + EPSG:2926 + EPSG:2927 + EPSG:2928 + EPSG:2929 + EPSG:2930 + EPSG:2931 + EPSG:2932 + EPSG:2933 + EPSG:2934 + EPSG:2935 + EPSG:2936 + EPSG:2937 + EPSG:2938 + EPSG:2939 + EPSG:2940 + EPSG:2941 + EPSG:2942 + EPSG:2943 + EPSG:2944 + EPSG:2945 + EPSG:2946 + EPSG:2947 + EPSG:2948 + EPSG:2949 + EPSG:2950 + EPSG:2951 + EPSG:2952 + EPSG:2953 + EPSG:2954 + EPSG:2955 + EPSG:2956 + EPSG:2957 + EPSG:2958 + EPSG:2959 + EPSG:2960 + EPSG:2961 + EPSG:2962 + EPSG:2963 + EPSG:2964 + EPSG:2965 + EPSG:2966 + EPSG:2967 + EPSG:2968 + EPSG:2969 + EPSG:2970 + EPSG:2971 + EPSG:2972 + EPSG:2973 + EPSG:2975 + EPSG:2976 + EPSG:2977 + EPSG:2978 + EPSG:2979 + EPSG:2980 + EPSG:2981 + EPSG:2982 + EPSG:2983 + EPSG:2984 + EPSG:2985 + EPSG:2986 + EPSG:2987 + EPSG:2988 + EPSG:2989 + EPSG:2990 + EPSG:2991 + EPSG:2992 + EPSG:2993 + EPSG:2994 + EPSG:2995 + EPSG:2996 + EPSG:2997 + EPSG:2998 + EPSG:2999 + EPSG:3000 + EPSG:3001 + EPSG:3002 + EPSG:3003 + EPSG:3004 + EPSG:3005 + EPSG:3006 + EPSG:3007 + EPSG:3008 + EPSG:3009 + EPSG:3010 + EPSG:3011 + EPSG:3012 + EPSG:3013 + EPSG:3014 + EPSG:3015 + EPSG:3016 + EPSG:3017 + EPSG:3018 + EPSG:3019 + EPSG:3020 + EPSG:3021 + EPSG:3022 + EPSG:3023 + EPSG:3024 + EPSG:3025 + EPSG:3026 + EPSG:3027 + EPSG:3028 + EPSG:3029 + EPSG:3030 + EPSG:3031 + EPSG:3032 + EPSG:3033 + EPSG:3034 + EPSG:3035 + EPSG:3036 + EPSG:3037 + EPSG:3038 + EPSG:3039 + EPSG:3040 + EPSG:3041 + EPSG:3042 + EPSG:3043 + EPSG:3044 + EPSG:3045 + EPSG:3046 + EPSG:3047 + EPSG:3048 + EPSG:3049 + EPSG:3050 + EPSG:3051 + EPSG:3052 + EPSG:3053 + EPSG:3054 + EPSG:3055 + EPSG:3056 + EPSG:3057 + EPSG:3058 + EPSG:3059 + EPSG:3060 + EPSG:3061 + EPSG:3062 + EPSG:3063 + EPSG:3064 + EPSG:3065 + EPSG:3066 + EPSG:3067 + EPSG:3068 + EPSG:3069 + EPSG:3070 + EPSG:3071 + EPSG:3072 + EPSG:3073 + EPSG:3074 + EPSG:3075 + EPSG:3076 + EPSG:3077 + EPSG:3078 + EPSG:3079 + EPSG:3080 + EPSG:3081 + EPSG:3082 + EPSG:3083 + EPSG:3084 + EPSG:3085 + EPSG:3086 + EPSG:3087 + EPSG:3088 + EPSG:3089 + EPSG:3090 + EPSG:3091 + EPSG:3092 + EPSG:3093 + EPSG:3094 + EPSG:3095 + EPSG:3096 + EPSG:3097 + EPSG:3098 + EPSG:3099 + EPSG:3100 + EPSG:3101 + EPSG:3102 + EPSG:3103 + EPSG:3104 + EPSG:3105 + EPSG:3106 + EPSG:3107 + EPSG:3108 + EPSG:3109 + EPSG:3110 + EPSG:3111 + EPSG:3112 + EPSG:3113 + EPSG:3114 + EPSG:3115 + EPSG:3116 + EPSG:3117 + EPSG:3118 + EPSG:3119 + EPSG:3120 + EPSG:3121 + EPSG:3122 + EPSG:3123 + EPSG:3124 + EPSG:3125 + EPSG:3126 + EPSG:3127 + EPSG:3128 + EPSG:3129 + EPSG:3130 + EPSG:3131 + EPSG:3132 + EPSG:3133 + EPSG:3134 + EPSG:3135 + EPSG:3136 + EPSG:3137 + EPSG:3138 + EPSG:3139 + EPSG:3140 + EPSG:3141 + EPSG:3142 + EPSG:3143 + EPSG:3144 + EPSG:3145 + EPSG:3146 + EPSG:3147 + EPSG:3148 + EPSG:3149 + EPSG:3150 + EPSG:3151 + EPSG:3152 + EPSG:3153 + EPSG:3154 + EPSG:3155 + EPSG:3156 + EPSG:3157 + EPSG:3158 + EPSG:3159 + EPSG:3160 + EPSG:3161 + EPSG:3162 + EPSG:3163 + EPSG:3164 + EPSG:3165 + EPSG:3166 + EPSG:3167 + EPSG:3168 + EPSG:3169 + EPSG:3170 + EPSG:3171 + EPSG:3172 + EPSG:3173 + EPSG:3174 + EPSG:3175 + EPSG:3176 + EPSG:3177 + EPSG:3178 + EPSG:3179 + EPSG:3180 + EPSG:3181 + EPSG:3182 + EPSG:3183 + EPSG:3184 + EPSG:3185 + EPSG:3186 + EPSG:3187 + EPSG:3188 + EPSG:3189 + EPSG:3190 + EPSG:3191 + EPSG:3192 + EPSG:3193 + EPSG:3194 + EPSG:3195 + EPSG:3196 + EPSG:3197 + EPSG:3198 + EPSG:3199 + EPSG:3200 + EPSG:3201 + EPSG:3202 + EPSG:3203 + EPSG:3204 + EPSG:3205 + EPSG:3206 + EPSG:3207 + EPSG:3208 + EPSG:3209 + EPSG:3210 + EPSG:3211 + EPSG:3212 + EPSG:3213 + EPSG:3214 + EPSG:3215 + EPSG:3216 + EPSG:3217 + EPSG:3218 + EPSG:3219 + EPSG:3220 + EPSG:3221 + EPSG:3222 + EPSG:3223 + EPSG:3224 + EPSG:3225 + EPSG:3226 + EPSG:3227 + EPSG:3228 + EPSG:3229 + EPSG:3230 + EPSG:3231 + EPSG:3232 + EPSG:3233 + EPSG:3234 + EPSG:3235 + EPSG:3236 + EPSG:3237 + EPSG:3238 + EPSG:3239 + EPSG:3240 + EPSG:3241 + EPSG:3242 + EPSG:3243 + EPSG:3244 + EPSG:3245 + EPSG:3246 + EPSG:3247 + EPSG:3248 + EPSG:3249 + EPSG:3250 + EPSG:3251 + EPSG:3252 + EPSG:3253 + EPSG:3254 + EPSG:3255 + EPSG:3256 + EPSG:3257 + EPSG:3258 + EPSG:3259 + EPSG:3260 + EPSG:3261 + EPSG:3262 + EPSG:3263 + EPSG:3264 + EPSG:3265 + EPSG:3266 + EPSG:3267 + EPSG:3268 + EPSG:3269 + EPSG:3270 + EPSG:3271 + EPSG:3272 + EPSG:3273 + EPSG:3274 + EPSG:3275 + EPSG:3276 + EPSG:3277 + EPSG:3278 + EPSG:3279 + EPSG:3280 + EPSG:3281 + EPSG:3282 + EPSG:3283 + EPSG:3284 + EPSG:3285 + EPSG:3286 + EPSG:3287 + EPSG:3288 + EPSG:3289 + EPSG:3290 + EPSG:3291 + EPSG:3292 + EPSG:3293 + EPSG:3294 + EPSG:3295 + EPSG:3296 + EPSG:3297 + EPSG:3298 + EPSG:3299 + EPSG:3300 + EPSG:3301 + EPSG:3302 + EPSG:3303 + EPSG:3304 + EPSG:3305 + EPSG:3306 + EPSG:3307 + EPSG:3308 + EPSG:3309 + EPSG:3310 + EPSG:3311 + EPSG:3312 + EPSG:3313 + EPSG:3314 + EPSG:3315 + EPSG:3316 + EPSG:3317 + EPSG:3318 + EPSG:3319 + EPSG:3320 + EPSG:3321 + EPSG:3322 + EPSG:3323 + EPSG:3324 + EPSG:3325 + EPSG:3326 + EPSG:3327 + EPSG:3328 + EPSG:3329 + EPSG:3330 + EPSG:3331 + EPSG:3332 + EPSG:3333 + EPSG:3334 + EPSG:3335 + EPSG:3336 + EPSG:3337 + EPSG:3338 + EPSG:3339 + EPSG:3340 + EPSG:3341 + EPSG:3342 + EPSG:3343 + EPSG:3344 + EPSG:3345 + EPSG:3346 + EPSG:3347 + EPSG:3348 + EPSG:3349 + EPSG:3350 + EPSG:3351 + EPSG:3352 + EPSG:3353 + EPSG:3354 + EPSG:3355 + EPSG:3356 + EPSG:3357 + EPSG:3358 + EPSG:3359 + EPSG:3360 + EPSG:3361 + EPSG:3362 + EPSG:3363 + EPSG:3364 + EPSG:3365 + EPSG:3366 + EPSG:3367 + EPSG:3368 + EPSG:3369 + EPSG:3370 + EPSG:3371 + EPSG:3372 + EPSG:3373 + EPSG:3374 + EPSG:3375 + EPSG:3376 + EPSG:3377 + EPSG:3378 + EPSG:3379 + EPSG:3380 + EPSG:3381 + EPSG:3382 + EPSG:3383 + EPSG:3384 + EPSG:3385 + EPSG:3386 + EPSG:3387 + EPSG:3388 + EPSG:3389 + EPSG:3390 + EPSG:3391 + EPSG:3392 + EPSG:3393 + EPSG:3394 + EPSG:3395 + EPSG:3396 + EPSG:3397 + EPSG:3398 + EPSG:3399 + EPSG:3400 + EPSG:3401 + EPSG:3402 + EPSG:3403 + EPSG:3404 + EPSG:3405 + EPSG:3406 + EPSG:3407 + EPSG:3408 + EPSG:3409 + EPSG:3410 + EPSG:3411 + EPSG:3412 + EPSG:3413 + EPSG:3414 + EPSG:3415 + EPSG:3416 + EPSG:3417 + EPSG:3418 + EPSG:3419 + EPSG:3420 + EPSG:3421 + EPSG:3422 + EPSG:3423 + EPSG:3424 + EPSG:3425 + EPSG:3426 + EPSG:3427 + EPSG:3428 + EPSG:3429 + EPSG:3430 + EPSG:3431 + EPSG:3432 + EPSG:3433 + EPSG:3434 + EPSG:3435 + EPSG:3436 + EPSG:3437 + EPSG:3438 + EPSG:3439 + EPSG:3440 + EPSG:3441 + EPSG:3442 + EPSG:3443 + EPSG:3444 + EPSG:3445 + EPSG:3446 + EPSG:3447 + EPSG:3448 + EPSG:3449 + EPSG:3450 + EPSG:3451 + EPSG:3452 + EPSG:3453 + EPSG:3454 + EPSG:3455 + EPSG:3456 + EPSG:3457 + EPSG:3458 + EPSG:3459 + EPSG:3460 + EPSG:3461 + EPSG:3462 + EPSG:3463 + EPSG:3464 + EPSG:3560 + EPSG:3561 + EPSG:3562 + EPSG:3563 + EPSG:3564 + EPSG:3565 + EPSG:3566 + EPSG:3567 + EPSG:3568 + EPSG:3569 + EPSG:3570 + EPSG:3571 + EPSG:3572 + EPSG:3573 + EPSG:3574 + EPSG:3575 + EPSG:3576 + EPSG:3577 + EPSG:3920 + EPSG:3991 + EPSG:3992 + EPSG:3993 + EPSG:4001 + EPSG:4002 + EPSG:4003 + EPSG:4004 + EPSG:4005 + EPSG:4006 + EPSG:4007 + EPSG:4008 + EPSG:4009 + EPSG:4010 + EPSG:4011 + EPSG:4012 + EPSG:4013 + EPSG:4014 + EPSG:4015 + EPSG:4016 + EPSG:4018 + EPSG:4019 + EPSG:4020 + EPSG:4021 + EPSG:4022 + EPSG:4024 + EPSG:4025 + EPSG:4027 + EPSG:4028 + EPSG:4029 + EPSG:4030 + EPSG:4031 + EPSG:4032 + EPSG:4033 + EPSG:4034 + EPSG:4035 + EPSG:4036 + EPSG:4041 + EPSG:4042 + EPSG:4043 + EPSG:4044 + EPSG:4045 + EPSG:4047 + EPSG:4052 + EPSG:4053 + EPSG:4054 + EPSG:4120 + EPSG:4121 + EPSG:4122 + EPSG:4123 + EPSG:4124 + EPSG:4125 + EPSG:4126 + EPSG:4127 + EPSG:4128 + EPSG:4129 + EPSG:4130 + EPSG:4131 + EPSG:4132 + EPSG:4133 + EPSG:4134 + EPSG:4135 + EPSG:4136 + EPSG:4137 + EPSG:4138 + EPSG:4139 + EPSG:4140 + EPSG:4141 + EPSG:4142 + EPSG:4143 + EPSG:4144 + EPSG:4145 + EPSG:4146 + EPSG:4147 + EPSG:4148 + EPSG:4149 + EPSG:4150 + EPSG:4151 + EPSG:4152 + EPSG:4153 + EPSG:4154 + EPSG:4155 + EPSG:4156 + EPSG:4157 + EPSG:4158 + EPSG:4159 + EPSG:4160 + EPSG:4161 + EPSG:4162 + EPSG:4163 + EPSG:4164 + EPSG:4165 + EPSG:4166 + EPSG:4167 + EPSG:4168 + EPSG:4169 + EPSG:4170 + EPSG:4171 + EPSG:4172 + EPSG:4173 + EPSG:4174 + EPSG:4175 + EPSG:4176 + EPSG:4178 + EPSG:4179 + EPSG:4180 + EPSG:4181 + EPSG:4182 + EPSG:4183 + EPSG:4184 + EPSG:4185 + EPSG:4188 + EPSG:4189 + EPSG:4190 + EPSG:4191 + EPSG:4192 + EPSG:4193 + EPSG:4194 + EPSG:4195 + EPSG:4196 + EPSG:4197 + EPSG:4198 + EPSG:4199 + EPSG:4200 + EPSG:4201 + EPSG:4202 + EPSG:4203 + EPSG:4204 + EPSG:4205 + EPSG:4206 + EPSG:4207 + EPSG:4208 + EPSG:4209 + EPSG:4210 + EPSG:4211 + EPSG:4212 + EPSG:4213 + EPSG:4214 + EPSG:4215 + EPSG:4216 + EPSG:4218 + EPSG:4219 + EPSG:4220 + EPSG:4221 + EPSG:4222 + EPSG:4223 + EPSG:4224 + EPSG:4225 + EPSG:4226 + EPSG:4227 + EPSG:4228 + EPSG:4229 + EPSG:4230 + EPSG:4231 + EPSG:4232 + EPSG:4233 + EPSG:4234 + EPSG:4235 + EPSG:4236 + EPSG:4237 + EPSG:4238 + EPSG:4239 + EPSG:4240 + EPSG:4241 + EPSG:4242 + EPSG:4243 + EPSG:4244 + EPSG:4245 + EPSG:4246 + EPSG:4247 + EPSG:4248 + EPSG:4249 + EPSG:4250 + EPSG:4251 + EPSG:4252 + EPSG:4253 + EPSG:4254 + EPSG:4255 + EPSG:4256 + EPSG:4257 + EPSG:4258 + EPSG:4259 + EPSG:4260 + EPSG:4261 + EPSG:4262 + EPSG:4263 + EPSG:4264 + EPSG:4265 + EPSG:4266 + EPSG:4267 + EPSG:4268 + EPSG:4269 + EPSG:4270 + EPSG:4271 + EPSG:4272 + EPSG:4273 + EPSG:4274 + EPSG:4275 + EPSG:4276 + EPSG:4277 + EPSG:4278 + EPSG:4279 + EPSG:4280 + EPSG:4281 + EPSG:4282 + EPSG:4283 + EPSG:4284 + EPSG:4285 + EPSG:4286 + EPSG:4287 + EPSG:4288 + EPSG:4289 + EPSG:4291 + EPSG:4292 + EPSG:4293 + EPSG:4294 + EPSG:4295 + EPSG:4296 + EPSG:4297 + EPSG:4298 + EPSG:4299 + EPSG:4300 + EPSG:4301 + EPSG:4302 + EPSG:4303 + EPSG:4304 + EPSG:4306 + EPSG:4307 + EPSG:4308 + EPSG:4309 + EPSG:4310 + EPSG:4311 + EPSG:4312 + EPSG:4313 + EPSG:4314 + EPSG:4315 + EPSG:4316 + EPSG:4317 + EPSG:4318 + EPSG:4319 + EPSG:4322 + EPSG:4324 + EPSG:4326 + EPSG:4327 + EPSG:4328 + EPSG:4329 + EPSG:4330 + EPSG:4331 + EPSG:4332 + EPSG:4333 + EPSG:4334 + EPSG:4335 + EPSG:4336 + EPSG:4337 + EPSG:4338 + EPSG:4339 + EPSG:4340 + EPSG:4341 + EPSG:4342 + EPSG:4343 + EPSG:4344 + EPSG:4345 + EPSG:4346 + EPSG:4347 + EPSG:4348 + EPSG:4349 + EPSG:4350 + EPSG:4351 + EPSG:4352 + EPSG:4353 + EPSG:4354 + EPSG:4355 + EPSG:4356 + EPSG:4357 + EPSG:4358 + EPSG:4359 + EPSG:4360 + EPSG:4361 + EPSG:4362 + EPSG:4363 + EPSG:4364 + EPSG:4365 + EPSG:4366 + EPSG:4367 + EPSG:4368 + EPSG:4369 + EPSG:4370 + EPSG:4371 + EPSG:4372 + EPSG:4373 + EPSG:4374 + EPSG:4375 + EPSG:4376 + EPSG:4377 + EPSG:4378 + EPSG:4379 + EPSG:4380 + EPSG:4381 + EPSG:4382 + EPSG:4383 + EPSG:4384 + EPSG:4385 + EPSG:4386 + EPSG:4387 + EPSG:4388 + EPSG:4389 + EPSG:4600 + EPSG:4601 + EPSG:4602 + EPSG:4603 + EPSG:4604 + EPSG:4605 + EPSG:4606 + EPSG:4607 + EPSG:4608 + EPSG:4609 + EPSG:4610 + EPSG:4611 + EPSG:4612 + EPSG:4613 + EPSG:4614 + EPSG:4615 + EPSG:4616 + EPSG:4617 + EPSG:4618 + EPSG:4619 + EPSG:4620 + EPSG:4621 + EPSG:4622 + EPSG:4623 + EPSG:4624 + EPSG:4625 + EPSG:4626 + EPSG:4627 + EPSG:4628 + EPSG:4629 + EPSG:4630 + EPSG:4631 + EPSG:4632 + EPSG:4633 + EPSG:4634 + EPSG:4635 + EPSG:4636 + EPSG:4637 + EPSG:4638 + EPSG:4639 + EPSG:4640 + EPSG:4641 + EPSG:4642 + EPSG:4643 + EPSG:4644 + EPSG:4645 + EPSG:4646 + EPSG:4657 + EPSG:4658 + EPSG:4659 + EPSG:4660 + EPSG:4661 + EPSG:4662 + EPSG:4663 + EPSG:4664 + EPSG:4665 + EPSG:4666 + EPSG:4667 + EPSG:4668 + EPSG:4669 + EPSG:4670 + EPSG:4671 + EPSG:4672 + EPSG:4673 + EPSG:4674 + EPSG:4675 + EPSG:4676 + EPSG:4677 + EPSG:4678 + EPSG:4679 + EPSG:4680 + EPSG:4681 + EPSG:4682 + EPSG:4683 + EPSG:4684 + EPSG:4685 + EPSG:4686 + EPSG:4687 + EPSG:4688 + EPSG:4689 + EPSG:4690 + EPSG:4691 + EPSG:4692 + EPSG:4693 + EPSG:4694 + EPSG:4695 + EPSG:4696 + EPSG:4697 + EPSG:4698 + EPSG:4699 + EPSG:4700 + EPSG:4701 + EPSG:4702 + EPSG:4703 + EPSG:4704 + EPSG:4705 + EPSG:4706 + EPSG:4707 + EPSG:4708 + EPSG:4709 + EPSG:4710 + EPSG:4711 + EPSG:4712 + EPSG:4713 + EPSG:4714 + EPSG:4715 + EPSG:4716 + EPSG:4717 + EPSG:4718 + EPSG:4719 + EPSG:4720 + EPSG:4721 + EPSG:4722 + EPSG:4723 + EPSG:4724 + EPSG:4725 + EPSG:4726 + EPSG:4727 + EPSG:4728 + EPSG:4729 + EPSG:4730 + EPSG:4731 + EPSG:4732 + EPSG:4733 + EPSG:4734 + EPSG:4735 + EPSG:4736 + EPSG:4737 + EPSG:4738 + EPSG:4739 + EPSG:4740 + EPSG:4741 + EPSG:4742 + EPSG:4743 + EPSG:4744 + EPSG:4745 + EPSG:4746 + EPSG:4747 + EPSG:4748 + EPSG:4749 + EPSG:4750 + EPSG:4751 + EPSG:4752 + EPSG:4753 + EPSG:4754 + EPSG:4755 + EPSG:4756 + EPSG:4757 + EPSG:4758 + EPSG:4801 + EPSG:4802 + EPSG:4803 + EPSG:4804 + EPSG:4805 + EPSG:4806 + EPSG:4807 + EPSG:4808 + EPSG:4809 + EPSG:4810 + EPSG:4811 + EPSG:4813 + EPSG:4814 + EPSG:4815 + EPSG:4816 + EPSG:4817 + EPSG:4818 + EPSG:4819 + EPSG:4820 + EPSG:4821 + EPSG:4894 + EPSG:4895 + EPSG:4896 + EPSG:4897 + EPSG:4898 + EPSG:4899 + EPSG:4900 + EPSG:4901 + EPSG:4902 + EPSG:4903 + EPSG:4904 + EPSG:4906 + EPSG:4907 + EPSG:4908 + EPSG:4909 + EPSG:4910 + EPSG:4911 + EPSG:4912 + EPSG:4913 + EPSG:4914 + EPSG:4915 + EPSG:4916 + EPSG:4917 + EPSG:4918 + EPSG:4919 + EPSG:4920 + EPSG:4921 + EPSG:4922 + EPSG:4923 + EPSG:4924 + EPSG:4925 + EPSG:4926 + EPSG:4927 + EPSG:4928 + EPSG:4929 + EPSG:4930 + EPSG:4931 + EPSG:4932 + EPSG:4933 + EPSG:4934 + EPSG:4935 + EPSG:4936 + EPSG:4937 + EPSG:4938 + EPSG:4939 + EPSG:4940 + EPSG:4941 + EPSG:4942 + EPSG:4943 + EPSG:4944 + EPSG:4945 + EPSG:4946 + EPSG:4947 + EPSG:4948 + EPSG:4949 + EPSG:4950 + EPSG:4951 + EPSG:4952 + EPSG:4953 + EPSG:4954 + EPSG:4955 + EPSG:4956 + EPSG:4957 + EPSG:4958 + EPSG:4959 + EPSG:4960 + EPSG:4961 + EPSG:4962 + EPSG:4963 + EPSG:4964 + EPSG:4965 + EPSG:4966 + EPSG:4967 + EPSG:4968 + EPSG:4969 + EPSG:4970 + EPSG:4971 + EPSG:4972 + EPSG:4973 + EPSG:4974 + EPSG:4975 + EPSG:4976 + EPSG:4977 + EPSG:4978 + EPSG:4979 + EPSG:4980 + EPSG:4981 + EPSG:4982 + EPSG:4983 + EPSG:4984 + EPSG:4985 + EPSG:4986 + EPSG:4987 + EPSG:4988 + EPSG:4989 + EPSG:4990 + EPSG:4991 + EPSG:4992 + EPSG:4993 + EPSG:4994 + EPSG:4995 + EPSG:4996 + EPSG:4997 + EPSG:4998 + EPSG:4999 + EPSG:5600 + EPSG:5601 + EPSG:5602 + EPSG:5603 + EPSG:5604 + EPSG:5605 + EPSG:5606 + EPSG:5607 + EPSG:5608 + EPSG:5609 + EPSG:5701 + EPSG:5702 + EPSG:5703 + EPSG:5704 + EPSG:5705 + EPSG:5706 + EPSG:5709 + EPSG:5710 + EPSG:5711 + EPSG:5712 + EPSG:5713 + EPSG:5714 + EPSG:5715 + EPSG:5716 + EPSG:5717 + EPSG:5718 + EPSG:5719 + EPSG:5720 + EPSG:5721 + EPSG:5722 + EPSG:5723 + EPSG:5724 + EPSG:5725 + EPSG:5726 + EPSG:5727 + EPSG:5728 + EPSG:5729 + EPSG:5730 + EPSG:5731 + EPSG:5732 + EPSG:5733 + EPSG:5734 + EPSG:5735 + EPSG:5736 + EPSG:5737 + EPSG:5738 + EPSG:5739 + EPSG:5740 + EPSG:5741 + EPSG:5742 + EPSG:5743 + EPSG:5744 + EPSG:5745 + EPSG:5746 + EPSG:5747 + EPSG:5748 + EPSG:5749 + EPSG:5750 + EPSG:5751 + EPSG:5752 + EPSG:5753 + EPSG:5754 + EPSG:5755 + EPSG:5756 + EPSG:5757 + EPSG:5758 + EPSG:5759 + EPSG:5760 + EPSG:5761 + EPSG:5762 + EPSG:5763 + EPSG:5764 + EPSG:5765 + EPSG:5766 + EPSG:5767 + EPSG:5768 + EPSG:5769 + EPSG:5770 + EPSG:5771 + EPSG:5772 + EPSG:5773 + EPSG:5774 + EPSG:5775 + EPSG:5776 + EPSG:5777 + EPSG:5778 + EPSG:5779 + EPSG:5780 + EPSG:5781 + EPSG:5782 + EPSG:5783 + EPSG:5784 + EPSG:5785 + EPSG:5786 + EPSG:5787 + EPSG:5788 + EPSG:5789 + EPSG:5790 + EPSG:5791 + EPSG:5792 + EPSG:5793 + EPSG:5794 + EPSG:5795 + EPSG:5796 + EPSG:5797 + EPSG:5798 + EPSG:5799 + EPSG:5800 + EPSG:5801 + EPSG:5802 + EPSG:5803 + EPSG:5804 + EPSG:5805 + EPSG:5806 + EPSG:5807 + EPSG:5808 + EPSG:5809 + EPSG:5810 + EPSG:5811 + EPSG:5812 + EPSG:5813 + EPSG:5814 + EPSG:5815 + EPSG:5816 + EPSG:5817 + EPSG:5818 + EPSG:7400 + EPSG:7401 + EPSG:7402 + EPSG:7403 + EPSG:7404 + EPSG:7405 + EPSG:7406 + EPSG:7407 + EPSG:7408 + EPSG:7409 + EPSG:7410 + EPSG:7411 + EPSG:7412 + EPSG:7413 + EPSG:7414 + EPSG:7415 + EPSG:7416 + EPSG:7417 + EPSG:7418 + EPSG:7419 + EPSG:7420 + EPSG:20004 + EPSG:20005 + EPSG:20006 + EPSG:20007 + EPSG:20008 + EPSG:20009 + EPSG:20010 + EPSG:20011 + EPSG:20012 + EPSG:20013 + EPSG:20014 + EPSG:20015 + EPSG:20016 + EPSG:20017 + EPSG:20018 + EPSG:20019 + EPSG:20020 + EPSG:20021 + EPSG:20022 + EPSG:20023 + EPSG:20024 + EPSG:20025 + EPSG:20026 + EPSG:20027 + EPSG:20028 + EPSG:20029 + EPSG:20030 + EPSG:20031 + EPSG:20032 + EPSG:20064 + EPSG:20065 + EPSG:20066 + EPSG:20067 + EPSG:20068 + EPSG:20069 + EPSG:20070 + EPSG:20071 + EPSG:20072 + EPSG:20073 + EPSG:20074 + EPSG:20075 + EPSG:20076 + EPSG:20077 + EPSG:20078 + EPSG:20079 + EPSG:20080 + EPSG:20081 + EPSG:20082 + EPSG:20083 + EPSG:20084 + EPSG:20085 + EPSG:20086 + EPSG:20087 + EPSG:20088 + EPSG:20089 + EPSG:20090 + EPSG:20091 + EPSG:20092 + EPSG:20135 + EPSG:20136 + EPSG:20137 + EPSG:20138 + EPSG:20248 + EPSG:20249 + EPSG:20250 + EPSG:20251 + EPSG:20252 + EPSG:20253 + EPSG:20254 + EPSG:20255 + EPSG:20256 + EPSG:20257 + EPSG:20258 + EPSG:20348 + EPSG:20349 + EPSG:20350 + EPSG:20351 + EPSG:20352 + EPSG:20353 + EPSG:20354 + EPSG:20355 + EPSG:20356 + EPSG:20357 + EPSG:20358 + EPSG:20436 + EPSG:20437 + EPSG:20438 + EPSG:20439 + EPSG:20440 + EPSG:20499 + EPSG:20538 + EPSG:20539 + EPSG:20790 + EPSG:20791 + EPSG:20822 + EPSG:20823 + EPSG:20824 + EPSG:20934 + EPSG:20935 + EPSG:20936 + EPSG:21035 + EPSG:21036 + EPSG:21037 + EPSG:21095 + EPSG:21096 + EPSG:21097 + EPSG:21100 + EPSG:21148 + EPSG:21149 + EPSG:21150 + EPSG:21291 + EPSG:21292 + EPSG:21413 + EPSG:21414 + EPSG:21415 + EPSG:21416 + EPSG:21417 + EPSG:21418 + EPSG:21419 + EPSG:21420 + EPSG:21421 + EPSG:21422 + EPSG:21423 + EPSG:21453 + EPSG:21454 + EPSG:21455 + EPSG:21456 + EPSG:21457 + EPSG:21458 + EPSG:21459 + EPSG:21460 + EPSG:21461 + EPSG:21462 + EPSG:21463 + EPSG:21473 + EPSG:21474 + EPSG:21475 + EPSG:21476 + EPSG:21477 + EPSG:21478 + EPSG:21479 + EPSG:21480 + EPSG:21481 + EPSG:21482 + EPSG:21483 + EPSG:21500 + EPSG:21780 + EPSG:21781 + EPSG:21817 + EPSG:21818 + EPSG:21891 + EPSG:21892 + EPSG:21893 + EPSG:21894 + EPSG:21896 + EPSG:21897 + EPSG:21898 + EPSG:21899 + EPSG:22032 + EPSG:22033 + EPSG:22091 + EPSG:22092 + EPSG:22171 + EPSG:22172 + EPSG:22173 + EPSG:22174 + EPSG:22175 + EPSG:22176 + EPSG:22177 + EPSG:22181 + EPSG:22182 + EPSG:22183 + EPSG:22184 + EPSG:22185 + EPSG:22186 + EPSG:22187 + EPSG:22191 + EPSG:22192 + EPSG:22193 + EPSG:22194 + EPSG:22195 + EPSG:22196 + EPSG:22197 + EPSG:22234 + EPSG:22235 + EPSG:22236 + EPSG:22275 + EPSG:22277 + EPSG:22279 + EPSG:22281 + EPSG:22283 + EPSG:22285 + EPSG:22287 + EPSG:22289 + EPSG:22291 + EPSG:22293 + EPSG:22300 + EPSG:22332 + EPSG:22391 + EPSG:22392 + EPSG:22521 + EPSG:22522 + EPSG:22523 + EPSG:22524 + EPSG:22525 + EPSG:22700 + EPSG:22770 + EPSG:22780 + EPSG:22832 + EPSG:22991 + EPSG:22992 + EPSG:22993 + EPSG:22994 + EPSG:23028 + EPSG:23029 + EPSG:23030 + EPSG:23031 + EPSG:23032 + EPSG:23033 + EPSG:23034 + EPSG:23035 + EPSG:23036 + EPSG:23037 + EPSG:23038 + EPSG:23090 + EPSG:23095 + EPSG:23239 + EPSG:23240 + EPSG:23433 + EPSG:23700 + EPSG:23846 + EPSG:23847 + EPSG:23848 + EPSG:23849 + EPSG:23850 + EPSG:23851 + EPSG:23852 + EPSG:23853 + EPSG:23866 + EPSG:23867 + EPSG:23868 + EPSG:23869 + EPSG:23870 + EPSG:23871 + EPSG:23872 + EPSG:23877 + EPSG:23878 + EPSG:23879 + EPSG:23880 + EPSG:23881 + EPSG:23882 + EPSG:23883 + EPSG:23884 + EPSG:23886 + EPSG:23887 + EPSG:23888 + EPSG:23889 + EPSG:23890 + EPSG:23891 + EPSG:23892 + EPSG:23893 + EPSG:23894 + EPSG:23946 + EPSG:23947 + EPSG:23948 + EPSG:24047 + EPSG:24048 + EPSG:24100 + EPSG:24200 + EPSG:24305 + EPSG:24306 + EPSG:24311 + EPSG:24312 + EPSG:24313 + EPSG:24342 + EPSG:24343 + EPSG:24344 + EPSG:24345 + EPSG:24346 + EPSG:24347 + EPSG:24370 + EPSG:24371 + EPSG:24372 + EPSG:24373 + EPSG:24374 + EPSG:24375 + EPSG:24376 + EPSG:24377 + EPSG:24378 + EPSG:24379 + EPSG:24380 + EPSG:24381 + EPSG:24382 + EPSG:24383 + EPSG:24500 + EPSG:24547 + EPSG:24548 + EPSG:24571 + EPSG:24600 + EPSG:24718 + EPSG:24719 + EPSG:24720 + EPSG:24817 + EPSG:24818 + EPSG:24819 + EPSG:24820 + EPSG:24821 + EPSG:24877 + EPSG:24878 + EPSG:24879 + EPSG:24880 + EPSG:24881 + EPSG:24882 + EPSG:24891 + EPSG:24892 + EPSG:24893 + EPSG:25000 + EPSG:25231 + EPSG:25391 + EPSG:25392 + EPSG:25393 + EPSG:25394 + EPSG:25395 + EPSG:25700 + EPSG:25828 + EPSG:25829 + EPSG:25830 + EPSG:25831 + EPSG:25832 + EPSG:25833 + EPSG:25834 + EPSG:25835 + EPSG:25836 + EPSG:25837 + EPSG:25838 + EPSG:25884 + EPSG:25932 + EPSG:26191 + EPSG:26192 + EPSG:26193 + EPSG:26194 + EPSG:26195 + EPSG:26237 + EPSG:26331 + EPSG:26332 + EPSG:26391 + EPSG:26392 + EPSG:26393 + EPSG:26432 + EPSG:26591 + EPSG:26592 + EPSG:26632 + EPSG:26692 + EPSG:26701 + EPSG:26702 + EPSG:26703 + EPSG:26704 + EPSG:26705 + EPSG:26706 + EPSG:26707 + EPSG:26708 + EPSG:26709 + EPSG:26710 + EPSG:26711 + EPSG:26712 + EPSG:26713 + EPSG:26714 + EPSG:26715 + EPSG:26716 + EPSG:26717 + EPSG:26718 + EPSG:26719 + EPSG:26720 + EPSG:26721 + EPSG:26722 + EPSG:26729 + EPSG:26730 + EPSG:26731 + EPSG:26732 + EPSG:26733 + EPSG:26734 + EPSG:26735 + EPSG:26736 + EPSG:26737 + EPSG:26738 + EPSG:26739 + EPSG:26740 + EPSG:26741 + EPSG:26742 + EPSG:26743 + EPSG:26744 + EPSG:26745 + EPSG:26746 + EPSG:26747 + EPSG:26748 + EPSG:26749 + EPSG:26750 + EPSG:26751 + EPSG:26752 + EPSG:26753 + EPSG:26754 + EPSG:26755 + EPSG:26756 + EPSG:26757 + EPSG:26758 + EPSG:26759 + EPSG:26760 + EPSG:26766 + EPSG:26767 + EPSG:26768 + EPSG:26769 + EPSG:26770 + EPSG:26771 + EPSG:26772 + EPSG:26773 + EPSG:26774 + EPSG:26775 + EPSG:26776 + EPSG:26777 + EPSG:26778 + EPSG:26779 + EPSG:26780 + EPSG:26781 + EPSG:26782 + EPSG:26783 + EPSG:26784 + EPSG:26785 + EPSG:26786 + EPSG:26787 + EPSG:26791 + EPSG:26792 + EPSG:26793 + EPSG:26794 + EPSG:26795 + EPSG:26796 + EPSG:26797 + EPSG:26798 + EPSG:26799 + EPSG:26801 + EPSG:26802 + EPSG:26803 + EPSG:26811 + EPSG:26812 + EPSG:26813 + EPSG:26901 + EPSG:26902 + EPSG:26903 + EPSG:26904 + EPSG:26905 + EPSG:26906 + EPSG:26907 + EPSG:26908 + EPSG:26909 + EPSG:26910 + EPSG:26911 + EPSG:26912 + EPSG:26913 + EPSG:26914 + EPSG:26915 + EPSG:26916 + EPSG:26917 + EPSG:26918 + EPSG:26919 + EPSG:26920 + EPSG:26921 + EPSG:26922 + EPSG:26923 + EPSG:26929 + EPSG:26930 + EPSG:26931 + EPSG:26932 + EPSG:26933 + EPSG:26934 + EPSG:26935 + EPSG:26936 + EPSG:26937 + EPSG:26938 + EPSG:26939 + EPSG:26940 + EPSG:26941 + EPSG:26942 + EPSG:26943 + EPSG:26944 + EPSG:26945 + EPSG:26946 + EPSG:26948 + EPSG:26949 + EPSG:26950 + EPSG:26951 + EPSG:26952 + EPSG:26953 + EPSG:26954 + EPSG:26955 + EPSG:26956 + EPSG:26957 + EPSG:26958 + EPSG:26959 + EPSG:26960 + EPSG:26961 + EPSG:26962 + EPSG:26963 + EPSG:26964 + EPSG:26965 + EPSG:26966 + EPSG:26967 + EPSG:26968 + EPSG:26969 + EPSG:26970 + EPSG:26971 + EPSG:26972 + EPSG:26973 + EPSG:26974 + EPSG:26975 + EPSG:26976 + EPSG:26977 + EPSG:26978 + EPSG:26979 + EPSG:26980 + EPSG:26981 + EPSG:26982 + EPSG:26983 + EPSG:26984 + EPSG:26985 + EPSG:26986 + EPSG:26987 + EPSG:26988 + EPSG:26989 + EPSG:26990 + EPSG:26991 + EPSG:26992 + EPSG:26993 + EPSG:26994 + EPSG:26995 + EPSG:26996 + EPSG:26997 + EPSG:26998 + EPSG:27037 + EPSG:27038 + EPSG:27039 + EPSG:27040 + EPSG:27120 + EPSG:27200 + EPSG:27205 + EPSG:27206 + EPSG:27207 + EPSG:27208 + EPSG:27209 + EPSG:27210 + EPSG:27211 + EPSG:27212 + EPSG:27213 + EPSG:27214 + EPSG:27215 + EPSG:27216 + EPSG:27217 + EPSG:27218 + EPSG:27219 + EPSG:27220 + EPSG:27221 + EPSG:27222 + EPSG:27223 + EPSG:27224 + EPSG:27225 + EPSG:27226 + EPSG:27227 + EPSG:27228 + EPSG:27229 + EPSG:27230 + EPSG:27231 + EPSG:27232 + EPSG:27258 + EPSG:27259 + EPSG:27260 + EPSG:27291 + EPSG:27292 + EPSG:27391 + EPSG:27392 + EPSG:27393 + EPSG:27394 + EPSG:27395 + EPSG:27396 + EPSG:27397 + EPSG:27398 + EPSG:27429 + EPSG:27492 + EPSG:27500 + EPSG:27561 + EPSG:27562 + EPSG:27563 + EPSG:27564 + EPSG:27571 + EPSG:27572 + EPSG:27573 + EPSG:27574 + EPSG:27581 + EPSG:27582 + EPSG:27583 + EPSG:27584 + EPSG:27591 + EPSG:27592 + EPSG:27593 + EPSG:27594 + EPSG:27700 + EPSG:28191 + EPSG:28192 + EPSG:28193 + EPSG:28232 + EPSG:28348 + EPSG:28349 + EPSG:28350 + EPSG:28351 + EPSG:28352 + EPSG:28353 + EPSG:28354 + EPSG:28355 + EPSG:28356 + EPSG:28357 + EPSG:28358 + EPSG:28402 + EPSG:28403 + EPSG:28404 + EPSG:28405 + EPSG:28406 + EPSG:28407 + EPSG:28408 + EPSG:28409 + EPSG:28410 + EPSG:28411 + EPSG:28412 + EPSG:28413 + EPSG:28414 + EPSG:28415 + EPSG:28416 + EPSG:28417 + EPSG:28418 + EPSG:28419 + EPSG:28420 + EPSG:28421 + EPSG:28422 + EPSG:28423 + EPSG:28424 + EPSG:28425 + EPSG:28426 + EPSG:28427 + EPSG:28428 + EPSG:28429 + EPSG:28430 + EPSG:28431 + EPSG:28432 + EPSG:28462 + EPSG:28463 + EPSG:28464 + EPSG:28465 + EPSG:28466 + EPSG:28467 + EPSG:28468 + EPSG:28469 + EPSG:28470 + EPSG:28471 + EPSG:28472 + EPSG:28473 + EPSG:28474 + EPSG:28475 + EPSG:28476 + EPSG:28477 + EPSG:28478 + EPSG:28479 + EPSG:28480 + EPSG:28481 + EPSG:28482 + EPSG:28483 + EPSG:28484 + EPSG:28485 + EPSG:28486 + EPSG:28487 + EPSG:28488 + EPSG:28489 + EPSG:28490 + EPSG:28491 + EPSG:28492 + EPSG:28600 + EPSG:28991 + EPSG:28992 + EPSG:29100 + EPSG:29101 + EPSG:29118 + EPSG:29119 + EPSG:29120 + EPSG:29121 + EPSG:29122 + EPSG:29168 + EPSG:29169 + EPSG:29170 + EPSG:29171 + EPSG:29172 + EPSG:29177 + EPSG:29178 + EPSG:29179 + EPSG:29180 + EPSG:29181 + EPSG:29182 + EPSG:29183 + EPSG:29184 + EPSG:29185 + EPSG:29187 + EPSG:29188 + EPSG:29189 + EPSG:29190 + EPSG:29191 + EPSG:29192 + EPSG:29193 + EPSG:29194 + EPSG:29195 + EPSG:29220 + EPSG:29221 + EPSG:29333 + EPSG:29371 + EPSG:29373 + EPSG:29375 + EPSG:29377 + EPSG:29379 + EPSG:29381 + EPSG:29383 + EPSG:29385 + EPSG:29635 + EPSG:29636 + EPSG:29700 + EPSG:29701 + EPSG:29702 + EPSG:29738 + EPSG:29739 + EPSG:29849 + EPSG:29850 + EPSG:29871 + EPSG:29872 + EPSG:29873 + EPSG:29900 + EPSG:29901 + EPSG:29902 + EPSG:29903 + EPSG:30161 + EPSG:30162 + EPSG:30163 + EPSG:30164 + EPSG:30165 + EPSG:30166 + EPSG:30167 + EPSG:30168 + EPSG:30169 + EPSG:30170 + EPSG:30171 + EPSG:30172 + EPSG:30173 + EPSG:30174 + EPSG:30175 + EPSG:30176 + EPSG:30177 + EPSG:30178 + EPSG:30179 + EPSG:30200 + EPSG:30339 + EPSG:30340 + EPSG:30491 + EPSG:30492 + EPSG:30493 + EPSG:30494 + EPSG:30729 + EPSG:30730 + EPSG:30731 + EPSG:30732 + EPSG:30791 + EPSG:30792 + EPSG:30800 + EPSG:31028 + EPSG:31121 + EPSG:31154 + EPSG:31170 + EPSG:31171 + EPSG:31251 + EPSG:31252 + EPSG:31253 + EPSG:31254 + EPSG:31255 + EPSG:31256 + EPSG:31257 + EPSG:31258 + EPSG:31259 + EPSG:31265 + EPSG:31266 + EPSG:31267 + EPSG:31268 + EPSG:31275 + EPSG:31276 + EPSG:31277 + EPSG:31278 + EPSG:31279 + EPSG:31281 + EPSG:31282 + EPSG:31283 + EPSG:31284 + EPSG:31285 + EPSG:31286 + EPSG:31287 + EPSG:31288 + EPSG:31289 + EPSG:31290 + EPSG:31291 + EPSG:31292 + EPSG:31293 + EPSG:31294 + EPSG:31295 + EPSG:31296 + EPSG:31297 + EPSG:31300 + EPSG:31370 + EPSG:31461 + EPSG:31462 + EPSG:31463 + EPSG:31464 + EPSG:31465 + EPSG:31466 + EPSG:31467 + EPSG:31468 + EPSG:31469 + EPSG:31528 + EPSG:31529 + EPSG:31600 + EPSG:31700 + EPSG:31838 + EPSG:31839 + EPSG:31900 + EPSG:31901 + EPSG:31965 + EPSG:31966 + EPSG:31967 + EPSG:31968 + EPSG:31969 + EPSG:31970 + EPSG:31971 + EPSG:31972 + EPSG:31973 + EPSG:31974 + EPSG:31975 + EPSG:31976 + EPSG:31977 + EPSG:31978 + EPSG:31979 + EPSG:31980 + EPSG:31981 + EPSG:31982 + EPSG:31983 + EPSG:31984 + EPSG:31985 + EPSG:31986 + EPSG:31987 + EPSG:31988 + EPSG:31989 + EPSG:31990 + EPSG:31991 + EPSG:31992 + EPSG:31993 + EPSG:31994 + EPSG:31995 + EPSG:31996 + EPSG:31997 + EPSG:31998 + EPSG:31999 + EPSG:32000 + EPSG:32001 + EPSG:32002 + EPSG:32003 + EPSG:32005 + EPSG:32006 + EPSG:32007 + EPSG:32008 + EPSG:32009 + EPSG:32010 + EPSG:32011 + EPSG:32012 + EPSG:32013 + EPSG:32014 + EPSG:32015 + EPSG:32016 + EPSG:32017 + EPSG:32018 + EPSG:32019 + EPSG:32020 + EPSG:32021 + EPSG:32022 + EPSG:32023 + EPSG:32024 + EPSG:32025 + EPSG:32026 + EPSG:32027 + EPSG:32028 + EPSG:32029 + EPSG:32030 + EPSG:32031 + EPSG:32033 + EPSG:32034 + EPSG:32035 + EPSG:32036 + EPSG:32037 + EPSG:32038 + EPSG:32039 + EPSG:32040 + EPSG:32041 + EPSG:32042 + EPSG:32043 + EPSG:32044 + EPSG:32045 + EPSG:32046 + EPSG:32047 + EPSG:32048 + EPSG:32049 + EPSG:32050 + EPSG:32051 + EPSG:32052 + EPSG:32053 + EPSG:32054 + EPSG:32055 + EPSG:32056 + EPSG:32057 + EPSG:32058 + EPSG:32061 + EPSG:32062 + EPSG:32064 + EPSG:32065 + EPSG:32066 + EPSG:32067 + EPSG:32074 + EPSG:32075 + EPSG:32076 + EPSG:32077 + EPSG:32081 + EPSG:32082 + EPSG:32083 + EPSG:32084 + EPSG:32085 + EPSG:32086 + EPSG:32098 + EPSG:32099 + EPSG:32100 + EPSG:32104 + EPSG:32107 + EPSG:32108 + EPSG:32109 + EPSG:32110 + EPSG:32111 + EPSG:32112 + EPSG:32113 + EPSG:32114 + EPSG:32115 + EPSG:32116 + EPSG:32117 + EPSG:32118 + EPSG:32119 + EPSG:32120 + EPSG:32121 + EPSG:32122 + EPSG:32123 + EPSG:32124 + EPSG:32125 + EPSG:32126 + EPSG:32127 + EPSG:32128 + EPSG:32129 + EPSG:32130 + EPSG:32133 + EPSG:32134 + EPSG:32135 + EPSG:32136 + EPSG:32137 + EPSG:32138 + EPSG:32139 + EPSG:32140 + EPSG:32141 + EPSG:32142 + EPSG:32143 + EPSG:32144 + EPSG:32145 + EPSG:32146 + EPSG:32147 + EPSG:32148 + EPSG:32149 + EPSG:32150 + EPSG:32151 + EPSG:32152 + EPSG:32153 + EPSG:32154 + EPSG:32155 + EPSG:32156 + EPSG:32157 + EPSG:32158 + EPSG:32161 + EPSG:32164 + EPSG:32165 + EPSG:32166 + EPSG:32167 + EPSG:32180 + EPSG:32181 + EPSG:32182 + EPSG:32183 + EPSG:32184 + EPSG:32185 + EPSG:32186 + EPSG:32187 + EPSG:32188 + EPSG:32189 + EPSG:32190 + EPSG:32191 + EPSG:32192 + EPSG:32193 + EPSG:32194 + EPSG:32195 + EPSG:32196 + EPSG:32197 + EPSG:32198 + EPSG:32199 + EPSG:32201 + EPSG:32202 + EPSG:32203 + EPSG:32204 + EPSG:32205 + EPSG:32206 + EPSG:32207 + EPSG:32208 + EPSG:32209 + EPSG:32210 + EPSG:32211 + EPSG:32212 + EPSG:32213 + EPSG:32214 + EPSG:32215 + EPSG:32216 + EPSG:32217 + EPSG:32218 + EPSG:32219 + EPSG:32220 + EPSG:32221 + EPSG:32222 + EPSG:32223 + EPSG:32224 + EPSG:32225 + EPSG:32226 + EPSG:32227 + EPSG:32228 + EPSG:32229 + EPSG:32230 + EPSG:32231 + EPSG:32232 + EPSG:32233 + EPSG:32234 + EPSG:32235 + EPSG:32236 + EPSG:32237 + EPSG:32238 + EPSG:32239 + EPSG:32240 + EPSG:32241 + EPSG:32242 + EPSG:32243 + EPSG:32244 + EPSG:32245 + EPSG:32246 + EPSG:32247 + EPSG:32248 + EPSG:32249 + EPSG:32250 + EPSG:32251 + EPSG:32252 + EPSG:32253 + EPSG:32254 + EPSG:32255 + EPSG:32256 + EPSG:32257 + EPSG:32258 + EPSG:32259 + EPSG:32260 + EPSG:32301 + EPSG:32302 + EPSG:32303 + EPSG:32304 + EPSG:32305 + EPSG:32306 + EPSG:32307 + EPSG:32308 + EPSG:32309 + EPSG:32310 + EPSG:32311 + EPSG:32312 + EPSG:32313 + EPSG:32314 + EPSG:32315 + EPSG:32316 + EPSG:32317 + EPSG:32318 + EPSG:32319 + EPSG:32320 + EPSG:32321 + EPSG:32322 + EPSG:32323 + EPSG:32324 + EPSG:32325 + EPSG:32326 + EPSG:32327 + EPSG:32328 + EPSG:32329 + EPSG:32330 + EPSG:32331 + EPSG:32332 + EPSG:32333 + EPSG:32334 + EPSG:32335 + EPSG:32336 + EPSG:32337 + EPSG:32338 + EPSG:32339 + EPSG:32340 + EPSG:32341 + EPSG:32342 + EPSG:32343 + EPSG:32344 + EPSG:32345 + EPSG:32346 + EPSG:32347 + EPSG:32348 + EPSG:32349 + EPSG:32350 + EPSG:32351 + EPSG:32352 + EPSG:32353 + EPSG:32354 + EPSG:32355 + EPSG:32356 + EPSG:32357 + EPSG:32358 + EPSG:32359 + EPSG:32360 + EPSG:32401 + EPSG:32402 + EPSG:32403 + EPSG:32404 + EPSG:32405 + EPSG:32406 + EPSG:32407 + EPSG:32408 + EPSG:32409 + EPSG:32410 + EPSG:32411 + EPSG:32412 + EPSG:32413 + EPSG:32414 + EPSG:32415 + EPSG:32416 + EPSG:32417 + EPSG:32418 + EPSG:32419 + EPSG:32420 + EPSG:32421 + EPSG:32422 + EPSG:32423 + EPSG:32424 + EPSG:32425 + EPSG:32426 + EPSG:32427 + EPSG:32428 + EPSG:32429 + EPSG:32430 + EPSG:32431 + EPSG:32432 + EPSG:32433 + EPSG:32434 + EPSG:32435 + EPSG:32436 + EPSG:32437 + EPSG:32438 + EPSG:32439 + EPSG:32440 + EPSG:32441 + EPSG:32442 + EPSG:32443 + EPSG:32444 + EPSG:32445 + EPSG:32446 + EPSG:32447 + EPSG:32448 + EPSG:32449 + EPSG:32450 + EPSG:32451 + EPSG:32452 + EPSG:32453 + EPSG:32454 + EPSG:32455 + EPSG:32456 + EPSG:32457 + EPSG:32458 + EPSG:32459 + EPSG:32460 + EPSG:32501 + EPSG:32502 + EPSG:32503 + EPSG:32504 + EPSG:32505 + EPSG:32506 + EPSG:32507 + EPSG:32508 + EPSG:32509 + EPSG:32510 + EPSG:32511 + EPSG:32512 + EPSG:32513 + EPSG:32514 + EPSG:32515 + EPSG:32516 + EPSG:32517 + EPSG:32518 + EPSG:32519 + EPSG:32520 + EPSG:32521 + EPSG:32522 + EPSG:32523 + EPSG:32524 + EPSG:32525 + EPSG:32526 + EPSG:32527 + EPSG:32528 + EPSG:32529 + EPSG:32530 + EPSG:32531 + EPSG:32532 + EPSG:32533 + EPSG:32534 + EPSG:32535 + EPSG:32536 + EPSG:32537 + EPSG:32538 + EPSG:32539 + EPSG:32540 + EPSG:32541 + EPSG:32542 + EPSG:32543 + EPSG:32544 + EPSG:32545 + EPSG:32546 + EPSG:32547 + EPSG:32548 + EPSG:32549 + EPSG:32550 + EPSG:32551 + EPSG:32552 + EPSG:32553 + EPSG:32554 + EPSG:32555 + EPSG:32556 + EPSG:32557 + EPSG:32558 + EPSG:32559 + EPSG:32560 + EPSG:32600 + EPSG:32601 + EPSG:32602 + EPSG:32603 + EPSG:32604 + EPSG:32605 + EPSG:32606 + EPSG:32607 + EPSG:32608 + EPSG:32609 + EPSG:32610 + EPSG:32611 + EPSG:32612 + EPSG:32613 + EPSG:32614 + EPSG:32615 + EPSG:32616 + EPSG:32617 + EPSG:32618 + EPSG:32619 + EPSG:32620 + EPSG:32621 + EPSG:32622 + EPSG:32623 + EPSG:32624 + EPSG:32625 + EPSG:32626 + EPSG:32627 + EPSG:32628 + EPSG:32629 + EPSG:32630 + EPSG:32631 + EPSG:32632 + EPSG:32633 + EPSG:32634 + EPSG:32635 + EPSG:32636 + EPSG:32637 + EPSG:32638 + EPSG:32639 + EPSG:32640 + EPSG:32641 + EPSG:32642 + EPSG:32643 + EPSG:32644 + EPSG:32645 + EPSG:32646 + EPSG:32647 + EPSG:32648 + EPSG:32649 + EPSG:32650 + EPSG:32651 + EPSG:32652 + EPSG:32653 + EPSG:32654 + EPSG:32655 + EPSG:32656 + EPSG:32657 + EPSG:32658 + EPSG:32659 + EPSG:32660 + EPSG:32661 + EPSG:32662 + EPSG:32664 + EPSG:32665 + EPSG:32666 + EPSG:32667 + EPSG:32700 + EPSG:32701 + EPSG:32702 + EPSG:32703 + EPSG:32704 + EPSG:32705 + EPSG:32706 + EPSG:32707 + EPSG:32708 + EPSG:32709 + EPSG:32710 + EPSG:32711 + EPSG:32712 + EPSG:32713 + EPSG:32714 + EPSG:32715 + EPSG:32716 + EPSG:32717 + EPSG:32718 + EPSG:32719 + EPSG:32720 + EPSG:32721 + EPSG:32722 + EPSG:32723 + EPSG:32724 + EPSG:32725 + EPSG:32726 + EPSG:32727 + EPSG:32728 + EPSG:32729 + EPSG:32730 + EPSG:32731 + EPSG:32732 + EPSG:32733 + EPSG:32734 + EPSG:32735 + EPSG:32736 + EPSG:32737 + EPSG:32738 + EPSG:32739 + EPSG:32740 + EPSG:32741 + EPSG:32742 + EPSG:32743 + EPSG:32744 + EPSG:32745 + EPSG:32746 + EPSG:32747 + EPSG:32748 + EPSG:32749 + EPSG:32750 + EPSG:32751 + EPSG:32752 + EPSG:32753 + EPSG:32754 + EPSG:32755 + EPSG:32756 + EPSG:32757 + EPSG:32758 + EPSG:32759 + EPSG:32760 + EPSG:32761 + EPSG:32766 + EPSG:61206405 + EPSG:61216405 + EPSG:61226405 + EPSG:61236405 + EPSG:61246405 + EPSG:61266405 + EPSG:61266413 + EPSG:61276405 + EPSG:61286405 + EPSG:61296405 + EPSG:61306405 + EPSG:61306413 + EPSG:61316405 + EPSG:61326405 + EPSG:61336405 + EPSG:61346405 + EPSG:61356405 + EPSG:61366405 + EPSG:61376405 + EPSG:61386405 + EPSG:61396405 + EPSG:61406405 + EPSG:61406413 + EPSG:61416405 + EPSG:61426405 + EPSG:61436405 + EPSG:61446405 + EPSG:61456405 + EPSG:61466405 + EPSG:61476405 + EPSG:61486405 + EPSG:61486413 + EPSG:61496405 + EPSG:61506405 + EPSG:61516405 + EPSG:61516413 + EPSG:61526405 + EPSG:61526413 + EPSG:61536405 + EPSG:61546405 + EPSG:61556405 + EPSG:61566405 + EPSG:61576405 + EPSG:61586405 + EPSG:61596405 + EPSG:61606405 + EPSG:61616405 + EPSG:61626405 + EPSG:61636405 + EPSG:61636413 + EPSG:61646405 + EPSG:61656405 + EPSG:61666405 + EPSG:61676405 + EPSG:61676413 + EPSG:61686405 + EPSG:61696405 + EPSG:61706405 + EPSG:61706413 + EPSG:61716405 + EPSG:61716413 + EPSG:61736405 + EPSG:61736413 + EPSG:61746405 + EPSG:61756405 + EPSG:61766405 + EPSG:61766413 + EPSG:61786405 + EPSG:61796405 + EPSG:61806405 + EPSG:61806413 + EPSG:61816405 + EPSG:61826405 + EPSG:61836405 + EPSG:61846405 + EPSG:61886405 + EPSG:61896405 + EPSG:61896413 + EPSG:61906405 + EPSG:61906413 + EPSG:61916405 + EPSG:61926405 + EPSG:61936405 + EPSG:61946405 + EPSG:61956405 + EPSG:61966405 + EPSG:61976405 + EPSG:61986405 + EPSG:61996405 + EPSG:62006405 + EPSG:62016405 + EPSG:62026405 + EPSG:62036405 + EPSG:62046405 + EPSG:62056405 + EPSG:62066405 + EPSG:62076405 + EPSG:62086405 + EPSG:62096405 + EPSG:62106405 + EPSG:62116405 + EPSG:62126405 + EPSG:62136405 + EPSG:62146405 + EPSG:62156405 + EPSG:62166405 + EPSG:62186405 + EPSG:62196405 + EPSG:62206405 + EPSG:62216405 + EPSG:62226405 + EPSG:62236405 + EPSG:62246405 + EPSG:62256405 + EPSG:62276405 + EPSG:62296405 + EPSG:62306405 + EPSG:62316405 + EPSG:62326405 + EPSG:62336405 + EPSG:62366405 + EPSG:62376405 + EPSG:62386405 + EPSG:62396405 + EPSG:62406405 + EPSG:62416405 + EPSG:62426405 + EPSG:62436405 + EPSG:62446405 + EPSG:62456405 + EPSG:62466405 + EPSG:62476405 + EPSG:62486405 + EPSG:62496405 + EPSG:62506405 + EPSG:62516405 + EPSG:62526405 + EPSG:62536405 + EPSG:62546405 + EPSG:62556405 + EPSG:62566405 + EPSG:62576405 + EPSG:62586405 + EPSG:62586413 + EPSG:62596405 + EPSG:62616405 + EPSG:62626405 + EPSG:62636405 + EPSG:62646405 + EPSG:62656405 + EPSG:62666405 + EPSG:62676405 + EPSG:62686405 + EPSG:62696405 + EPSG:62706405 + EPSG:62716405 + EPSG:62726405 + EPSG:62736405 + EPSG:62746405 + EPSG:62756405 + EPSG:62766405 + EPSG:62776405 + EPSG:62786405 + EPSG:62796405 + EPSG:62806405 + EPSG:62816405 + EPSG:62826405 + EPSG:62836405 + EPSG:62836413 + EPSG:62846405 + EPSG:62856405 + EPSG:62866405 + EPSG:62886405 + EPSG:62896405 + EPSG:62926405 + EPSG:62936405 + EPSG:62956405 + EPSG:62976405 + EPSG:62986405 + EPSG:62996405 + EPSG:63006405 + EPSG:63016405 + EPSG:63026405 + EPSG:63036405 + EPSG:63046405 + EPSG:63066405 + EPSG:63076405 + EPSG:63086405 + EPSG:63096405 + EPSG:63106405 + EPSG:63116405 + EPSG:63126405 + EPSG:63136405 + EPSG:63146405 + EPSG:63156405 + EPSG:63166405 + EPSG:63176405 + EPSG:63186405 + EPSG:63196405 + EPSG:63226405 + EPSG:63246405 + EPSG:63266405 + EPSG:63266406 + EPSG:63266407 + EPSG:63266408 + EPSG:63266409 + EPSG:63266410 + EPSG:63266411 + EPSG:63266412 + EPSG:63266413 + EPSG:63266414 + EPSG:63266415 + EPSG:63266416 + EPSG:63266417 + EPSG:63266418 + EPSG:63266419 + EPSG:63266420 + EPSG:66006405 + EPSG:66016405 + EPSG:66026405 + EPSG:66036405 + EPSG:66046405 + EPSG:66056405 + EPSG:66066405 + EPSG:66076405 + EPSG:66086405 + EPSG:66096405 + EPSG:66106405 + EPSG:66116405 + EPSG:66126405 + EPSG:66126413 + EPSG:66136405 + EPSG:66146405 + EPSG:66156405 + EPSG:66166405 + EPSG:66186405 + EPSG:66196405 + EPSG:66196413 + EPSG:66206405 + EPSG:66216405 + EPSG:66226405 + EPSG:66236405 + EPSG:66246405 + EPSG:66246413 + EPSG:66256405 + EPSG:66266405 + EPSG:66276405 + EPSG:66276413 + EPSG:66286405 + EPSG:66296405 + EPSG:66306405 + EPSG:66316405 + EPSG:66326405 + EPSG:66336405 + EPSG:66346405 + EPSG:66356405 + EPSG:66366405 + EPSG:66376405 + EPSG:66386405 + EPSG:66396405 + EPSG:66406405 + EPSG:66406413 + EPSG:66416405 + EPSG:66426405 + EPSG:66436405 + EPSG:66446405 + EPSG:66456405 + EPSG:66456413 + EPSG:66466405 + EPSG:66576405 + EPSG:66586405 + EPSG:66596405 + EPSG:66596413 + EPSG:66606405 + EPSG:66616405 + EPSG:66616413 + EPSG:66636405 + EPSG:66646405 + EPSG:66656405 + EPSG:66666405 + EPSG:66676405 + EPSG:68016405 + EPSG:68026405 + EPSG:68036405 + EPSG:68046405 + EPSG:68056405 + EPSG:68066405 + EPSG:68086405 + EPSG:68096405 + EPSG:68136405 + EPSG:68146405 + EPSG:68156405 + EPSG:68186405 + EPSG:68206405 + EPSG:69036405 + EPSG:42302 + EPSG:42301 + EPSG:900913 + EPSG:45556 + EPSG:45555 + EPSG:54004 + EPSG:41001 + EPSG:42311 + EPSG:42310 + EPSG:18001 + EPSG:100003 + EPSG:42106 + EPSG:100002 + EPSG:42105 + EPSG:100001 + EPSG:42309 + EPSG:42104 + EPSG:42308 + EPSG:42103 + EPSG:42307 + EPSG:42102 + EPSG:42306 + EPSG:42101 + EPSG:42305 + EPSG:42304 + EPSG:42303 + + + tiger:poly_landmarks + Manhattan (NY) landmarks + Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs + + DS_poly_landmarks + poly_landmarks + landmarks + manhattan + + EPSG:4326 + + + + + + tiger:poi + Manhattan (NY) points of interest + Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest. + + poi + DS_poi + points_of_interest + Manhattan + + EPSG:4326 + + + + + + tiger:tiger_roads + Manhattan (NY) roads + Highly simplified road layout of Manhattan in New York.. + + DS_tiger_roads + tiger_roads + roads + + EPSG:4326 + + + + + + sf:archsites + Spearfish archeological sites + Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA + + archsites + sfArchsites + spearfish + archeology + + EPSG:26713 + + + + + + sf:bugsites + Spearfish bug locations + Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA + + sfBugsites + bugsites + insects + spearfish + tiger_beetles + + EPSG:26713 + + + + + + sf:restricted + Spearfish restricted areas + Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA + + restricted + sfRestricted + spearfish + areas + + EPSG:26713 + + + + + + sf:roads + Spearfish roads + Sample data from GRASS, road layout, Spearfish, South Dakota, USA + + sfRoads + roads + spearfish + + EPSG:26713 + + + + + + sf:streams + Spearfish streams + Sample data from GRASS, streams, Spearfish, South Dakota, USA + + sfStreams + streams + spearfish + + EPSG:26713 + + + + + + topp:tasmania_cities + Tasmania cities + Cities in Tasmania (actually, just the capital) + + cities + Tasmania + + EPSG:4326 + + + + + + topp:tasmania_roads + Tasmania roads + Main Tasmania roads + + Roads + Tasmania + + EPSG:4326 + + + + + + topp:tasmania_state_boundaries + Tasmania state boundaries + Tasmania state boundaries + + tasmania_state_boundaries + Tasmania + boundaries + + EPSG:4326 + + + + + + topp:tasmania_water_bodies + Tasmania water bodies + Tasmania water bodies + + Lakes + Bodies + Australia + Water + Tasmania + + EPSG:4326 + + + + + + topp:states + USA Population + This is some census data on the states. + + census + united + boundaries + state + states + + EPSG:4326 + + + + + + tiger:giant_polygon + World rectangle + A simple rectangular polygon covering most of the world, it\'s only used for the purpose of providing a background (WMS bgcolor could be used instead) + + DS_giant_polygon + giant_polygon + + EPSG:4326 + + + + + + nurc:Arc_Sample + Global annual rainfall + Global annual rainfall in ArcGrid format + + WCS + arcGridSample + arcGridSample_Coverage + + EPSG:4326 + + + + + + nurc:Img_Sample + North America sample imagery + A very rough imagery of North America + + WCS + worldImageSample + worldImageSample_Coverage + + EPSG:4326 + + + + + + nurc:mosaic + Sample PNG mosaic + Subsampled satellite imagery loaded as a mosaic of PNG images + + WCS + mosaic + mosaic + + EPSG:4326 + + + + + + nurc:Pk50095 + Sample scanned and georerenced map + This is a sample for the world image format (wld + prj + tiff) + + WCS + img_sample2 + Pk50095 + + EPSG:32633 + + + + + + sf:sfdem + sfdem is a Tagged Image File Format with Geographic information + Generated from sfdem + + WCS + sfdem + sfdem + + EPSG:26713 + + + + + + spearfish + spearfish + Layer-Group type layer: spearfish + EPSG:26713 + + + + + tasmania + tasmania + Layer-Group type layer: tasmania + EPSG:4326 + + + + + tiger-ny + tiger-ny + Layer-Group type layer: tiger-ny + EPSG:4326 + + + + + + diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml new file mode 100644 index 0000000000..788357b65c --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml @@ -0,0 +1,283 @@ + + + ]> + + + + + OGC:WMS + Acme Corp. Map Server + WMT Map Server maintained by Acme Corporation. Contact: webmaster@wmt.acme.com. High-quality maps showing roadrunner nests and possible ambush locations. + + + bird + roadrunner + ambush + + + + + + Jeff deLaBeaujardiere + NASA + + Computer Scientist + + + postal +
NASA Goddard Space Flight Center, Code 933
+ Greenbelt + MD + 20771 + USA + +
+ +1 301 286-1569 + +1 301 286-1777 + delabeau@iniki.gsfc.nasa.gov +
+ none + + none +
+ + + + application/vnd.ogc.wms_xml + + + + + + + + + + + + + + + image/gif + image/png + image/jpeg + + + + + + + + + + + + + application/vnd.ogc.gml + + text/plain + text/html + + + + + + + + + + + application/vnd.ogc.gml + + + + + + + + + + + + application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage + + application/vnd.ogc.se_blank + + + + + + Acme Corp. Map Server + EPSG:4326 + + + + + + ROADS_RIVERS + Roads and Rivers + EPSG:26986 + + + + + + State College University + + + image/gif + + + + + 123456 + + application/vnd.ogc.se_xml + + + + + + + + ROADS_1M + Roads at 1:1M scale + Roads at a scale of 1 to 1 million. + + road + + transportation + atlas + + 123456 + + text/plain + + + + text/xml + + + + + + + RIVERS_1M + Rivers at 1:1M scale + Rivers at a scale of 1 to 1 million. + + + river + canal + waterway + + + + + + + Weather Forecast Data + EPSG:4326 + + + 1999-01-01/2000-08-22/P1D + + + Clouds + Forecast cloud cover + + + + Temperature + Forecast temperature + + + + Pressure + Forecast barometric pressure + + + 1999-01-01/2000-08-22/P1D + 0,1000,3000,5000,10000 + + + + + + ozone_image + Global ozone distribution (1992) + + 1992 + + + + population + World population, annual + + 1990/2000/P1Y + + + + + + +
diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml new file mode 100644 index 0000000000..69fa94ad10 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml @@ -0,0 +1,124 @@ + + + ]> + + + + OGC:WMS + i3Geo - i3geo + Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas + + i3Geo + + + + + Web Master + Coordena??o Geral de TI + + Administrador do s?tio web + + uri +
http://www.mma.gov.br
+ Brasilia + DF + + Brasil +
+ geoprocessamento@mma.gov.br +
+ none + vedado o uso comercial +
+ + + + + application/vnd.ogc.wms_xml + + + + + + + + + image/png + image/jpeg + image/gif + image/png; mode=8bit + application/x-pdf + image/svg+xml + image/tiff + application/vnd.google-earth.kml+xml + application/vnd.google-earth.kmz + + + + + + + + + text/plain + application/vnd.ogc.gml + + + + + + + + + text/xml + + + + + + + + + + application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage + application/vnd.ogc.se_blank + + + + + i3geoogc + i3Geo - i3geo + Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas + + i3Geo + + + + + + i3Geo + + + image/png + + + + + antigo_caminantes + Guia de Caminantes - 1817 + EPSG:4618 EPSG:4291 EPSG:4326 EPSG:22521 EPSG:22522 EPSG:22523 EPSG:22524 EPSG:22525 EPSG:29101 EPSG:29119 EPSG:29120 EPSG:29121 EPSG:29122 EPSG:29177 EPSG:29178 EPSG:29179 EPSG:29180 EPSG:29181 EPSG:29182 EPSG:29183 EPSG:29184 EPSG:29185 + + + + text/html + + + + + +
diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml new file mode 100644 index 0000000000..eb15d278e5 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml @@ -0,0 +1,178 @@ + + + + + + + + +]> + + + OGC:WMS + GeoServer Web Map Service + A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS + + WFS + WMS + GEOSERVER + + + + + OpenGeo + OpenGeo + + Outreach + + Work +
+ New York + + + USA + + + + inquiry@opengeo.org + + NONE + NONE + + + + + application/vnd.ogc.wms_xml + + + + + + + + + + + + + image/png + application/atom xml + application/atom+xml + application/openlayers + application/pdf + application/rss xml + application/rss+xml + application/vnd.google-earth.kml + application/vnd.google-earth.kml xml + application/vnd.google-earth.kml+xml + application/vnd.google-earth.kmz + application/vnd.google-earth.kmz xml + application/vnd.google-earth.kmz+xml + atom + image/geotiff + image/geotiff8 + image/gif + image/jpeg + image/png8 + image/svg + image/svg xml + image/svg+xml + image/tiff + image/tiff8 + kml + kmz + openlayers + rss + + + + + + + + + + text/plain + application/vnd.ogc.gml + text/html + + + + + + + + + + + + + application/vnd.ogc.wms_xml + + + + + + + + + + image/png + image/jpeg + image/gif + + + + + + + + + + application/vnd.ogc.sld+xml + + + + + + + + + + + application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage + + + + EPSG:900913 + + 156543.03390625 78271.516953125 39135.7584765625 19567.87923828125 9783.939619140625 4891.9698095703125 2445.9849047851562 1222.9924523925781 611.4962261962891 305.74811309814453 152.87405654907226 76.43702827453613 38.218514137268066 19.109257068634033 9.554628534317017 4.777314267158508 2.388657133579254 1.194328566789627 0.5971642833948135 0.29858214169740677 0.14929107084870338 0.07464553542435169 0.037322767712175846 0.018661383856087923 0.009330691928043961 0.004665345964021981 + 256 + 256 + image/png + medford:hydro + + + + EPSG:4326 + + 0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 6.866455078125E-4 3.4332275390625E-4 1.71661376953125E-4 8.58306884765625E-5 4.291534423828125E-5 2.1457672119140625E-5 1.0728836059570312E-5 5.364418029785156E-6 2.682209014892578E-6 1.341104507446289E-6 6.705522537231445E-7 3.3527612686157227E-7 1.6763806343078613E-7 8.381903171539307E-8 4.190951585769653E-8 2.0954757928848267E-8 + 256 + 256 + image/gif + medford + + + + + + GeoServer Web Map Service + A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS + EPSG:4326 + EPSG:900913 + + + + diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml new file mode 100644 index 0000000000..e08f97af23 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml @@ -0,0 +1,17 @@ + + + Plain text message about an error. + Another error message, this one with a service + exception code supplied. + + , line 42 +A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters: +]]> + + + foo.c An error occurred Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it. ]]> + + diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml new file mode 100644 index 0000000000..0d4c52da60 --- /dev/null +++ b/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml @@ -0,0 +1,284 @@ + + + + WMS + Acme Corp. Map Server + Map Server maintained by Acme Corporation. Contact: webmaster@wmt.acme.com. High-quality maps showing roadrunner nests and possible ambush locations. + + + bird + roadrunner + ambush + + + + + + + Jeff Smith + NASA + + Computer Scientist + + + postal +
NASA Goddard Space Flight Center
+ Greenbelt + MD + 20771 + + USA +
+ +1 301 555-1212 + user@host.com +
+ + none + + none + 16 + 2048 + 2048 +
+ + + + + text/xml + + + + + + + + + + + + + + image/gif + image/png + image/jpeg + + + + + + + + + + + + text/xml + text/plain + text/html + + + + + + + + + + + + XML + + INIMAGE + BLANK + + + Acme Corp. Map Server + CRS:84 + + + + + + + + ROADS_RIVERS + Roads and Rivers + + EPSG:26986 + + -71.63 + -70.78 + 41.75 + 42.90 + + + + + + State College University + + + + image/gif + + + + 123456 + + + XML + + + + 1000 + 250000 + + ROADS_1M + Roads at 1:1M scale + Roads at a scale of 1 to 1 million. + + + road + transportation + atlas + + 123456 + + + text/plain + + + + text/xml + + + + + + + RIVERS_1M + Rivers at 1:1M scale + Rivers at a scale of 1 to 1 million. + + + river + canal + waterway + + + + + + Weather Forecast Data + CRS:84 + + + -180 + 180 + + -90 + 90 + + 1999-01-01/2000-08-22/P1D + + + Clouds + Forecast cloud cover + + + Temperature + Forecast temperature + + + + Pressure + Forecast barometric pressure + + + 1999-01-01/2000-08-22/P1D + + 0,1000,3000,5000,10000 + + + + ozone_image + Global ozone distribution (1992) + + + -180 + 180 + -90 + 90 + + 1992 + + + + population + World population, annual + + -180 + + 180 + -90 + 90 + + 1990/2000/P1Y + + + + +
From 648476050741441152ae81ae6a6919a3259b5e69 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Wed, 6 Feb 2013 14:35:43 +0100 Subject: [PATCH 2/9] make Travis build pass again --- src/ol/parser/ogc/wmscapabilities.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ol/parser/ogc/wmscapabilities.js b/src/ol/parser/ogc/wmscapabilities.js index 5d12af2b43..133c1cca8d 100644 --- a/src/ol/parser/ogc/wmscapabilities.js +++ b/src/ol/parser/ogc/wmscapabilities.js @@ -5,27 +5,33 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1'); goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC'); goog.require('ol.parser.ogc.WMSCapabilities_v1_3_0'); + /** * @define {boolean} Whether to enable WMS Capabilities version 1.1.0. */ ol.ENABLE_WMSCAPS_1_1_0 = true; + /** * @define {boolean} Whether to enable WMS Capabilities version 1.1.1. */ ol.ENABLE_WMSCAPS_1_1_1 = true; + /** * @define {boolean} Whether to enable WMS Capabilities version 1.3.0. */ ol.ENABLE_WMSCAPS_1_3_0 = true; + /** - * @define {boolean} Whether to enable WMS Capabilities version 1.1.1 + * @define {boolean} Whether to enable WMS Capabilities version 1.1.1. * WMSC profile. */ ol.ENABLE_WMSCAPS_1_1_1_WMSC = true; + + /** * @constructor * @param {Object} formatOptions Options which will be set on this object. From f16664cb8776f583f6187477620a86d19e6e9918 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 7 Feb 2013 10:45:35 +0100 Subject: [PATCH 3/9] add an example --- examples/wms-capabilities.html | 53 ++++++++++++++++++++++++++++ examples/wms-capabilities.js | 26 ++++++++++++++ src/ol/parser/ogc/wmscapabilities.js | 10 +++--- 3 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 examples/wms-capabilities.html create mode 100644 examples/wms-capabilities.js diff --git a/examples/wms-capabilities.html b/examples/wms-capabilities.html new file mode 100644 index 0000000000..62e0a2e96a --- /dev/null +++ b/examples/wms-capabilities.html @@ -0,0 +1,53 @@ + + + + + + + + + wms capabilities example + + +
+
+
+

WMS GetCapabilities parsing example

+
Example of parsing a WMS GetCapabilities response.
+
+

See the + wms-capabilities.js source + to see how this is done.

+
+
+
+
wms, capabilities, getcapabilities
+ + + diff --git a/examples/wms-capabilities.js b/examples/wms-capabilities.js new file mode 100644 index 0000000000..71ba95bc33 --- /dev/null +++ b/examples/wms-capabilities.js @@ -0,0 +1,26 @@ +goog.require('goog.debug.Console'); +goog.require('goog.debug.DivConsole'); +goog.require('goog.debug.Logger'); +goog.require('goog.debug.Logger.Level'); +goog.require('goog.json.Serializer'); +goog.require('goog.net.XhrIo'); +goog.require('ol.parser.ogc.WMSCapabilities'); + + +if (goog.DEBUG) { + goog.debug.Console.autoInstall(); + goog.debug.Logger.getLogger('ol').setLevel(goog.debug.Logger.Level.INFO); + var logconsole = new goog.debug.DivConsole(goog.dom.getElement('log')); + logconsole.setCapturing(true); +} + +var parser = new ol.parser.ogc.WMSCapabilities(), result; +var url = '../test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml'; +goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + result = parser.read(xhr.getResponseXml()); + if (goog.DEBUG) { + var output = new goog.json.Serializer().serialize(result); + goog.debug.Logger.getLogger('ol').info(output); + } +}); diff --git a/src/ol/parser/ogc/wmscapabilities.js b/src/ol/parser/ogc/wmscapabilities.js index 133c1cca8d..c30a0e5d1a 100644 --- a/src/ol/parser/ogc/wmscapabilities.js +++ b/src/ol/parser/ogc/wmscapabilities.js @@ -34,12 +34,12 @@ ol.ENABLE_WMSCAPS_1_1_1_WMSC = true; /** * @constructor - * @param {Object} formatOptions Options which will be set on this object. + * @param {Object=} opt_options Options which will be set on this object. * @extends {ol.parser.ogc.Versioned} */ -ol.parser.ogc.WMSCapabilities = function(formatOptions) { - formatOptions = formatOptions || {}; - formatOptions['defaultVersion'] = '1.1.1'; +ol.parser.ogc.WMSCapabilities = function(opt_options) { + opt_options = opt_options || {}; + opt_options['defaultVersion'] = '1.1.1'; this.parsers = {}; if (ol.ENABLE_WMSCAPS_1_1_0) { this.parsers['v1_1_0'] = ol.parser.ogc.WMSCapabilities_v1_1_0; @@ -53,6 +53,6 @@ ol.parser.ogc.WMSCapabilities = function(formatOptions) { if (ol.ENABLE_WMSCAPS_1_3_0) { this.parsers['v1_3_0'] = ol.parser.ogc.WMSCapabilities_v1_3_0; } - goog.base(this, formatOptions); + goog.base(this, opt_options); }; goog.inherits(ol.parser.ogc.WMSCapabilities, ol.parser.ogc.Versioned); From 13d95b90a34364307803c77425e5ad970f82503b Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Wed, 13 Feb 2013 20:58:48 +0100 Subject: [PATCH 4/9] use namespace URI instead of prefix as suggested by @tschaub and discussed with @ahocevar --- src/ol/parser/ogc/exceptionreport.js | 11 +++-------- src/ol/parser/ogc/wmscapabilities_v1.js | 10 +++------- src/ol/parser/ogc/wmscapabilities_v1_1.js | 4 ++-- src/ol/parser/ogc/wmscapabilities_v1_1_0.js | 2 +- src/ol/parser/ogc/wmscapabilities_v1_1_1.js | 2 +- src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js | 2 +- src/ol/parser/ogc/wmscapabilities_v1_3_0.js | 15 +++++++++------ src/ol/parser/xml.js | 11 ++--------- 8 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/ol/parser/ogc/exceptionreport.js b/src/ol/parser/ogc/exceptionreport.js index 45f53b2226..ce2e4990c1 100644 --- a/src/ol/parser/ogc/exceptionreport.js +++ b/src/ol/parser/ogc/exceptionreport.js @@ -9,11 +9,6 @@ goog.require('ol.parser.XML'); * @extends {ol.parser.XML} */ ol.parser.ogc.ExceptionReport = function() { - this.defaultPrefix = 'ogc'; - this.namespaces = {}; - this.namespaces['ogc'] = 'http://www.opengis.net/ogc'; - this.namespaces['ows'] = 'http://www.opengis.net/ows'; - this.namespaces['ows11'] = 'http://www.opengis.net/ows/1.1'; var exceptionReader = function(node, exceptionReport) { var exception = { code: node.getAttribute('exceptionCode'), @@ -28,7 +23,7 @@ ol.parser.ogc.ExceptionReport = function() { exception.texts.push(text); }; this.readers = { - 'ogc': { + 'http://www.opengis.net/ogc': { 'ServiceExceptionReport': function(node, obj) { obj['exceptionReport'] = {}; obj['exceptionReport']['exceptions'] = []; @@ -42,7 +37,7 @@ ol.parser.ogc.ExceptionReport = function() { exceptionReport['exceptions'].push(exception); } }, - 'ows': { + 'http://www.opengis.net/ows': { 'ExceptionReport': function(node, obj) { obj.success = false; obj.exceptionReport = { @@ -59,7 +54,7 @@ ol.parser.ogc.ExceptionReport = function() { exceptionTextReader.apply(this, arguments); } }, - 'ows11': { + 'http://www.opengis.net/ows/1.1': { 'ExceptionReport': function(node, obj) { obj.exceptionReport = { version: node.getAttribute('version'), diff --git a/src/ol/parser/ogc/wmscapabilities_v1.js b/src/ol/parser/ogc/wmscapabilities_v1.js index 02fedc289b..f1fe0ca815 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1.js +++ b/src/ol/parser/ogc/wmscapabilities_v1.js @@ -10,14 +10,10 @@ goog.require('ol.parser.XML'); * @extends {ol.parser.XML} */ ol.parser.ogc.WMSCapabilities_v1 = function() { - this.defaultPrefix = 'wms'; + this.defaultNamespaceURI = 'http://www.opengis.net/wms'; this.errorProperty = 'service'; - this.namespaces = {}; - this.namespaces['wms'] = 'http://www.opengis.net/wms'; - this.namespaces['xlink'] = 'http://www.w3.org/1999/xlink'; - this.namespaces['xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'; this.readers = { - 'wms': { + 'http://www.opengis.net/wms': { 'Service': function(node, obj) { obj['service'] = {}; this.readChildNodes(node, obj['service']); @@ -51,7 +47,7 @@ ol.parser.ogc.WMSCapabilities_v1 = function() { return bbox; }, 'OnlineResource': function(node, obj) { - obj.href = this.getAttributeNS(node, this.namespaces['xlink'], + obj.href = this.getAttributeNS(node, 'http://www.w3.org/1999/xlink', 'href'); }, 'ContactInformation': function(node, obj) { diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1.js b/src/ol/parser/ogc/wmscapabilities_v1_1.js index c451e73955..a4cb628b52 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1_1.js +++ b/src/ol/parser/ogc/wmscapabilities_v1_1.js @@ -9,8 +9,8 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1'); */ ol.parser.ogc.WMSCapabilities_v1_1 = function() { goog.base(this); - var bboxreader = this.readers['wms']['BoundingBox']; - goog.object.extend(this.readers['wms'], { + var bboxreader = this.readers['http://www.opengis.net/wms']['BoundingBox']; + goog.object.extend(this.readers['http://www.opengis.net/wms'], { 'WMT_MS_Capabilities': function(node, obj) { this.readChildNodes(node, obj); }, diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_0.js b/src/ol/parser/ogc/wmscapabilities_v1_1_0.js index 56f5e6c973..9aaea77ba5 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1_1_0.js +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_0.js @@ -10,7 +10,7 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1_1'); ol.parser.ogc.WMSCapabilities_v1_1_0 = function() { goog.base(this); this.version = '1.1.0'; - goog.object.extend(this.readers['wms'], { + goog.object.extend(this.readers['http://www.opengis.net/wms'], { 'SRS': function(node, obj) { var srs = this.getChildValue(node); var values = srs.split(/ +/); diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_1.js b/src/ol/parser/ogc/wmscapabilities_v1_1_1.js index 9dc0db672b..a8c23c2e3f 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1_1_1.js +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_1.js @@ -10,7 +10,7 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1_1'); ol.parser.ogc.WMSCapabilities_v1_1_1 = function() { goog.base(this); this.version = '1.1.1'; - goog.object.extend(this.readers['wms'], { + goog.object.extend(this.readers['http://www.opengis.net/wms'], { 'SRS': function(node, obj) { obj.srs[this.getChildValue(node)] = true; } diff --git a/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js b/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js index eca49226e6..246babafc3 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js +++ b/src/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.js @@ -10,7 +10,7 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1'); ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC = function() { goog.base(this); this.profile = 'WMSC'; - goog.object.extend(this.readers['wms'], { + goog.object.extend(this.readers['http://www.opengis.net/wms'], { 'VendorSpecificCapabilities': function(node, obj) { obj.vendorSpecific = {tileSets: []}; this.readChildNodes(node, obj.vendorSpecific); diff --git a/src/ol/parser/ogc/wmscapabilities_v1_3_0.js b/src/ol/parser/ogc/wmscapabilities_v1_3_0.js index e3ac7ea2a0..c17ab9acea 100644 --- a/src/ol/parser/ogc/wmscapabilities_v1_3_0.js +++ b/src/ol/parser/ogc/wmscapabilities_v1_3_0.js @@ -9,8 +9,8 @@ goog.require('ol.parser.ogc.WMSCapabilities_v1'); */ ol.parser.ogc.WMSCapabilities_v1_3_0 = function() { goog.base(this); - var bboxreader = this.readers['wms']['BoundingBox']; - goog.object.extend(this.readers['wms'], { + var bboxreader = this.readers['http://www.opengis.net/wms']['BoundingBox']; + goog.object.extend(this.readers['http://www.opengis.net/wms'], { 'WMS_Capabilities': function(node, obj) { this.readChildNodes(node, obj); }, @@ -30,7 +30,7 @@ ol.parser.ogc.WMSCapabilities_v1_3_0 = function() { }, 'CRS': function(node, obj) { // CRS is the synonym of SRS - this.readers['wms']['SRS'].apply(this, arguments); + this.readers['http://www.opengis.net/wms']['SRS'].apply(this, arguments); }, 'EX_GeographicBoundingBox': function(node, obj) { // replacement of LatLonBoundingBox @@ -87,7 +87,8 @@ ol.parser.ogc.WMSCapabilities_v1_3_0 = function() { }); this.readers['sld'] = { 'UserDefinedSymbolization': function(node, obj) { - this.readers.wms.UserDefinedSymbolization.apply(this, arguments); + var readers = this.readers['http://www.opengis.net/wms']; + readers.UserDefinedSymbolization.apply(this, arguments); // add the two extra attributes var value = node.getAttribute('InlineFeature'); obj['userSymbols'].inlineFeature = parseInt(value, 10) == 1; @@ -95,10 +96,12 @@ ol.parser.ogc.WMSCapabilities_v1_3_0 = function() { obj['userSymbols'].remoteWCS = parseInt(value, 10) == 1; }, 'DescribeLayer': function(node, obj) { - this.readers.wms.DescribeLayer.apply(this, arguments); + var readers = this.readers['http://www.opengis.net/wms']; + readers.DescribeLayer.apply(this, arguments); }, 'GetLegendGraphic': function(node, obj) { - this.readers.wms.GetLegendGraphic.apply(this, arguments); + var readers = this.readers['http://www.opengis.net/wms']; + readers.GetLegendGraphic.apply(this, arguments); } }; }; diff --git a/src/ol/parser/xml.js b/src/ol/parser/xml.js index 269efff7ed..d0df3ab763 100644 --- a/src/ol/parser/xml.js +++ b/src/ol/parser/xml.js @@ -1,5 +1,4 @@ goog.provide('ol.parser.XML'); -goog.require('goog.object'); @@ -7,12 +6,6 @@ goog.require('goog.object'); * @constructor */ ol.parser.XML = function() { - // clone the namespaces object and set all namespace aliases - this.namespaces = goog.object.clone(this.namespaces); - this.namespaceAlias = {}; - for (var alias in this.namespaces) { - this.namespaceAlias[this.namespaces[alias]] = alias; - } }; @@ -30,8 +23,8 @@ ol.parser.XML.prototype.readNode = function(node, obj) { if (!obj) { obj = {}; } - var group = this.readers[node.namespaceURI ? - this.namespaceAlias[node.namespaceURI] : this.defaultPrefix]; + var group = this.readers[node.namespaceURI] || + this.readers[this.defaultNamespaceURI]; if (group) { var local = node.localName || node.nodeName.split(':').pop(); var reader = group[local] || group['*']; From f5c627ab519a25cb5d5bbc6b4442472ff3b0d8cc Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 13 Feb 2013 15:37:33 -0700 Subject: [PATCH 5/9] Only listen once for tile events Assuming browser garbage collection cannot happen while we have listeners in the global registry, we need to listenOnce to avoid memory leaks with the tile queue. --- src/ol/tilequeue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/tilequeue.js b/src/ol/tilequeue.js index 64984ba1a8..c5788df972 100644 --- a/src/ol/tilequeue.js +++ b/src/ol/tilequeue.js @@ -174,7 +174,7 @@ ol.TileQueue.prototype.loadMoreTiles = function() { var tile; while (this.heap_.length > 0 && this.tilesLoading_ < this.maxTilesLoading_) { tile = /** @type {ol.Tile} */ (this.dequeue_()); - goog.events.listen(tile, goog.events.EventType.CHANGE, + goog.events.listenOnce(tile, goog.events.EventType.CHANGE, this.handleTileChange, false, this); tile.load(); ++this.tilesLoading_; From de7a1d8f81df159eecadbf53f8e2e5dcd1775388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 13 Feb 2013 21:50:32 +0100 Subject: [PATCH 6/9] Apply transform matrix to text coords With this commit the transform matrix is applied to each texture coordinate, as opposed to each fragment. This leads to less calculation on the GPU. --- src/ol/renderer/webgl/webgllayerrenderer.js | 2 +- src/ol/renderer/webgl/webglmaprenderer.js | 21 ++++++++++--------- .../renderer/webgl/webgltilelayerrenderer.js | 16 +++++++------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/ol/renderer/webgl/webgllayerrenderer.js b/src/ol/renderer/webgl/webgllayerrenderer.js index 3f8f3c2d17..238462410f 100644 --- a/src/ol/renderer/webgl/webgllayerrenderer.js +++ b/src/ol/renderer/webgl/webgllayerrenderer.js @@ -88,7 +88,7 @@ ol.renderer.webgl.Layer.prototype.getMapRenderer = function() { /** * @return {!goog.vec.Mat4.Number} Matrix. */ -ol.renderer.webgl.Layer.prototype.getMatrix = goog.abstractMethod; +ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = goog.abstractMethod; /** diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index 0af57fa846..7ca920c264 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -48,15 +48,13 @@ ol.renderer.webgl.map.shader.Fragment = function() { '', 'uniform mat4 uColorMatrix;', 'uniform float uOpacity;', - 'uniform mat4 uMatrix;', 'uniform sampler2D uTexture;', '', - 'varying vec2 vTexCoord;', + 'varying vec4 vTexCoord;', '', 'void main(void) {', '', - ' vec4 texCoord = uMatrix * vec4(vTexCoord, 0., 1.);', - ' vec4 texColor = texture2D(uTexture, texCoord.st);', + ' vec4 texColor = texture2D(uTexture, vTexCoord.st);', ' vec4 color = uColorMatrix * vec4(texColor.rgb, 1.);', ' color.a = texColor.a * uOpacity;', '', @@ -80,11 +78,13 @@ ol.renderer.webgl.map.shader.Vertex = function() { 'attribute vec2 aPosition;', 'attribute vec2 aTexCoord;', '', - 'varying vec2 vTexCoord;', + 'uniform mat4 uTexCoordMatrix;', + '', + 'varying vec4 vTexCoord;', '', 'void main(void) {', ' gl_Position = vec4(aPosition, 0., 1.);', - ' vTexCoord = aTexCoord;', + ' vTexCoord = uTexCoordMatrix * vec4(aTexCoord, 0., 1.);', '}' ].join('\n')); }; @@ -157,9 +157,9 @@ ol.renderer.webgl.Map = function(container, map) { * @type {{aPosition: number, * aTexCoord: number, * uColorMatrix: WebGLUniformLocation, - * uMatrix: WebGLUniformLocation, * uOpacity: WebGLUniformLocation, - * uTexture: WebGLUniformLocation}|null} + * uTexture: WebGLUniformLocation, + * uTexCoordMatrix: WebGLUniformLocation}|null} */ this.locations_ = null; @@ -518,7 +518,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { aPosition: gl.getAttribLocation(program, 'aPosition'), aTexCoord: gl.getAttribLocation(program, 'aTexCoord'), uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'), - uMatrix: gl.getUniformLocation(program, 'uMatrix'), + uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'), uOpacity: gl.getUniformLocation(program, 'uOpacity'), uTexture: gl.getUniformLocation(program, 'uTexture') }; @@ -553,7 +553,8 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { } var layerRenderer = this.getLayerRenderer(layer); gl.uniformMatrix4fv( - this.locations_.uMatrix, false, layerRenderer.getMatrix()); + this.locations_.uTexCoordMatrix, false, + layerRenderer.getTexCoordMatrix()); gl.uniformMatrix4fv( this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix()); gl.uniform1f(this.locations_.uOpacity, layer.getOpacity()); diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 27c0cbadab..8f1dab302a 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -139,7 +139,7 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) { * @private * @type {!goog.vec.Mat4.Number} */ - this.matrix_ = goog.vec.Mat4.createNumber(); + this.texCoordMatrix_ = goog.vec.Mat4.createNumber(); /** * @private @@ -224,8 +224,8 @@ ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() { /** * @inheritDoc */ -ol.renderer.webgl.TileLayer.prototype.getMatrix = function() { - return this.matrix_; +ol.renderer.webgl.TileLayer.prototype.getTexCoordMatrix = function() { + return this.texCoordMatrix_; }; @@ -467,21 +467,21 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); this.scheduleExpireCache(frameState, tileSource); - goog.vec.Mat4.makeIdentity(this.matrix_); - goog.vec.Mat4.translate(this.matrix_, + goog.vec.Mat4.makeIdentity(this.texCoordMatrix_); + goog.vec.Mat4.translate(this.texCoordMatrix_, (view2DState.center.x - framebufferExtent.minX) / (framebufferExtent.maxX - framebufferExtent.minX), (view2DState.center.y - framebufferExtent.minY) / (framebufferExtent.maxY - framebufferExtent.minY), 0); - goog.vec.Mat4.rotateZ(this.matrix_, view2DState.rotation); - goog.vec.Mat4.scale(this.matrix_, + goog.vec.Mat4.rotateZ(this.texCoordMatrix_, view2DState.rotation); + goog.vec.Mat4.scale(this.texCoordMatrix_, frameState.size.width * view2DState.resolution / (framebufferExtent.maxX - framebufferExtent.minX), frameState.size.height * view2DState.resolution / (framebufferExtent.maxY - framebufferExtent.minY), 1); - goog.vec.Mat4.translate(this.matrix_, + goog.vec.Mat4.translate(this.texCoordMatrix_, -0.5, -0.5, 0); From b6b493c198bac09834168bdd52b0f42836015446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 14 Feb 2013 11:50:58 +0100 Subject: [PATCH 7/9] Use vec2 for vTexCoord --- src/ol/renderer/webgl/webglmaprenderer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index 7ca920c264..f7a553f3f2 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -50,11 +50,11 @@ ol.renderer.webgl.map.shader.Fragment = function() { 'uniform float uOpacity;', 'uniform sampler2D uTexture;', '', - 'varying vec4 vTexCoord;', + 'varying vec2 vTexCoord;', '', 'void main(void) {', '', - ' vec4 texColor = texture2D(uTexture, vTexCoord.st);', + ' vec4 texColor = texture2D(uTexture, vTexCoord);', ' vec4 color = uColorMatrix * vec4(texColor.rgb, 1.);', ' color.a = texColor.a * uOpacity;', '', @@ -80,11 +80,11 @@ ol.renderer.webgl.map.shader.Vertex = function() { '', 'uniform mat4 uTexCoordMatrix;', '', - 'varying vec4 vTexCoord;', + 'varying vec2 vTexCoord;', '', 'void main(void) {', ' gl_Position = vec4(aPosition, 0., 1.);', - ' vTexCoord = uTexCoordMatrix * vec4(aTexCoord, 0., 1.);', + ' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;', '}' ].join('\n')); }; From 34975428c428335856272d606b45b417e2664d44 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 13 Feb 2013 17:03:06 +0100 Subject: [PATCH 8/9] Change view.rotate params: rotation and optional anchor. --- .../dragrotateandzoominteraction.js | 35 +++++++++--------- src/ol/interaction/dragrotateinteraction.js | 37 +++++++++---------- src/ol/view2d.js | 23 ++++++++++-- 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/ol/interaction/dragrotateandzoominteraction.js b/src/ol/interaction/dragrotateandzoominteraction.js index 9cc3ab89ca..7cf2f7ffa1 100644 --- a/src/ol/interaction/dragrotateandzoominteraction.js +++ b/src/ol/interaction/dragrotateandzoominteraction.js @@ -26,15 +26,15 @@ ol.interaction.DragRotateAndZoom = function(condition) { /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRatio_ = 0; + this.lastAngle_; /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRotation_ = 0; + this.lastMagnitude_; }; goog.inherits(ol.interaction.DragRotateAndZoom, ol.interaction.Drag); @@ -52,15 +52,23 @@ ol.interaction.DragRotateAndZoom.prototype.handleDrag = browserEvent.offsetX - size.width / 2, size.height / 2 - browserEvent.offsetY); var theta = Math.atan2(delta.y, delta.x); - var resolution = this.startRatio_ * delta.magnitude(); + var magnitude = delta.magnitude(); // FIXME works for View2D only var view = map.getView(); goog.asserts.assert(view instanceof ol.View2D); map.requestRenderFrame(); // FIXME the calls to map.rotate and map.zoomToResolution should use // map.withFrozenRendering but an assertion fails :-( - view.rotate(map, this.startRotation_, -theta); - view.zoomToResolution(map, resolution); + if (goog.isDef(this.lastAngle_)) { + var angleDelta = theta - this.lastAngle_; + view.rotate(map, view.getRotation() - angleDelta); + } + this.lastAngle_ = theta; + if (goog.isDef(this.lastMagnitude_)) { + var resolution = this.lastMagnitude_ * (view.getResolution() / magnitude); + view.zoomToResolution(map, resolution); + } + this.lastMagnitude_ = magnitude; }; @@ -70,18 +78,9 @@ ol.interaction.DragRotateAndZoom.prototype.handleDrag = ol.interaction.DragRotateAndZoom.prototype.handleDragStart = function(mapBrowserEvent) { var browserEvent = mapBrowserEvent.browserEvent; - var map = mapBrowserEvent.map; - var view = map.getView().getView2D(); if (this.condition_(browserEvent)) { - var resolution = view.getResolution(); - var size = map.getSize(); - var delta = new goog.math.Vec2( - browserEvent.offsetX - size.width / 2, - size.height / 2 - browserEvent.offsetY); - var theta = Math.atan2(delta.y, delta.x); - this.startRotation_ = view.getRotation() + theta; - this.startRatio_ = resolution / delta.magnitude(); - map.requestRenderFrame(); + this.lastAngle_ = undefined; + this.lastMagnitude_ = undefined; return true; } else { return false; diff --git a/src/ol/interaction/dragrotateinteraction.js b/src/ol/interaction/dragrotateinteraction.js index 048a847957..276fb15c56 100644 --- a/src/ol/interaction/dragrotateinteraction.js +++ b/src/ol/interaction/dragrotateinteraction.js @@ -23,9 +23,9 @@ ol.interaction.DragRotate = function(condition) { /** * @private - * @type {number} + * @type {number|undefined} */ - this.startRotation_ = 0; + this.lastAngle_; }; goog.inherits(ol.interaction.DragRotate, ol.interaction.Drag); @@ -39,14 +39,16 @@ ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) { var map = mapBrowserEvent.map; var size = map.getSize(); var offset = mapBrowserEvent.getPixel(); - var theta = Math.atan2( - size.height / 2 - offset.y, - offset.x - size.width / 2); - // FIXME supports View2D only - var view = map.getView(); - goog.asserts.assert(view instanceof ol.View2D); - map.requestRenderFrame(); - view.rotate(map, this.startRotation_, -theta); + var theta = Math.atan2(size.height / 2 - offset.y, offset.x - size.width / 2); + if (goog.isDef(this.lastAngle_)) { + var delta = theta - this.lastAngle_; + var view = map.getView(); + // FIXME supports View2D only + goog.asserts.assert(view instanceof ol.View2D); + map.requestRenderFrame(); + view.rotate(map, view.getRotation() - delta); + } + this.lastAngle_ = theta; }; @@ -56,18 +58,13 @@ ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) { ol.interaction.DragRotate.prototype.handleDragStart = function(mapBrowserEvent) { var browserEvent = mapBrowserEvent.browserEvent; - var map = mapBrowserEvent.map; - // FIXME supports View2D only - var view = map.getView(); - goog.asserts.assert(view instanceof ol.View2D); if (browserEvent.isMouseActionButton() && this.condition_(browserEvent)) { + var map = mapBrowserEvent.map; + // FIXME supports View2D only + var view = map.getView(); + goog.asserts.assert(view instanceof ol.View2D); map.requestRenderFrame(); - var size = map.getSize(); - var offset = mapBrowserEvent.getPixel(); - var theta = Math.atan2( - size.height / 2 - offset.y, - offset.x - size.width / 2); - this.startRotation_ = view.getRotation() + theta; + this.lastAngle_ = undefined; return true; } else { return false; diff --git a/src/ol/view2d.js b/src/ol/view2d.js index ca726b99f4..ed707f2e74 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -256,11 +256,26 @@ goog.exportProperty( /** * @param {ol.Map} map Map. * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. + * @param {ol.Coordinate=} opt_anchor Anchor coordinate. */ -ol.View2D.prototype.rotate = function(map, rotation, delta) { - rotation = this.constraints_.rotation(rotation, delta); - this.setRotation(rotation); +ol.View2D.prototype.rotate = function(map, rotation, opt_anchor) { + rotation = this.constraints_.rotation(rotation, 0); + if (goog.isDefAndNotNull(opt_anchor)) { + var anchor = opt_anchor; + var oldCenter = /** @type {!ol.Coordinate} */ (this.getCenter()); + var center = new ol.Coordinate( + oldCenter.x - anchor.x, + oldCenter.y - anchor.y); + center.rotate(rotation - this.getRotation()); + center.x += anchor.x; + center.y += anchor.y; + map.withFrozenRendering(function() { + this.setCenter(center); + this.setRotation(rotation); + }, this); + } else { + this.setRotation(rotation); + } }; From 012cb501df86966d3fa2c377a0f10cf180060508 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Fri, 15 Feb 2013 00:33:05 +0100 Subject: [PATCH 9/9] Don't re-lint files that have already passed after a lint failure --- build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.py b/build.py index eb1dd3d6ba..7a5f049e36 100755 --- a/build.py +++ b/build.py @@ -213,7 +213,7 @@ def serve_precommit(t): virtual('lint', 'build/lint-src-timestamp', 'build/lint-spec-timestamp', 'build/check-requires-timestamp') -@target('build/lint-src-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC) +@target('build/lint-src-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC, precious=True) def build_lint_src_timestamp(t): limited_doc_files = [path for path in ifind('externs', 'build/src/external/externs') @@ -288,7 +288,7 @@ def build_check_requires_timestamp(t): t.touch() -@target('build/lint-spec-timestamp', SPEC) +@target('build/lint-spec-timestamp', SPEC, precious=True) def build_lint_spec_timestamp(t): t.run('%(GJSLINT)s', t.newer(SPEC)) t.touch()