diff --git a/build.py b/build.py index dd012dceb4..3c3aa7cb5b 100755 --- a/build.py +++ b/build.py @@ -345,7 +345,8 @@ def examples_star_json(name, match): "api", "observable" ], "compilation_level": "ADVANCED", - "output_wrapper": "// OpenLayers 3. See http://ol3.js.org/\n(function(){%output%})();", + "warning_level": "VERBOSE", + "output_wrapper": "(function(){%output%})();", "use_types_for_optimization": True, "manage_closure_dependencies": True } diff --git a/config/examples-all.json b/config/examples-all.json index f5b300e3ca..12e017f984 100644 --- a/config/examples-all.json +++ b/config/examples-all.json @@ -68,7 +68,8 @@ "api", "observable" ], "compilation_level": "ADVANCED", - "output_wrapper": "// OpenLayers 3. See http://ol3js.org/\n(function(){%output%})();", + "warning_level": "VERBOSE", + "output_wrapper": "(function(){%output%})();", "use_types_for_optimization": true, "manage_closure_dependencies": true diff --git a/config/ol.json b/config/ol.json index 0740a4c8d5..1e86764780 100644 --- a/config/ol.json +++ b/config/ol.json @@ -58,6 +58,7 @@ "api", "observable" ], "compilation_level": "ADVANCED", + "warning_level": "VERBOSE", "output_wrapper": "(function(){%output%})();", "use_types_for_optimization": true, "manage_closure_dependencies": true diff --git a/css/ol.css b/css/ol.css index 3ead609e85..4b87bdbfe8 100644 --- a/css/ol.css +++ b/css/ol.css @@ -131,65 +131,6 @@ button.ol-full-screen-true:after { content: "\00d7"; } -/* invisible but not hidden */ -.ol-has-tooltip [role=tooltip] { - position: absolute; - clip: rect(1px 1px 1px 1px); /* < IE8 */ - clip: rect(1px, 1px, 1px, 1px); - padding: 0; - border: 0; - height: 1px; - width: 1px; - overflow: hidden; - font-weight: normal; - font-size: 14px; - text-shadow: 0 0 2px #fff; -} - -/* show a tooltip offset to below and right */ -.ol-has-tooltip:hover [role=tooltip], .ol-has-tooltip:focus [role=tooltip] { - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; - clip: auto; - padding: 0 .4em; - font-size: .8em; - height: 1.2em; - width: auto; - line-height: 1.2em; - z-index: 1100; - max-height: 100px; - white-space: nowrap; - display: inline-block; - background: #FFF; - background: rgba(255,255,255,0.6); - color: #000; - border: 3px solid rgba(255,255,255,0); - border-left-width: 0; - border-radius: 0 4px 4px 0; - bottom: .3em; - left: 2.2em; -} -.ol-touch .ol-has-tooltip:hover [role=tooltip], -.ol-touch .ol-has-tooltip:focus [role=tooltip] { - display: none; -} -.ol-zoom .ol-has-tooltip:hover [role=tooltip], -.ol-zoom .ol-has-tooltip:focus [role=tooltip] { - top: 1.1em; -} -.ol-rotate .ol-has-tooltip:hover [role=tooltip], -.ol-rotate .ol-has-tooltip:focus [role=tooltip], -.ol-attribution .ol-has-tooltip:hover [role=tooltip], -.ol-attribution .ol-has-tooltip:focus [role=tooltip], -.ol-full-screen .ol-has-tooltip:hover [role=tooltip], -.ol-full-screen .ol-has-tooltip:focus [role=tooltip] { - right: 2.2em; - left: auto; - border-radius: 4px 0 0 4px; - border-left-width: 3px; - border-right-width: 0; -} .ol-attribution { text-align: right; @@ -222,7 +163,6 @@ button.ol-full-screen-true:after { .ol-attribution ul, .ol-attribution button { display: inline-block; } -.ol-attribution:not(.ol-collapsed) button:hover [role=tooltip], .ol-attribution.ol-collapsed ul { display: none; } @@ -284,8 +224,7 @@ button.ol-full-screen-true:after { .ol-control button, .ol-attribution, -.ol-scale-line-inner, -.ol-has-tooltip [role=tooltip] { +.ol-scale-line-inner { font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif; } @@ -314,7 +253,6 @@ button.ol-full-screen-true:after { left: 2px; position: absolute; } -.ol-overviewmap:not(.ol-collapsed) button:hover [role=tooltip], .ol-overviewmap.ol-collapsed .ol-overviewmap-map, .ol-overviewmap.ol-uncollapsible button { display: none; diff --git a/examples/button-title.html b/examples/button-title.html new file mode 100644 index 0000000000..1247a7accd --- /dev/null +++ b/examples/button-title.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + ol3 custom tooltips example + + + + + +
+ +
+
+
+
+
+ +
+
+

Custom tooltips

+

+ This example shows how to customize the buttons tooltips with + Bootstrap. +

+
+

+ See the button-title.js source to see how this is done. +

+
+
+ custom, tooltip +
+
+
+
+ + + + + + + + + diff --git a/examples/button-title.js b/examples/button-title.js new file mode 100644 index 0000000000..b7ae541d85 --- /dev/null +++ b/examples/button-title.js @@ -0,0 +1,27 @@ +goog.require('ol.Map'); +goog.require('ol.View'); +goog.require('ol.layer.Tile'); +goog.require('ol.source.OSM'); + +var map = new ol.Map({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }) + ], + renderer: exampleNS.getRendererFromQueryString(), + target: 'map', + view: new ol.View({ + center: [-8730000, 5930000], + rotation: Math.PI / 5, + zoom: 8 + }) +}); + + +$('.ol-zoom-in, .ol-zoom-out').tooltip({ + placement: 'right' +}); +$('.ol-rotate-reset, .ol-attribution button[title]').tooltip({ + placement: 'left' +}); diff --git a/examples/wmts-hidpi.js b/examples/wmts-hidpi.js index 682a08c5fb..52a0d7b669 100644 --- a/examples/wmts-hidpi.js +++ b/examples/wmts-hidpi.js @@ -29,7 +29,7 @@ var source = new ol.source.WMTS({ style: 'normal', matrixSet: 'google3857', urls: urls, - requestEncoding: /** @type {ol.source.WMTSRequestEncoding} */ ('REST'), + requestEncoding: 'REST', tileGrid: new ol.tilegrid.WMTS({ origin: [-20037508.3428, 20037508.3428], resolutions: [ diff --git a/externs/olx.js b/externs/olx.js index 57e5d11ac5..f7bcedf399 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -1740,6 +1740,12 @@ olx.format.WFSWriteGetFeatureOptions.prototype.maxFeatures; */ olx.format.WFSWriteGetFeatureOptions.prototype.geometryName; +/** + * GML format to use within the WFS format. + * @type {ol.format.GMLBase|undefined} + * @api + */ +olx.format.WFSWriteGetFeatureOptions.prototype.gmlFormat; /** * Extent to use for the BBOX filter. @@ -3857,6 +3863,7 @@ olx.source.IGCOptions.prototype.urls; * projection: ol.proj.ProjectionLike, * ratio: (number|undefined), * resolutions: (Array.|undefined), + * imageLoadFunction: (ol.ImageLoadFunctionType|undefined), * params: (Object|undefined)}} * @api */ @@ -3929,6 +3936,15 @@ olx.source.ImageMapGuideOptions.prototype.ratio; olx.source.ImageMapGuideOptions.prototype.resolutions; + +/** + * Optional function to load an image given a URL. + * @type {ol.TileLoadFunctionType|undefined} + * @api + */ +olx.source.ImageMapGuideOptions.prototype.imageLoadFunction; + + /** * Additional parameters. * @type {Object|undefined} @@ -4368,6 +4384,7 @@ olx.source.ImageVectorOptions.prototype.style; * hidpi: (boolean|undefined), * serverType: (ol.source.wms.ServerType|string|undefined), * logo: (string|olx.LogoOptions|undefined), + * imageLoadFunction: (ol.ImageLoadFunctionType|undefined), * params: Object., * projection: ol.proj.ProjectionLike, * ratio: (number|undefined), @@ -4412,6 +4429,14 @@ olx.source.ImageWMSOptions.prototype.hidpi; olx.source.ImageWMSOptions.prototype.serverType; +/** + * Optional function to load an image given a URL. + * @type {ol.TileLoadFunctionType|undefined} + * @api + */ +olx.source.ImageWMSOptions.prototype.imageLoadFunction; + + /** * Logo. * @type {string|olx.LogoOptions|undefined} @@ -4528,6 +4553,7 @@ olx.source.StamenOptions.prototype.url; * crossOrigin: (null|string|undefined), * imageExtent: (ol.Extent), * imageSize: (ol.Size|undefined), + * imageLoadFunction: (ol.ImageLoadFunctionType|undefined), * logo: (string|olx.LogoOptions|undefined), * projection: ol.proj.ProjectionLike, * url: string}} @@ -4568,6 +4594,14 @@ olx.source.ImageStaticOptions.prototype.imageExtent; olx.source.ImageStaticOptions.prototype.imageSize; +/** + * Optional function to load an image given a URL. + * @type {ol.TileLoadFunctionType|undefined} + * @api + */ +olx.source.ImageStaticOptions.prototype.imageLoadFunction; + + /** * Logo. * @type {string|olx.LogoOptions|undefined} @@ -4656,7 +4690,8 @@ olx.source.ServerVectorOptions.prototype.projection; /** * @typedef {{crossOrigin: (null|string|undefined), * tileLoadFunction: (ol.TileLoadFunctionType|undefined), - * url: string}} + * url: string, + * wrapX: (boolean|undefined)}} * @api */ olx.source.TileJSONOptions; @@ -4686,6 +4721,14 @@ olx.source.TileJSONOptions.prototype.tileLoadFunction; olx.source.TileJSONOptions.prototype.url; +/** + * Whether to wrap the world horizontally. Default is `true`. + * @type {boolean|undefined} + * @api + */ +olx.source.TileJSONOptions.prototype.wrapX; + + /** * @typedef {{attributions: (Array.|undefined), * params: Object., @@ -4987,7 +5030,7 @@ olx.source.StaticVectorOptions.prototype.urls; * logo: (string|olx.LogoOptions|undefined), * tileGrid: ol.tilegrid.WMTS, * projection: ol.proj.ProjectionLike, - * requestEncoding: (ol.source.WMTSRequestEncoding|undefined), + * requestEncoding: (ol.source.WMTSRequestEncoding|string|undefined), * layer: string, * style: string, * tilePixelRatio: (number|undefined), @@ -5048,8 +5091,8 @@ olx.source.WMTSOptions.prototype.projection; /** - * Request encoding. - * @type {ol.source.WMTSRequestEncoding|undefined} + * Request encoding. Default is `KVP`. + * @type {ol.source.WMTSRequestEncoding|string|undefined} * @api */ olx.source.WMTSOptions.prototype.requestEncoding; @@ -5481,7 +5524,8 @@ olx.style.IconOptions.prototype.crossOrigin; /** * Image object for the icon. If the `src` option is not provided then the - * provided image must already be loaded. + * provided image must already be loaded. And in that case, it is required + * to provide the size of the image, with the `size` option. * @type {Image|undefined} * @api */ @@ -5546,7 +5590,9 @@ olx.style.IconOptions.prototype.rotation; /** - * Icon size in pixel. + * Icon size in pixel. Can be used together with `offset` to define the + * sub-rectangle to use from the origin (sprite) icon image. Also, setting + * the `size` is required if `img` is set and `src` is not. * @type {ol.Size|undefined} * @api */ @@ -5561,6 +5607,86 @@ olx.style.IconOptions.prototype.size; olx.style.IconOptions.prototype.src; +/** + * @typedef {{fill: (ol.style.Fill|undefined), + * points: number, + * radius: number, + * radius2: number, + * angle: number, + * snapToPixel: (boolean|undefined), + * stroke: (ol.style.Stroke|undefined)}} + * @api + */ +olx.style.RegularShapeOptions; + + +/** + * Fill style. + * @type {ol.style.Fill|undefined} + * @api + */ +olx.style.RegularShapeOptions.prototype.fill; + + +/** + * Number of points for stars and regular polygons. In case of a polygon, the + * number of points is the number of sides. + * @type {number} + * @api + */ +olx.style.RegularShapeOptions.prototype.points; + + +/** + * Shape radius. + * @type {number} + * @api + */ +olx.style.RegularShapeOptions.prototype.radius; + + +/** + * Shape secondary radius for drawing stars. If radius 2 is equal to radius, + * the regular shape will be a regular polygon instead of a star. + * Default value is equal to radius. + * @type {number} + * @api + */ +olx.style.RegularShapeOptions.prototype.radius2; + + +/** + * Shape's rotation in radians. A value of 0 will have one of the shape's point + * facing up. + * Default value is 0. + * @type {number} + * @api + */ +olx.style.RegularShapeOptions.prototype.angle; + + +/** + * If `true` integral numbers of pixels are used as the X and Y pixel + * coordinate when drawing the shape in the output canvas. If `false` + * fractional numbers may be used. Using `true` allows for "sharp" + * rendering (no blur), while using `false` allows for "accurate" + * rendering. Note that accuracy is important if the shape's + * position is animated. Without it, the shape may jitter noticeably. + * Default value is `true`. + * @type {boolean|undefined} + * @api + */ +olx.style.RegularShapeOptions.prototype.snapToPixel; + + +/** + * Stroke style. + * @type {ol.style.Stroke|undefined} + * @api + */ +olx.style.RegularShapeOptions.prototype.stroke; + + /** * @typedef {{color: (ol.Color|string|undefined), * lineCap: (string|undefined), diff --git a/src/ol/control/attributioncontrol.js b/src/ol/control/attributioncontrol.js index dcafa64c51..c14051509c 100644 --- a/src/ol/control/attributioncontrol.js +++ b/src/ol/control/attributioncontrol.js @@ -69,9 +69,6 @@ ol.control.Attribution = function(opt_options) { var tipLabel = goog.isDef(options.tipLabel) ? options.tipLabel : 'Attributions'; - var tip = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, tipLabel); /** * @private @@ -96,10 +93,9 @@ ol.control.Attribution = function(opt_options) { */ this.labelSpan_ = label; var button = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': 'ol-has-tooltip', - 'type': 'button' + 'type': 'button', + 'title': tipLabel }, this.labelSpan_); - goog.dom.appendChild(button, tip); var buttonHandler = new ol.pointer.PointerEventHandler(button); this.registerDisposable(buttonHandler); @@ -115,12 +111,12 @@ ol.control.Attribution = function(opt_options) { this.blur(); }, false); - var element = goog.dom.createDom(goog.dom.TagName.DIV, { - 'class': className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + - ol.css.CLASS_CONTROL + - (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') + - (this.collapsible_ ? '' : ' ol-uncollapsible') - }, this.ulElement_, button); + var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + + ol.css.CLASS_CONTROL + + (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') + + (this.collapsible_ ? '' : ' ol-uncollapsible'); + var element = goog.dom.createDom(goog.dom.TagName.DIV, + cssClasses, this.ulElement_, button); goog.base(this, { element: element, diff --git a/src/ol/control/fullscreencontrol.js b/src/ol/control/fullscreencontrol.js index f01402efb2..6fe367bfaa 100644 --- a/src/ol/control/fullscreencontrol.js +++ b/src/ol/control/fullscreencontrol.js @@ -40,16 +40,11 @@ ol.control.FullScreen = function(opt_options) { var tipLabel = goog.isDef(options.tipLabel) ? options.tipLabel : 'Toggle full-screen'; - var tip = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, tipLabel); - var button = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': this.cssClassName_ + '-' + goog.dom.fullscreen.isFullScreen() + - ' ol-has-tooltip', - 'type': 'button' + 'class': this.cssClassName_ + '-' + goog.dom.fullscreen.isFullScreen(), + 'type': 'button', + 'title': tipLabel }); - goog.dom.appendChild(button, tip); var buttonHandler = new ol.pointer.PointerEventHandler(button); this.registerDisposable(buttonHandler); goog.events.listen(buttonHandler, @@ -69,7 +64,7 @@ ol.control.FullScreen = function(opt_options) { this.handleFullScreenChange_, false, this); var cssClasses = this.cssClassName_ + ' ' + ol.css.CLASS_UNSELECTABLE + - ' ' + ol.css.CLASS_CONTROL + + ' ' + ol.css.CLASS_CONTROL + ' ' + (!goog.dom.fullscreen.isSupported() ? ol.css.CLASS_UNSUPPORTED : ''); var element = goog.dom.createDom(goog.dom.TagName.DIV, cssClasses, button); diff --git a/src/ol/control/mousepositioncontrol.js b/src/ol/control/mousepositioncontrol.js index 05fb83d751..03264ef6f8 100644 --- a/src/ol/control/mousepositioncontrol.js +++ b/src/ol/control/mousepositioncontrol.js @@ -46,9 +46,7 @@ ol.control.MousePosition = function(opt_options) { var className = goog.isDef(options.className) ? options.className : 'ol-mouse-position'; - var element = goog.dom.createDom(goog.dom.TagName.DIV, { - 'class': className - }); + var element = goog.dom.createDom(goog.dom.TagName.DIV, className); goog.base(this, { element: element, diff --git a/src/ol/control/overviewmapcontrol.js b/src/ol/control/overviewmapcontrol.js index 3e2a6d9ae0..0e8da6cdc8 100644 --- a/src/ol/control/overviewmapcontrol.js +++ b/src/ol/control/overviewmapcontrol.js @@ -57,9 +57,6 @@ ol.control.OverviewMap = function(opt_options) { var tipLabel = goog.isDef(options.tipLabel) ? options.tipLabel : 'Overview map'; - var tip = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, tipLabel); /** * @private @@ -83,10 +80,9 @@ ol.control.OverviewMap = function(opt_options) { */ this.labelSpan_ = label; var button = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': 'ol-has-tooltip', - 'type': 'button' + 'type': 'button', + 'title': tipLabel }, this.labelSpan_); - goog.dom.appendChild(button, tip); var buttonHandler = new ol.pointer.PointerEventHandler(button); this.registerDisposable(buttonHandler); @@ -138,12 +134,12 @@ ol.control.OverviewMap = function(opt_options) { }); this.ovmap_.addOverlay(this.boxOverlay_); - var element = goog.dom.createDom(goog.dom.TagName.DIV, { - 'class': className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + - ol.css.CLASS_CONTROL + - (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') + - (this.collapsible_ ? '' : ' ol-uncollapsible') - }, ovmapDiv, button); + var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + + ol.css.CLASS_CONTROL + + (this.collapsed_ && this.collapsible_ ? ' ol-collapsed' : '') + + (this.collapsible_ ? '' : ' ol-uncollapsible'); + var element = goog.dom.createDom(goog.dom.TagName.DIV, + cssClasses, ovmapDiv, button); goog.base(this, { element: element, diff --git a/src/ol/control/rotatecontrol.js b/src/ol/control/rotatecontrol.js index 0888b36cf9..60c7823cae 100644 --- a/src/ol/control/rotatecontrol.js +++ b/src/ol/control/rotatecontrol.js @@ -38,19 +38,16 @@ ol.control.Rotate = function(opt_options) { * @private */ this.label_ = goog.dom.createDom(goog.dom.TagName.SPAN, - { 'class': 'ol-compass' }, - goog.isDef(options.label) ? options.label : '\u21E7'); + 'ol-compass', goog.isDef(options.label) ? options.label : '\u21E7'); var tipLabel = goog.isDef(options.tipLabel) ? options.tipLabel : 'Reset rotation'; - var tip = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, tipLabel); var button = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': className + '-reset ol-has-tooltip', - 'type' : 'button' - }, tip, this.label_); + 'class': className + '-reset', + 'type' : 'button', + 'title': tipLabel + }, this.label_); var handler = new ol.pointer.PointerEventHandler(button); this.registerDisposable(handler); diff --git a/src/ol/control/scalelinecontrol.js b/src/ol/control/scalelinecontrol.js index 2e3eb4e39d..cf2777df2b 100644 --- a/src/ol/control/scalelinecontrol.js +++ b/src/ol/control/scalelinecontrol.js @@ -66,17 +66,15 @@ ol.control.ScaleLine = function(opt_options) { * @private * @type {Element} */ - this.innerElement_ = goog.dom.createDom(goog.dom.TagName.DIV, { - 'class': className + '-inner' - }); + this.innerElement_ = goog.dom.createDom(goog.dom.TagName.DIV, + className + '-inner'); /** * @private * @type {Element} */ - this.element_ = goog.dom.createDom(goog.dom.TagName.DIV, { - 'class': className + ' ' + ol.css.CLASS_UNSELECTABLE - }, this.innerElement_); + this.element_ = goog.dom.createDom(goog.dom.TagName.DIV, + className + ' ' + ol.css.CLASS_UNSELECTABLE, this.innerElement_); /** * @private diff --git a/src/ol/control/zoomcontrol.js b/src/ol/control/zoomcontrol.js index c0606138c9..5d613a7788 100644 --- a/src/ol/control/zoomcontrol.js +++ b/src/ol/control/zoomcontrol.js @@ -41,13 +41,11 @@ ol.control.Zoom = function(opt_options) { var zoomOutTipLabel = goog.isDef(options.zoomOutTipLabel) ? options.zoomOutTipLabel : 'Zoom out'; - var tTipZoomIn = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, zoomInTipLabel); var inElement = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': className + '-in ol-has-tooltip', - 'type' : 'button' - }, tTipZoomIn, zoomInLabel); + 'class': className + '-in', + 'type' : 'button', + 'title': zoomInTipLabel + }, zoomInLabel); var inElementHandler = new ol.pointer.PointerEventHandler(inElement); this.registerDisposable(inElementHandler); @@ -65,13 +63,11 @@ ol.control.Zoom = function(opt_options) { this.blur(); }, false); - var tTipsZoomOut = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, zoomOutTipLabel); var outElement = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': className + '-out ol-has-tooltip', - 'type' : 'button' - }, tTipsZoomOut, zoomOutLabel); + 'class': className + '-out', + 'type' : 'button', + 'title': zoomOutTipLabel + }, zoomOutLabel); var outElementHandler = new ol.pointer.PointerEventHandler(outElement); this.registerDisposable(outElementHandler); diff --git a/src/ol/control/zoomtoextentcontrol.js b/src/ol/control/zoomtoextentcontrol.js index 7f92fe8ae1..6f79e2ed7b 100644 --- a/src/ol/control/zoomtoextentcontrol.js +++ b/src/ol/control/zoomtoextentcontrol.js @@ -35,14 +35,10 @@ ol.control.ZoomToExtent = function(opt_options) { var tipLabel = goog.isDef(options.tipLabel) ? options.tipLabel : 'Fit to extent'; - var tip = goog.dom.createDom(goog.dom.TagName.SPAN, { - 'role' : 'tooltip' - }, tipLabel); var button = goog.dom.createDom(goog.dom.TagName.BUTTON, { - 'class': 'ol-has-tooltip', - 'type': 'button' + 'type': 'button', + 'title': tipLabel }); - goog.dom.appendChild(button, tip); var buttonHandler = new ol.pointer.PointerEventHandler(button); this.registerDisposable(buttonHandler); diff --git a/src/ol/format/gml/gml2.js b/src/ol/format/gml/gml2.js new file mode 100644 index 0000000000..f1564bc505 --- /dev/null +++ b/src/ol/format/gml/gml2.js @@ -0,0 +1,218 @@ +goog.provide('ol.format.GML2'); + +goog.require('goog.asserts'); +goog.require('goog.dom'); +goog.require('goog.dom.NodeType'); +goog.require('goog.object'); +goog.require('ol.extent'); +goog.require('ol.format.GML'); +goog.require('ol.format.GMLBase'); +goog.require('ol.format.XSD'); +goog.require('ol.proj'); +goog.require('ol.xml'); + + + +/** + * @classdesc + * Feature format for reading and writing data in the GML format, + * version 2.1.2. + * + * @constructor + * @param {olx.format.GMLOptions=} opt_options Optional configuration object. + * @extends {ol.format.GMLBase} + * @api + */ +ol.format.GML2 = function(opt_options) { + var options = /** @type {olx.format.GMLOptions} */ + (goog.isDef(opt_options) ? opt_options : {}); + + goog.base(this, options); + + /** + * @inheritDoc + */ + this.schemaLocation = goog.isDef(options.schemaLocation) ? + options.schemaLocation : ol.format.GML2.schemaLocation_; + +}; +goog.inherits(ol.format.GML2, ol.format.GMLBase); + + +/** + * @const + * @type {string} + * @private + */ +ol.format.GML2.schemaLocation_ = 'http://www.opengis.net/gml ' + + 'http://schemas.opengis.net/gml/2.1.2/feature.xsd'; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.|undefined} Flat coordinates. + */ +ol.format.GML2.prototype.readFlatCoordinates_ = function(node, objectStack) { + var s = ol.xml.getAllTextContent(node, false).replace(/^\s*|\s*$/g, ''); + var context = objectStack[0]; + goog.asserts.assert(goog.isObject(context)); + var containerSrs = goog.object.get(context, 'srsName'); + var containerDimension = node.parentNode.getAttribute('srsDimension'); + var axisOrientation = 'enu'; + if (!goog.isNull(containerSrs)) { + var proj = ol.proj.get(containerSrs); + axisOrientation = proj.getAxisOrientation(); + } + var coords = s.split(/[\s,]+/); + // The "dimension" attribute is from the GML 3.0.1 spec. + var dim = 2; + if (!goog.isNull(node.getAttribute('srsDimension'))) { + dim = ol.format.XSD.readNonNegativeIntegerString( + node.getAttribute('srsDimension')); + } else if (!goog.isNull(node.getAttribute('dimension'))) { + dim = ol.format.XSD.readNonNegativeIntegerString( + node.getAttribute('dimension')); + } else if (!goog.isNull(containerDimension)) { + dim = ol.format.XSD.readNonNegativeIntegerString(containerDimension); + } + var x, y, z; + var flatCoordinates = []; + for (var i = 0, ii = coords.length; i < ii; i += dim) { + x = parseFloat(coords[i]); + y = parseFloat(coords[i + 1]); + z = (dim === 3) ? parseFloat(coords[i + 2]) : 0; + if (axisOrientation.substr(0, 2) === 'en') { + flatCoordinates.push(x, y, z); + } else { + flatCoordinates.push(y, x, z); + } + } + return flatCoordinates; +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {ol.Extent|undefined} Envelope. + */ +ol.format.GML2.prototype.readBox_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Box'); + var flatCoordinates = ol.xml.pushParseAndPop( + /** @type {Array.} */ ([null]), + this.BOX_PARSERS_, node, objectStack, this); + return ol.extent.createOrUpdate(flatCoordinates[1][0], + flatCoordinates[1][1], flatCoordinates[1][3], + flatCoordinates[1][4]); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GML2.prototype.innerBoundaryIsParser_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'innerBoundaryIs'); + var flatLinearRing = ol.xml.pushParseAndPop( + /** @type {Array.|undefined} */ (undefined), + this.RING_PARSERS, node, objectStack, this); + if (goog.isDef(flatLinearRing)) { + var flatLinearRings = /** @type {Array.>} */ + (objectStack[objectStack.length - 1]); + goog.asserts.assert(goog.isArray(flatLinearRings)); + goog.asserts.assert(flatLinearRings.length > 0); + flatLinearRings.push(flatLinearRing); + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GML2.prototype.outerBoundaryIsParser_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'outerBoundaryIs'); + var flatLinearRing = ol.xml.pushParseAndPop( + /** @type {Array.|undefined} */ (undefined), + this.RING_PARSERS, node, objectStack, this); + if (goog.isDef(flatLinearRing)) { + var flatLinearRings = /** @type {Array.>} */ + (objectStack[objectStack.length - 1]); + goog.asserts.assert(goog.isArray(flatLinearRings)); + goog.asserts.assert(flatLinearRings.length > 0); + flatLinearRings[0] = flatLinearRing; + } +}; + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'coordinates': ol.xml.makeReplacer( + ol.format.GML2.prototype.readFlatCoordinates_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'innerBoundaryIs': ol.format.GML2.prototype.innerBoundaryIsParser_, + 'outerBoundaryIs': ol.format.GML2.prototype.outerBoundaryIsParser_ + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML2.prototype.BOX_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'coordinates': ol.xml.makeArrayPusher( + ol.format.GML2.prototype.readFlatCoordinates_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML2.prototype.GEOMETRY_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint), + 'MultiPoint': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readMultiPoint), + 'LineString': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readLineString), + 'MultiLineString': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readMultiLineString), + 'LinearRing' : ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readLinearRing), + 'Polygon': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPolygon), + 'MultiPolygon': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readMultiPolygon), + 'Box': ol.xml.makeReplacer(ol.format.GML2.prototype.readBox_) + } +}); diff --git a/src/ol/format/gmlformat.js b/src/ol/format/gml/gml3.js similarity index 53% rename from src/ol/format/gmlformat.js rename to src/ol/format/gml/gml3.js index 9f7e2dc6d9..fc53a3bdde 100644 --- a/src/ol/format/gmlformat.js +++ b/src/ol/format/gml/gml3.js @@ -1,24 +1,20 @@ -// FIXME Envelopes should not be treated as geometries! readEnvelope_ is part -// of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect -// envelopes/extents, only geometries! goog.provide('ol.format.GML'); +goog.provide('ol.format.GML3'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); -goog.require('goog.string'); goog.require('ol.Feature'); goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.format.Feature'); -goog.require('ol.format.XMLFeature'); +goog.require('ol.format.GMLBase'); goog.require('ol.format.XSD'); goog.require('ol.geom.Geometry'); goog.require('ol.geom.LineString'); goog.require('ol.geom.LinearRing'); goog.require('ol.geom.MultiLineString'); -goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); @@ -29,36 +25,21 @@ goog.require('ol.xml'); /** * @classdesc - * Feature format for reading and writing data in the GML format. + * Feature format for reading and writing data in the GML format + * version 3.1.1. * Currently only supports GML 3.1.1 Simple Features profile. * * @constructor * @param {olx.format.GMLOptions=} opt_options * Optional configuration object. - * @extends {ol.format.XMLFeature} - * @api stable + * @extends {ol.format.GMLBase} + * @api */ -ol.format.GML = function(opt_options) { +ol.format.GML3 = function(opt_options) { var options = /** @type {olx.format.GMLOptions} */ (goog.isDef(opt_options) ? opt_options : {}); - /** - * @private - * @type {string} - */ - this.featureType_ = options.featureType; - - /** - * @private - * @type {string} - */ - this.featureNS_ = options.featureNS; - - /** - * @private - * @type {string} - */ - this.srsName_ = options.srsName; + goog.base(this, options); /** * @private @@ -89,15 +70,13 @@ ol.format.GML = function(opt_options) { options.multiSurface : true; /** - * @private - * @type {string} + * @inheritDoc */ - this.schemaLocation_ = goog.isDef(options.schemaLocation) ? - options.schemaLocation : ol.format.GML.schemaLocation_; + this.schemaLocation = goog.isDef(options.schemaLocation) ? + options.schemaLocation : ol.format.GML3.schemaLocation_; - goog.base(this); }; -goog.inherits(ol.format.GML, ol.format.XMLFeature); +goog.inherits(ol.format.GML3, ol.format.GMLBase); /** @@ -105,194 +84,23 @@ goog.inherits(ol.format.GML, ol.format.XMLFeature); * @type {string} * @private */ -ol.format.GML.schemaLocation_ = 'http://www.opengis.net/gml ' + +ol.format.GML3.schemaLocation_ = 'http://www.opengis.net/gml ' + 'http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/' + '1.0.0/gmlsf.xsd'; -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Array.} Features. - * @private - */ -ol.format.GML.readFeatures_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - var localName = ol.xml.getLocalName(node); - var features; - if (localName == 'FeatureCollection') { - features = ol.xml.pushParseAndPop(null, - ol.format.GML.FEATURE_COLLECTION_PARSERS, node, objectStack); - } else if (localName == 'featureMembers' || localName == 'featureMember') { - var context = objectStack[0]; - goog.asserts.assert(goog.isObject(context)); - var featureType = goog.object.get(context, 'featureType'); - if (!goog.isDef(featureType) && !goog.isNull(node.firstElementChild)) { - var member = node.firstElementChild; - featureType = member.nodeName.split(':').pop(); - goog.object.set(context, 'featureType', featureType); - goog.object.set(context, 'featureNS', member.namespaceURI); - } - var parsers = {}; - var parsersNS = {}; - parsers[featureType] = (localName == 'featureMembers') ? - ol.xml.makeArrayPusher(ol.format.GML.readFeature_) : - ol.xml.makeReplacer(ol.format.GML.readFeature_); - parsersNS[goog.object.get(context, 'featureNS')] = parsers; - features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); - } - if (!goog.isDef(features)) { - features = []; - } - return features; -}; - - -/** - * @type {Object.>} - */ -ol.format.GML.FEATURE_COLLECTION_PARSERS = { - 'http://www.opengis.net/gml': { - 'featureMember': ol.xml.makeArrayPusher(ol.format.GML.readFeatures_), - 'featureMembers': ol.xml.makeReplacer(ol.format.GML.readFeatures_) - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {ol.geom.Geometry|undefined} Geometry. - */ -ol.format.GML.readGeometry = function(node, objectStack) { - var context = objectStack[0]; - goog.asserts.assert(goog.isObject(context)); - goog.object.set(context, 'srsName', - node.firstElementChild.getAttribute('srsName')); - var geometry = ol.xml.pushParseAndPop(/** @type {ol.geom.Geometry} */(null), - ol.format.GML.GEOMETRY_PARSERS_, node, objectStack); - if (goog.isDefAndNotNull(geometry)) { - return /** @type {ol.geom.Geometry} */ ( - ol.format.Feature.transformWithOptions(geometry, false, context)); - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {ol.Feature} Feature. - * @private - */ -ol.format.GML.readFeature_ = function(node, objectStack) { - var n; - var fid = node.getAttribute('fid') || - ol.xml.getAttributeNS(node, 'http://www.opengis.net/gml', 'id'); - var values = {}, geometryName; - for (n = node.firstElementChild; !goog.isNull(n); - n = n.nextElementSibling) { - // Assume attribute elements have one child node and that the child - // is a text node. Otherwise assume it is a geometry node. - if (n.childNodes.length === 0 || - (n.childNodes.length === 1 && - n.firstChild.nodeType === 3)) { - var value = ol.xml.getAllTextContent(n, false); - if (goog.string.isEmpty(value)) { - value = undefined; - } - values[ol.xml.getLocalName(n)] = value; - } else { - geometryName = ol.xml.getLocalName(n); - values[geometryName] = ol.format.GML.readGeometry(n, objectStack); - } - } - var feature = new ol.Feature(values); - if (goog.isDef(geometryName)) { - feature.setGeometryName(geometryName); - } - if (fid) { - feature.setId(fid); - } - return feature; -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.Point|undefined} Point. - */ -ol.format.GML.readPoint_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'Point'); - var flatCoordinates = - ol.format.GML.readFlatCoordinatesFromNode_(node, objectStack); - if (goog.isDefAndNotNull(flatCoordinates)) { - var point = new ol.geom.Point(null); - goog.asserts.assert(flatCoordinates.length == 3); - point.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); - return point; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.MultiPoint|undefined} MultiPoint. - */ -ol.format.GML.readMultiPoint_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'MultiPoint'); - var coordinates = ol.xml.pushParseAndPop( - /** @type {Array.>} */ ([]), - ol.format.GML.MULTIPOINT_PARSERS_, node, objectStack); - if (goog.isDef(coordinates)) { - return new ol.geom.MultiPoint(coordinates); - } else { - return undefined; - } -}; - - /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private * @return {ol.geom.MultiLineString|undefined} MultiLineString. */ -ol.format.GML.readMultiLineString_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'MultiLineString'); - var lineStrings = ol.xml.pushParseAndPop( - /** @type {Array.} */ ([]), - ol.format.GML.MULTILINESTRING_PARSERS_, node, objectStack); - if (goog.isDef(lineStrings)) { - var multiLineString = new ol.geom.MultiLineString(null); - multiLineString.setLineStrings(lineStrings); - return multiLineString; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.MultiLineString|undefined} MultiLineString. - */ -ol.format.GML.readMultiCurve_ = function(node, objectStack) { +ol.format.GML3.prototype.readMultiCurve_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'MultiCurve'); var lineStrings = ol.xml.pushParseAndPop( /** @type {Array.} */ ([]), - ol.format.GML.MULTICURVE_PARSERS_, node, objectStack); + this.MULTICURVE_PARSERS_, node, objectStack, this); if (goog.isDef(lineStrings)) { var multiLineString = new ol.geom.MultiLineString(null); multiLineString.setLineStrings(lineStrings); @@ -309,34 +117,12 @@ ol.format.GML.readMultiCurve_ = function(node, objectStack) { * @private * @return {ol.geom.MultiPolygon|undefined} MultiPolygon. */ -ol.format.GML.readMultiSurface_ = function(node, objectStack) { +ol.format.GML3.prototype.readMultiSurface_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'MultiSurface'); var polygons = ol.xml.pushParseAndPop( /** @type {Array.} */ ([]), - ol.format.GML.MULTISURFACE_PARSERS_, node, objectStack); - if (goog.isDef(polygons)) { - var multiPolygon = new ol.geom.MultiPolygon(null); - multiPolygon.setPolygons(polygons); - return multiPolygon; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.MultiPolygon|undefined} MultiPolygon. - */ -ol.format.GML.readMultiPolygon_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'MultiPolygon'); - var polygons = ol.xml.pushParseAndPop( - /** @type {Array.} */ ([]), - ol.format.GML.MULTIPOLYGON_PARSERS_, node, objectStack); + this.MULTISURFACE_PARSERS_, node, objectStack, this); if (goog.isDef(polygons)) { var multiPolygon = new ol.geom.MultiPolygon(null); multiPolygon.setPolygons(polygons); @@ -352,37 +138,11 @@ ol.format.GML.readMultiPolygon_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML.pointMemberParser_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'pointMember' || - node.localName == 'pointMembers'); - ol.xml.parse(ol.format.GML.POINTMEMBER_PARSERS_, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - */ -ol.format.GML.lineStringMemberParser_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'lineStringMember' || - node.localName == 'lineStringMembers'); - ol.xml.parse(ol.format.GML.LINESTRINGMEMBER_PARSERS_, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - */ -ol.format.GML.curveMemberParser_ = function(node, objectStack) { +ol.format.GML3.prototype.curveMemberParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'curveMember' || node.localName == 'curveMembers'); - ol.xml.parse(ol.format.GML.CURVEMEMBER_PARSERS_, node, objectStack); + ol.xml.parseNode(this.CURVEMEMBER_PARSERS_, node, objectStack, this); }; @@ -391,45 +151,12 @@ ol.format.GML.curveMemberParser_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML.surfaceMemberParser_ = function(node, objectStack) { +ol.format.GML3.prototype.surfaceMemberParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'surfaceMember' || node.localName == 'surfaceMembers'); - ol.xml.parse(ol.format.GML.SURFACEMEMBER_PARSERS_, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - */ -ol.format.GML.polygonMemberParser_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'polygonMember' || - node.localName == 'polygonMembers'); - ol.xml.parse(ol.format.GML.POLYGONMEMBER_PARSERS_, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.LineString|undefined} LineString. - */ -ol.format.GML.readLineString_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'LineString'); - var flatCoordinates = - ol.format.GML.readFlatCoordinatesFromNode_(node, objectStack); - if (goog.isDefAndNotNull(flatCoordinates)) { - var lineString = new ol.geom.LineString(null); - lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); - return lineString; - } else { - return undefined; - } + ol.xml.parseNode(this.SURFACEMEMBER_PARSERS_, + node, objectStack, this); }; @@ -439,12 +166,12 @@ ol.format.GML.readLineString_ = function(node, objectStack) { * @private * @return {Array.<(Array.)>|undefined} flat coordinates. */ -ol.format.GML.readPatch_ = function(node, objectStack) { +ol.format.GML3.prototype.readPatch_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'patches'); return ol.xml.pushParseAndPop( /** @type {Array.>} */ ([null]), - ol.format.GML.PATCHES_PARSERS_, node, objectStack); + this.PATCHES_PARSERS_, node, objectStack, this); }; @@ -454,12 +181,12 @@ ol.format.GML.readPatch_ = function(node, objectStack) { * @private * @return {Array.|undefined} flat coordinates. */ -ol.format.GML.readSegment_ = function(node, objectStack) { +ol.format.GML3.prototype.readSegment_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'segments'); return ol.xml.pushParseAndPop( /** @type {Array.} */ ([null]), - ol.format.GML.SEGMENTS_PARSERS_, node, objectStack); + this.SEGMENTS_PARSERS_, node, objectStack, this); }; @@ -469,12 +196,12 @@ ol.format.GML.readSegment_ = function(node, objectStack) { * @private * @return {Array.<(Array.)>|undefined} flat coordinates. */ -ol.format.GML.readPolygonPatch_ = function(node, objectStack) { +ol.format.GML3.prototype.readPolygonPatch_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'PolygonPatch'); return ol.xml.pushParseAndPop( /** @type {Array.>} */ ([null]), - ol.format.GML.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack); + this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); }; @@ -484,12 +211,14 @@ ol.format.GML.readPolygonPatch_ = function(node, objectStack) { * @private * @return {Array.|undefined} flat coordinates. */ -ol.format.GML.readLineStringSegment_ = function(node, objectStack) { +ol.format.GML3.prototype.readLineStringSegment_ = + function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'LineStringSegment'); return ol.xml.pushParseAndPop( /** @type {Array.} */ ([null]), - ol.format.GML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack); + this.GEOMETRY_FLAT_COORDINATES_PARSERS_, + node, objectStack, this); }; @@ -498,12 +227,12 @@ ol.format.GML.readLineStringSegment_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML.interiorParser_ = function(node, objectStack) { +ol.format.GML3.prototype.interiorParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'interior'); var flatLinearRing = ol.xml.pushParseAndPop( /** @type {Array.|undefined} */ (undefined), - ol.format.GML.RING_PARSERS_, node, objectStack); + this.RING_PARSERS, node, objectStack, this); if (goog.isDef(flatLinearRing)) { var flatLinearRings = /** @type {Array.>} */ (objectStack[objectStack.length - 1]); @@ -519,12 +248,12 @@ ol.format.GML.interiorParser_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML.exteriorParser_ = function(node, objectStack) { +ol.format.GML3.prototype.exteriorParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'exterior'); var flatLinearRing = ol.xml.pushParseAndPop( /** @type {Array.|undefined} */ (undefined), - ol.format.GML.RING_PARSERS_, node, objectStack); + this.RING_PARSERS, node, objectStack, this); if (goog.isDef(flatLinearRing)) { var flatLinearRings = /** @type {Array.>} */ (objectStack[objectStack.length - 1]); @@ -535,89 +264,18 @@ ol.format.GML.exteriorParser_ = function(node, objectStack) { }; -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Array.|undefined} LinearRing flat coordinates. - */ -ol.format.GML.readFlatLinearRing_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'LinearRing'); - var ring = ol.xml.pushParseAndPop(/** @type {Array.} */(null), - ol.format.GML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack); - if (goog.isDefAndNotNull(ring)) { - return ring; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.LinearRing|undefined} LinearRing. - */ -ol.format.GML.readLinearRing_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'LinearRing'); - var flatCoordinates = - ol.format.GML.readFlatCoordinatesFromNode_(node, objectStack); - if (goog.isDef(flatCoordinates)) { - var ring = new ol.geom.LinearRing(null); - ring.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); - return ring; - } else { - return undefined; - } -}; - - /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private * @return {ol.geom.Polygon|undefined} Polygon. */ -ol.format.GML.readPolygon_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - goog.asserts.assert(node.localName == 'Polygon'); - var flatLinearRings = ol.xml.pushParseAndPop( - /** @type {Array.>} */ ([null]), - ol.format.GML.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack); - if (goog.isDef(flatLinearRings) && - !goog.isNull(flatLinearRings[0])) { - var polygon = new ol.geom.Polygon(null); - var flatCoordinates = flatLinearRings[0]; - var ends = [flatCoordinates.length]; - var i, ii; - for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - ol.array.safeExtend(flatCoordinates, flatLinearRings[i]); - ends.push(flatCoordinates.length); - } - polygon.setFlatCoordinates( - ol.geom.GeometryLayout.XYZ, flatCoordinates, ends); - return polygon; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {ol.geom.Polygon|undefined} Polygon. - */ -ol.format.GML.readSurface_ = function(node, objectStack) { +ol.format.GML3.prototype.readSurface_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'Surface'); var flatLinearRings = ol.xml.pushParseAndPop( /** @type {Array.>} */ ([null]), - ol.format.GML.SURFACE_PARSERS_, node, objectStack); + this.SURFACE_PARSERS_, node, objectStack, this); if (goog.isDef(flatLinearRings) && !goog.isNull(flatLinearRings[0])) { var polygon = new ol.geom.Polygon(null); @@ -643,12 +301,12 @@ ol.format.GML.readSurface_ = function(node, objectStack) { * @private * @return {ol.geom.LineString|undefined} LineString. */ -ol.format.GML.readCurve_ = function(node, objectStack) { +ol.format.GML3.prototype.readCurve_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'Curve'); var flatCoordinates = ol.xml.pushParseAndPop( /** @type {Array.} */ ([null]), - ol.format.GML.CURVE_PARSERS_, node, objectStack); + this.CURVE_PARSERS_, node, objectStack, this); if (goog.isDef(flatCoordinates)) { var lineString = new ol.geom.LineString(null); lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); @@ -665,39 +323,25 @@ ol.format.GML.readCurve_ = function(node, objectStack) { * @private * @return {ol.Extent|undefined} Envelope. */ -ol.format.GML.readEnvelope_ = function(node, objectStack) { +ol.format.GML3.prototype.readEnvelope_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'Envelope'); var flatCoordinates = ol.xml.pushParseAndPop( /** @type {Array.} */ ([null]), - ol.format.GML.ENVELOPE_PARSERS_, node, objectStack); + this.ENVELOPE_PARSERS_, node, objectStack, this); return ol.extent.createOrUpdate(flatCoordinates[1][0], flatCoordinates[1][1], flatCoordinates[2][0], flatCoordinates[2][1]); }; -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Array.} Flat coordinates. - */ -ol.format.GML.readFlatCoordinatesFromNode_ = function(node, objectStack) { - goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); - return /** @type {Array.} */ (ol.xml.pushParseAndPop( - null, - ol.format.GML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack)); -}; - - /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private * @return {Array.|undefined} Flat coordinates. */ -ol.format.GML.readFlatPos_ = function(node, objectStack) { +ol.format.GML3.prototype.readFlatPos_ = function(node, objectStack) { var s = ol.xml.getAllTextContent(node, false); var re = /^\s*([+\-]?\d*\.?\d+(?:[eE][+\-]?\d+)?)\s*/; /** @type {Array.} */ @@ -744,7 +388,7 @@ ol.format.GML.readFlatPos_ = function(node, objectStack) { * @private * @return {Array.|undefined} Flat coordinates. */ -ol.format.GML.readFlatPosList_ = function(node, objectStack) { +ol.format.GML3.prototype.readFlatPosList_ = function(node, objectStack) { var s = ol.xml.getAllTextContent(node, false).replace(/^\s*|\s*$/g, ''); var context = objectStack[0]; goog.asserts.assert(goog.isObject(context)); @@ -788,23 +432,55 @@ ol.format.GML.readFlatPosList_ = function(node, objectStack) { * @type {Object.>} * @private */ -ol.format.GML.GEOMETRY_PARSERS_ = { +ol.format.GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'Point': ol.xml.makeReplacer(ol.format.GML.readPoint_), - 'MultiPoint': ol.xml.makeReplacer(ol.format.GML.readMultiPoint_), - 'LineString': ol.xml.makeReplacer(ol.format.GML.readLineString_), + 'pos': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPos_), + 'posList': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPosList_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'interior': ol.format.GML3.prototype.interiorParser_, + 'exterior': ol.format.GML3.prototype.exteriorParser_ + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML3.prototype.GEOMETRY_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint), + 'MultiPoint': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readMultiPoint), + 'LineString': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readLineString), 'MultiLineString': ol.xml.makeReplacer( - ol.format.GML.readMultiLineString_), - 'LinearRing' : ol.xml.makeReplacer(ol.format.GML.readLinearRing_), - 'Polygon': ol.xml.makeReplacer(ol.format.GML.readPolygon_), - 'MultiPolygon': ol.xml.makeReplacer(ol.format.GML.readMultiPolygon_), - 'Surface': ol.xml.makeReplacer(ol.format.GML.readSurface_), - 'MultiSurface': ol.xml.makeReplacer(ol.format.GML.readMultiSurface_), - 'Curve': ol.xml.makeReplacer(ol.format.GML.readCurve_), - 'MultiCurve': ol.xml.makeReplacer(ol.format.GML.readMultiCurve_), - 'Envelope': ol.xml.makeReplacer(ol.format.GML.readEnvelope_) + ol.format.GMLBase.prototype.readMultiLineString), + 'LinearRing' : ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readLinearRing), + 'Polygon': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPolygon), + 'MultiPolygon': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readMultiPolygon), + 'Surface': ol.xml.makeReplacer(ol.format.GML3.prototype.readSurface_), + 'MultiSurface': ol.xml.makeReplacer( + ol.format.GML3.prototype.readMultiSurface_), + 'Curve': ol.xml.makeReplacer(ol.format.GML3.prototype.readCurve_), + 'MultiCurve': ol.xml.makeReplacer( + ol.format.GML3.prototype.readMultiCurve_), + 'Envelope': ol.xml.makeReplacer(ol.format.GML3.prototype.readEnvelope_) } -}; +}); /** @@ -812,68 +488,14 @@ ol.format.GML.GEOMETRY_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.GEOMETRY_FLAT_COORDINATES_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'pos': ol.xml.makeReplacer(ol.format.GML.readFlatPos_), - 'posList': ol.xml.makeReplacer(ol.format.GML.readFlatPosList_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.FLAT_LINEAR_RINGS_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'interior': ol.format.GML.interiorParser_, - 'exterior': ol.format.GML.exteriorParser_ - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.MULTIPOINT_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'pointMember': ol.xml.makeArrayPusher(ol.format.GML.pointMemberParser_), - 'pointMembers': ol.xml.makeArrayPusher(ol.format.GML.pointMemberParser_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.MULTILINESTRING_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'lineStringMember': ol.xml.makeArrayPusher( - ol.format.GML.lineStringMemberParser_), - 'lineStringMembers': ol.xml.makeArrayPusher( - ol.format.GML.lineStringMemberParser_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.MULTICURVE_PARSERS_ = { +ol.format.GML3.prototype.MULTICURVE_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { 'curveMember': ol.xml.makeArrayPusher( - ol.format.GML.curveMemberParser_), + ol.format.GML3.prototype.curveMemberParser_), 'curveMembers': ol.xml.makeArrayPusher( - ol.format.GML.curveMemberParser_) + ol.format.GML3.prototype.curveMemberParser_) } -}; +}); /** @@ -881,14 +503,14 @@ ol.format.GML.MULTICURVE_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.MULTISURFACE_PARSERS_ = { +ol.format.GML3.prototype.MULTISURFACE_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { 'surfaceMember': ol.xml.makeArrayPusher( - ol.format.GML.surfaceMemberParser_), + ol.format.GML3.prototype.surfaceMemberParser_), 'surfaceMembers': ol.xml.makeArrayPusher( - ol.format.GML.surfaceMemberParser_) + ol.format.GML3.prototype.surfaceMemberParser_) } -}; +}); /** @@ -896,40 +518,13 @@ ol.format.GML.MULTISURFACE_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.MULTIPOLYGON_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'polygonMember': ol.xml.makeArrayPusher( - ol.format.GML.polygonMemberParser_), - 'polygonMembers': ol.xml.makeArrayPusher( - ol.format.GML.polygonMemberParser_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.POINTMEMBER_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'Point': ol.xml.makeArrayPusher( - ol.format.GML.readFlatCoordinatesFromNode_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.LINESTRINGMEMBER_PARSERS_ = { +ol.format.GML3.prototype.CURVEMEMBER_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { 'LineString': ol.xml.makeArrayPusher( - ol.format.GML.readLineString_) + ol.format.GMLBase.prototype.readLineString), + 'Curve': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readCurve_) } -}; +}); /** @@ -937,12 +532,12 @@ ol.format.GML.LINESTRINGMEMBER_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.CURVEMEMBER_PARSERS_ = { +ol.format.GML3.prototype.SURFACEMEMBER_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'LineString': ol.xml.makeArrayPusher(ol.format.GML.readLineString_), - 'Curve': ol.xml.makeArrayPusher(ol.format.GML.readCurve_) + 'Polygon': ol.xml.makeArrayPusher(ol.format.GMLBase.prototype.readPolygon), + 'Surface': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readSurface_) } -}; +}); /** @@ -950,12 +545,11 @@ ol.format.GML.CURVEMEMBER_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.SURFACEMEMBER_PARSERS_ = { +ol.format.GML3.prototype.SURFACE_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'Polygon': ol.xml.makeArrayPusher(ol.format.GML.readPolygon_), - 'Surface': ol.xml.makeArrayPusher(ol.format.GML.readSurface_) + 'patches': ol.xml.makeReplacer(ol.format.GML3.prototype.readPatch_) } -}; +}); /** @@ -963,12 +557,11 @@ ol.format.GML.SURFACEMEMBER_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.POLYGONMEMBER_PARSERS_ = { +ol.format.GML3.prototype.CURVE_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'Polygon': ol.xml.makeArrayPusher( - ol.format.GML.readPolygon_) + 'segments': ol.xml.makeReplacer(ol.format.GML3.prototype.readSegment_) } -}; +}); /** @@ -976,11 +569,14 @@ ol.format.GML.POLYGONMEMBER_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.SURFACE_PARSERS_ = { +ol.format.GML3.prototype.ENVELOPE_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'patches': ol.xml.makeReplacer(ol.format.GML.readPatch_) + 'lowerCorner': ol.xml.makeArrayPusher( + ol.format.GML3.prototype.readFlatPosList_), + 'upperCorner': ol.xml.makeArrayPusher( + ol.format.GML3.prototype.readFlatPosList_) } -}; +}); /** @@ -988,11 +584,12 @@ ol.format.GML.SURFACE_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.CURVE_PARSERS_ = { +ol.format.GML3.prototype.PATCHES_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { - 'segments': ol.xml.makeReplacer(ol.format.GML.readSegment_) + 'PolygonPatch': ol.xml.makeReplacer( + ol.format.GML3.prototype.readPolygonPatch_) } -}; +}); /** @@ -1000,95 +597,12 @@ ol.format.GML.CURVE_PARSERS_ = { * @type {Object.>} * @private */ -ol.format.GML.ENVELOPE_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'lowerCorner': ol.xml.makeArrayPusher(ol.format.GML.readFlatPosList_), - 'upperCorner': ol.xml.makeArrayPusher(ol.format.GML.readFlatPosList_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.PATCHES_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'PolygonPatch': ol.xml.makeReplacer(ol.format.GML.readPolygonPatch_) - } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.SEGMENTS_PARSERS_ = { +ol.format.GML3.prototype.SEGMENTS_PARSERS_ = Object({ 'http://www.opengis.net/gml' : { 'LineStringSegment': ol.xml.makeReplacer( - ol.format.GML.readLineStringSegment_) + ol.format.GML3.prototype.readLineStringSegment_) } -}; - - -/** - * @const - * @type {Object.>} - * @private - */ -ol.format.GML.RING_PARSERS_ = { - 'http://www.opengis.net/gml' : { - 'LinearRing': ol.xml.makeReplacer(ol.format.GML.readFlatLinearRing_) - } -}; - - -/** - * @inheritDoc - */ -ol.format.GML.prototype.readGeometryFromNode = function(node, opt_options) { - var geometry = ol.format.GML.readGeometry(node, - [this.getReadOptions(node, goog.isDef(opt_options) ? opt_options : {})]); - return (goog.isDef(geometry) ? geometry : null); -}; - - -/** - * Read all features from a GML FeatureCollection. - * - * @function - * @param {ArrayBuffer|Document|Node|Object|string} source Source. - * @param {olx.format.ReadOptions=} opt_options Options. - * @return {Array.} Features. - * @api stable - */ -ol.format.GML.prototype.readFeatures; - - -/** - * @inheritDoc - */ -ol.format.GML.prototype.readFeaturesFromNode = function(node, opt_options) { - var options = { - 'featureType': this.featureType_, - 'featureNS': this.featureNS_ - }; - if (goog.isDef(opt_options)) { - goog.object.extend(options, this.getReadOptions(node, opt_options)); - } - return ol.format.GML.readFeatures_(node, [options]); -}; - - -/** - * @inheritDoc - */ -ol.format.GML.prototype.readProjectionFromNode = function(node) { - return ol.proj.get(goog.isDef(this.srsName_) ? this.srsName_ : - node.firstElementChild.getAttribute('srsName')); -}; +}); /** @@ -1097,7 +611,7 @@ ol.format.GML.prototype.readProjectionFromNode = function(node) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writePos_ = function(node, value, objectStack) { +ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1123,7 +637,7 @@ ol.format.GML.writePos_ = function(node, value, objectStack) { * @return {string} * @private */ -ol.format.GML.getCoords_ = function(point, opt_srsName) { +ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName) { var axisOrientation = 'enu'; if (goog.isDefAndNotNull(opt_srsName)) { axisOrientation = ol.proj.get(opt_srsName).getAxisOrientation(); @@ -1140,7 +654,7 @@ ol.format.GML.getCoords_ = function(point, opt_srsName) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writePosList_ = function(node, value, objectStack) { +ol.format.GML3.prototype.writePosList_ = function(node, value, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1151,7 +665,7 @@ ol.format.GML.writePosList_ = function(node, value, objectStack) { var point; for (var i = 0; i < len; ++i) { point = points[i]; - parts[i] = ol.format.GML.getCoords_(point, srsName); + parts[i] = this.getCoords_(point, srsName); } ol.format.XSD.writeStringTextNode(node, parts.join(' ')); }; @@ -1163,7 +677,7 @@ ol.format.GML.writePosList_ = function(node, value, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writePoint_ = function(node, geometry, objectStack) { +ol.format.GML3.prototype.writePoint_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1172,7 +686,7 @@ ol.format.GML.writePoint_ = function(node, geometry, objectStack) { } var pos = ol.xml.createElementNS(node.namespaceURI, 'pos'); node.appendChild(pos); - ol.format.GML.writePos_(pos, geometry, objectStack); + this.writePos_(pos, geometry, objectStack); }; @@ -1180,7 +694,7 @@ ol.format.GML.writePoint_ = function(node, geometry, objectStack) { * @type {Object.>} * @private */ -ol.format.GML.ENVELOPE_SERIALIZERS_ = { +ol.format.GML3.ENVELOPE_SERIALIZERS_ = { 'http://www.opengis.net/gml': { 'lowerCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode), 'upperCorner': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode) @@ -1193,7 +707,7 @@ ol.format.GML.ENVELOPE_SERIALIZERS_ = { * @param {ol.Extent} extent Extent. * @param {Array.<*>} objectStack Node stack. */ -ol.format.GML.writeEnvelope = function(node, extent, objectStack) { +ol.format.GML3.prototype.writeEnvelope = function(node, extent, objectStack) { goog.asserts.assert(extent.length == 4); var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); @@ -1204,10 +718,10 @@ ol.format.GML.writeEnvelope = function(node, extent, objectStack) { var keys = ['lowerCorner', 'upperCorner']; var values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]]; ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ - ({node: node}), ol.format.GML.ENVELOPE_SERIALIZERS_, + ({node: node}), ol.format.GML3.ENVELOPE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, - objectStack, keys); + objectStack, keys, this); }; @@ -1217,7 +731,8 @@ ol.format.GML.writeEnvelope = function(node, extent, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeLinearRing_ = function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeLinearRing_ = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1226,7 +741,7 @@ ol.format.GML.writeLinearRing_ = function(node, geometry, objectStack) { } var posList = ol.xml.createElementNS(node.namespaceURI, 'posList'); node.appendChild(posList); - ol.format.GML.writePosList_(posList, geometry, objectStack); + this.writePosList_(posList, geometry, objectStack); }; @@ -1237,7 +752,8 @@ ol.format.GML.writeLinearRing_ = function(node, geometry, objectStack) { * @return {Node} Node. * @private */ -ol.format.GML.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { +ol.format.GML3.prototype.RING_NODE_FACTORY_ = + function(value, objectStack, opt_nodeName) { var context = objectStack[objectStack.length - 1]; var parentNode = context.node; goog.asserts.assert(goog.isObject(context)); @@ -1256,7 +772,8 @@ ol.format.GML.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeSurfaceOrPolygon_ = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1267,12 +784,14 @@ ol.format.GML.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { var rings = geometry.getLinearRings(); ol.xml.pushSerializeAndPop( {node: node, srsName: srsName}, - ol.format.GML.RING_SERIALIZERS_, ol.format.GML.RING_NODE_FACTORY_, - rings, objectStack); + ol.format.GML3.RING_SERIALIZERS_, + this.RING_NODE_FACTORY_, + rings, objectStack, undefined, this); } else if (node.nodeName === 'Surface') { var patches = ol.xml.createElementNS(node.namespaceURI, 'patches'); node.appendChild(patches); - ol.format.GML.writeSurfacePatches_(patches, geometry, objectStack); + this.writeSurfacePatches_( + patches, geometry, objectStack); } }; @@ -1283,21 +802,25 @@ ol.format.GML.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeCurveOrLineString_ = function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeCurveOrLineString_ = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); - if (node.nodeName !== 'LineStringSegment' && goog.isDefAndNotNull(srsName)) { + if (node.nodeName !== 'LineStringSegment' && + goog.isDefAndNotNull(srsName)) { node.setAttribute('srsName', srsName); } - if (node.nodeName === 'LineString' || node.nodeName === 'LineStringSegment') { + if (node.nodeName === 'LineString' || + node.nodeName === 'LineStringSegment') { var posList = ol.xml.createElementNS(node.namespaceURI, 'posList'); node.appendChild(posList); - ol.format.GML.writePosList_(posList, geometry, objectStack); + this.writePosList_(posList, geometry, objectStack); } else if (node.nodeName === 'Curve') { var segments = ol.xml.createElementNS(node.namespaceURI, 'segments'); node.appendChild(segments); - ol.format.GML.writeCurveSegments_(segments, geometry, objectStack); + this.writeCurveSegments_(segments, + geometry, objectStack); } }; @@ -1308,8 +831,8 @@ ol.format.GML.writeCurveOrLineString_ = function(node, geometry, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeMultiSurfaceOrPolygon_ = function(node, geometry, - objectStack) { +ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_ = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1319,9 +842,9 @@ ol.format.GML.writeMultiSurfaceOrPolygon_ = function(node, geometry, } var polygons = geometry.getPolygons(); ol.xml.pushSerializeAndPop({node: node, srsName: srsName, surface: surface}, - ol.format.GML.SURFACEORPOLYGONMEMBER_SERIALIZERS_, - ol.format.GML.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons, - objectStack); + ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_, + this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons, + objectStack, undefined, this); }; @@ -1331,7 +854,7 @@ ol.format.GML.writeMultiSurfaceOrPolygon_ = function(node, geometry, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeMultiPoint_ = function(node, geometry, +ol.format.GML3.prototype.writeMultiPoint_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); @@ -1341,9 +864,9 @@ ol.format.GML.writeMultiPoint_ = function(node, geometry, } var points = geometry.getPoints(); ol.xml.pushSerializeAndPop({node: node, srsName: srsName}, - ol.format.GML.POINTMEMBER_SERIALIZERS_, + ol.format.GML3.POINTMEMBER_SERIALIZERS_, ol.xml.makeSimpleNodeFactory('pointMember'), points, - objectStack); + objectStack, undefined, this); }; @@ -1353,8 +876,8 @@ ol.format.GML.writeMultiPoint_ = function(node, geometry, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeMultiCurveOrLineString_ = function(node, geometry, - objectStack) { +ol.format.GML3.prototype.writeMultiCurveOrLineString_ = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var srsName = goog.object.get(context, 'srsName'); @@ -1364,9 +887,9 @@ ol.format.GML.writeMultiCurveOrLineString_ = function(node, geometry, } var lines = geometry.getLineStrings(); ol.xml.pushSerializeAndPop({node: node, srsName: srsName, curve: curve}, - ol.format.GML.LINESTRINGORCURVEMEMBER_SERIALIZERS_, - ol.format.GML.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines, - objectStack); + ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_, + this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines, + objectStack, undefined, this); }; @@ -1376,10 +899,10 @@ ol.format.GML.writeMultiCurveOrLineString_ = function(node, geometry, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeRing_ = function(node, ring, objectStack) { +ol.format.GML3.prototype.writeRing_ = function(node, ring, objectStack) { var linearRing = ol.xml.createElementNS(node.namespaceURI, 'LinearRing'); node.appendChild(linearRing); - ol.format.GML.writeLinearRing_(linearRing, ring, objectStack); + this.writeLinearRing_(linearRing, ring, objectStack); }; @@ -1389,14 +912,15 @@ ol.format.GML.writeRing_ = function(node, ring, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeSurfaceOrPolygonMember_ = function(node, polygon, - objectStack) { +ol.format.GML3.prototype.writeSurfaceOrPolygonMember_ = + function(node, polygon, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); - var child = ol.format.GML.GEOMETRY_NODE_FACTORY_(polygon, objectStack); + var child = this.GEOMETRY_NODE_FACTORY_( + polygon, objectStack); if (goog.isDef(child)) { node.appendChild(child); - ol.format.GML.writeSurfaceOrPolygon_(child, polygon, objectStack); + this.writeSurfaceOrPolygon_(child, polygon, objectStack); } }; @@ -1407,10 +931,11 @@ ol.format.GML.writeSurfaceOrPolygonMember_ = function(node, polygon, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writePointMember_ = function(node, point, objectStack) { +ol.format.GML3.prototype.writePointMember_ = + function(node, point, objectStack) { var child = ol.xml.createElementNS(node.namespaceURI, 'Point'); node.appendChild(child); - ol.format.GML.writePoint_(child, point, objectStack); + this.writePoint_(child, point, objectStack); }; @@ -1420,14 +945,14 @@ ol.format.GML.writePointMember_ = function(node, point, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeLineStringOrCurveMember_ = function(node, line, - objectStack) { +ol.format.GML3.prototype.writeLineStringOrCurveMember_ = + function(node, line, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); - var child = ol.format.GML.GEOMETRY_NODE_FACTORY_(line, objectStack); + var child = this.GEOMETRY_NODE_FACTORY_(line, objectStack); if (goog.isDef(child)) { node.appendChild(child); - ol.format.GML.writeCurveOrLineString_(child, line, objectStack); + this.writeCurveOrLineString_(child, line, objectStack); } }; @@ -1438,10 +963,11 @@ ol.format.GML.writeLineStringOrCurveMember_ = function(node, line, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeSurfacePatches_ = function(node, polygon, objectStack) { +ol.format.GML3.prototype.writeSurfacePatches_ = + function(node, polygon, objectStack) { var child = ol.xml.createElementNS(node.namespaceURI, 'PolygonPatch'); node.appendChild(child); - ol.format.GML.writeSurfaceOrPolygon_(child, polygon, objectStack); + this.writeSurfaceOrPolygon_(child, polygon, objectStack); }; @@ -1451,10 +977,12 @@ ol.format.GML.writeSurfacePatches_ = function(node, polygon, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeCurveSegments_ = function(node, line, objectStack) { - var child = ol.xml.createElementNS(node.namespaceURI, 'LineStringSegment'); +ol.format.GML3.prototype.writeCurveSegments_ = + function(node, line, objectStack) { + var child = ol.xml.createElementNS(node.namespaceURI, + 'LineStringSegment'); node.appendChild(child); - ol.format.GML.writeCurveOrLineString_(child, line, objectStack); + this.writeCurveOrLineString_(child, line, objectStack); }; @@ -1463,7 +991,8 @@ ol.format.GML.writeCurveSegments_ = function(node, line, objectStack) { * @param {ol.geom.Geometry|ol.Extent} geometry Geometry. * @param {Array.<*>} objectStack Node stack. */ -ol.format.GML.writeGeometry = function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeGeometryElement = + function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var item = goog.object.clone(context); @@ -1482,8 +1011,9 @@ ol.format.GML.writeGeometry = function(node, geometry, objectStack) { ol.format.Feature.transformWithOptions(geometry, true, context); } ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ - (item), ol.format.GML.GEOMETRY_SERIALIZERS_, - ol.format.GML.GEOMETRY_NODE_FACTORY_, [value], objectStack); + (item), ol.format.GML3.GEOMETRY_SERIALIZERS_, + this.GEOMETRY_NODE_FACTORY_, [value], + objectStack, undefined, this); }; @@ -1492,7 +1022,8 @@ ol.format.GML.writeGeometry = function(node, geometry, objectStack) { * @param {ol.Feature} feature Feature. * @param {Array.<*>} objectStack Node stack. */ -ol.format.GML.writeFeature = function(node, feature, objectStack) { +ol.format.GML3.prototype.writeFeatureElement = + function(node, feature, objectStack) { var fid = feature.getId(); if (goog.isDef(fid)) { node.setAttribute('fid', fid); @@ -1515,7 +1046,7 @@ ol.format.GML.writeFeature = function(node, feature, objectStack) { if (key == geometryName) { if (!(key in context.serializers[featureNS])) { context.serializers[featureNS][key] = ol.xml.makeChildAppender( - ol.format.GML.writeGeometry); + this.writeGeometryElement, this); } } else { if (!(key in context.serializers[featureNS])) { @@ -1541,7 +1072,8 @@ ol.format.GML.writeFeature = function(node, feature, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML.writeFeatureMembers_ = function(node, features, objectStack) { +ol.format.GML3.prototype.writeFeatureMembers_ = + function(node, features, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var featureType = goog.object.get(context, 'featureType'); @@ -1549,7 +1081,7 @@ ol.format.GML.writeFeatureMembers_ = function(node, features, objectStack) { var serializers = {}; serializers[featureNS] = {}; serializers[featureNS][featureType] = ol.xml.makeChildAppender( - ol.format.GML.writeFeature); + this.writeFeatureElement, this); var item = goog.object.clone(context); item.node = node; ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ @@ -1564,12 +1096,12 @@ ol.format.GML.writeFeatureMembers_ = function(node, features, objectStack) { * @type {Object.>} * @private */ -ol.format.GML.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = { +ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = { 'http://www.opengis.net/gml': { 'surfaceMember': ol.xml.makeChildAppender( - ol.format.GML.writeSurfaceOrPolygonMember_), + ol.format.GML3.prototype.writeSurfaceOrPolygonMember_), 'polygonMember': ol.xml.makeChildAppender( - ol.format.GML.writeSurfaceOrPolygonMember_) + ol.format.GML3.prototype.writeSurfaceOrPolygonMember_) } }; @@ -1578,9 +1110,10 @@ ol.format.GML.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = { * @type {Object.>} * @private */ -ol.format.GML.POINTMEMBER_SERIALIZERS_ = { +ol.format.GML3.POINTMEMBER_SERIALIZERS_ = { 'http://www.opengis.net/gml': { - 'pointMember': ol.xml.makeChildAppender(ol.format.GML.writePointMember_) + 'pointMember': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writePointMember_) } }; @@ -1589,12 +1122,12 @@ ol.format.GML.POINTMEMBER_SERIALIZERS_ = { * @type {Object.>} * @private */ -ol.format.GML.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = { +ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = { 'http://www.opengis.net/gml': { 'lineStringMember': ol.xml.makeChildAppender( - ol.format.GML.writeLineStringOrCurveMember_), + ol.format.GML3.prototype.writeLineStringOrCurveMember_), 'curveMember': ol.xml.makeChildAppender( - ol.format.GML.writeLineStringOrCurveMember_) + ol.format.GML3.prototype.writeLineStringOrCurveMember_) } }; @@ -1603,10 +1136,10 @@ ol.format.GML.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = { * @type {Object.>} * @private */ -ol.format.GML.RING_SERIALIZERS_ = { +ol.format.GML3.RING_SERIALIZERS_ = { 'http://www.opengis.net/gml': { - 'exterior': ol.xml.makeChildAppender(ol.format.GML.writeRing_), - 'interior': ol.xml.makeChildAppender(ol.format.GML.writeRing_) + 'exterior': ol.xml.makeChildAppender(ol.format.GML3.prototype.writeRing_), + 'interior': ol.xml.makeChildAppender(ol.format.GML3.prototype.writeRing_) } }; @@ -1615,26 +1148,31 @@ ol.format.GML.RING_SERIALIZERS_ = { * @type {Object.>} * @private */ -ol.format.GML.GEOMETRY_SERIALIZERS_ = { +ol.format.GML3.GEOMETRY_SERIALIZERS_ = { 'http://www.opengis.net/gml': { - 'Curve': ol.xml.makeChildAppender(ol.format.GML.writeCurveOrLineString_), + 'Curve': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writeCurveOrLineString_), 'MultiCurve': ol.xml.makeChildAppender( - ol.format.GML.writeMultiCurveOrLineString_), - 'Point': ol.xml.makeChildAppender(ol.format.GML.writePoint_), - 'MultiPoint': ol.xml.makeChildAppender(ol.format.GML.writeMultiPoint_), + ol.format.GML3.prototype.writeMultiCurveOrLineString_), + 'Point': ol.xml.makeChildAppender(ol.format.GML3.prototype.writePoint_), + 'MultiPoint': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writeMultiPoint_), 'LineString': ol.xml.makeChildAppender( - ol.format.GML.writeCurveOrLineString_), + ol.format.GML3.prototype.writeCurveOrLineString_), 'MultiLineString': ol.xml.makeChildAppender( - ol.format.GML.writeMultiCurveOrLineString_), - 'LinearRing': ol.xml.makeChildAppender(ol.format.GML.writeLinearRing_), - 'Polygon': ol.xml.makeChildAppender(ol.format.GML.writeSurfaceOrPolygon_), + ol.format.GML3.prototype.writeMultiCurveOrLineString_), + 'LinearRing': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writeLinearRing_), + 'Polygon': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writeSurfaceOrPolygon_), 'MultiPolygon': ol.xml.makeChildAppender( - ol.format.GML.writeMultiSurfaceOrPolygon_), - 'Surface': ol.xml.makeChildAppender(ol.format.GML.writeSurfaceOrPolygon_), + ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_), + 'Surface': ol.xml.makeChildAppender( + ol.format.GML3.prototype.writeSurfaceOrPolygon_), 'MultiSurface': ol.xml.makeChildAppender( - ol.format.GML.writeMultiSurfaceOrPolygon_), + ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_), 'Envelope': ol.xml.makeChildAppender( - ol.format.GML.writeEnvelope) + ol.format.GML3.prototype.writeEnvelope) } }; @@ -1644,7 +1182,7 @@ ol.format.GML.GEOMETRY_SERIALIZERS_ = { * @type {Object.} * @private */ -ol.format.GML.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = { +ol.format.GML3.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = { 'MultiLineString': 'lineStringMember', 'MultiCurve': 'curveMember', 'MultiPolygon': 'polygonMember', @@ -1660,12 +1198,12 @@ ol.format.GML.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = { * @return {Node|undefined} Node. * @private */ -ol.format.GML.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, - objectStack, opt_nodeName) { +ol.format.GML3.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = + function(value, objectStack, opt_nodeName) { var parentNode = objectStack[objectStack.length - 1].node; goog.asserts.assert(ol.xml.isNode(parentNode)); return ol.xml.createElementNS('http://www.opengis.net/gml', - ol.format.GML.MULTIGEOMETRY_TO_MEMBER_NODENAME_[parentNode.nodeName]); + ol.format.GML3.MULTIGEOMETRY_TO_MEMBER_NODENAME_[parentNode.nodeName]); }; @@ -1677,8 +1215,8 @@ ol.format.GML.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, * @return {Node|undefined} Node. * @private */ -ol.format.GML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, - opt_nodeName) { +ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = + function(value, objectStack, opt_nodeName) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context)); var multiSurface = goog.object.get(context, 'multiSurface'); @@ -1711,15 +1249,15 @@ ol.format.GML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, /** * @inheritDoc */ -ol.format.GML.prototype.writeGeometryNode = function(geometry, opt_options) { +ol.format.GML3.prototype.writeGeometryNode = function(geometry, opt_options) { var geom = ol.xml.createElementNS('http://www.opengis.net/gml', 'geom'); - var context = {node: geom, srsName: this.srsName_, + var context = {node: geom, srsName: this.srsName, curve: this.curve_, surface: this.surface_, multiSurface: this.multiSurface_, multiCurve: this.multiCurve_}; if (goog.isDef(opt_options)) { goog.object.extend(context, opt_options); } - ol.format.GML.writeGeometry(geom, geometry, [context]); + this.writeGeometryElement(geom, geometry, [context]); return geom; }; @@ -1733,29 +1271,57 @@ ol.format.GML.prototype.writeGeometryNode = function(geometry, opt_options) { * @return {Node} Result. * @api stable */ -ol.format.GML.prototype.writeFeatures; +ol.format.GML3.prototype.writeFeatures; /** * @inheritDoc */ -ol.format.GML.prototype.writeFeaturesNode = function(features, opt_options) { +ol.format.GML3.prototype.writeFeaturesNode = function(features, opt_options) { var node = ol.xml.createElementNS('http://www.opengis.net/gml', 'featureMembers'); ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation', this.schemaLocation_); + 'xsi:schemaLocation', this.schemaLocation); var context = { - srsName: this.srsName_, + srsName: this.srsName, curve: this.curve_, surface: this.surface_, multiSurface: this.multiSurface_, multiCurve: this.multiCurve_, - featureNS: this.featureNS_, - featureType: this.featureType_ + featureNS: this.featureNS, + featureType: this.featureType }; if (goog.isDef(opt_options)) { goog.object.extend(context, opt_options); } - ol.format.GML.writeFeatureMembers_(node, features, [context]); + this.writeFeatureMembers_(node, features, [context]); return node; }; + + + +/** + * @classdesc + * Feature format for reading and writing data in the GML format + * version 3.1.1. + * Currently only supports GML 3.1.1 Simple Features profile. + * + * @constructor + * @param {olx.format.GMLOptions=} opt_options + * Optional configuration object. + * @extends {ol.format.GMLBase} + * @api stable + */ +ol.format.GML = ol.format.GML3; + + +/** + * Encode an array of features in GML 3.1.1 Simple Features. + * + * @function + * @param {Array.} features Features. + * @param {olx.format.WriteOptions=} opt_options Options. + * @return {Node} Result. + * @api stable + */ +ol.format.GML.prototype.writeFeatures; diff --git a/src/ol/format/gml/gmlbase.js b/src/ol/format/gml/gmlbase.js new file mode 100644 index 0000000000..5133badd8c --- /dev/null +++ b/src/ol/format/gml/gmlbase.js @@ -0,0 +1,564 @@ +// FIXME Envelopes should not be treated as geometries! readEnvelope_ is part +// of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect +// envelopes/extents, only geometries! +goog.provide('ol.format.GMLBase'); + +goog.require('goog.asserts'); +goog.require('goog.dom'); +goog.require('goog.dom.NodeType'); +goog.require('goog.object'); +goog.require('goog.string'); +goog.require('ol.Feature'); +goog.require('ol.array'); +goog.require('ol.format.Feature'); +goog.require('ol.format.XMLFeature'); +goog.require('ol.geom.Geometry'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.LinearRing'); +goog.require('ol.geom.MultiLineString'); +goog.require('ol.geom.MultiPoint'); +goog.require('ol.geom.MultiPolygon'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.Polygon'); +goog.require('ol.proj'); +goog.require('ol.xml'); + + + +/** + * @classdesc + * Abstract base class; normally only used for creating subclasses and not + * instantiated in apps. + * Feature base format for reading and writing data in the GML format. + * This class cannot be instantiate, it contains only base content that + * is shared with versioned format classes ol.format.GML2 and + * ol.format.GML3. + * + * @constructor + * @param {olx.format.GMLOptions=} opt_options + * Optional configuration object. + * @extends {ol.format.XMLFeature} + * @api + */ +ol.format.GMLBase = function(opt_options) { + var options = /** @type {olx.format.GMLOptions} */ + (goog.isDef(opt_options) ? opt_options : {}); + + /** + * @protected + * @type {string} + */ + this.featureType = options.featureType; + + /** + * @protected + * @type {string} + */ + this.featureNS = options.featureNS; + + /** + * @protected + * @type {string} + */ + this.srsName = options.srsName; + + /** + * @protected + * @type {string} + */ + this.schemaLocation = ''; + + goog.base(this); +}; +goog.inherits(ol.format.GMLBase, ol.format.XMLFeature); + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Array.} Features. + * @private + */ +ol.format.GMLBase.prototype.readFeatures_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + var localName = ol.xml.getLocalName(node); + var features; + if (localName == 'FeatureCollection') { + features = ol.xml.pushParseAndPop(null, + this.FEATURE_COLLECTION_PARSERS, node, + objectStack, this); + } else if (localName == 'featureMembers' || localName == 'featureMember') { + var context = objectStack[0]; + goog.asserts.assert(goog.isObject(context)); + var featureType = goog.object.get(context, 'featureType'); + if (!goog.isDef(featureType) && !goog.isNull(node.firstElementChild)) { + var member = node.firstElementChild; + featureType = member.nodeName.split(':').pop(); + goog.object.set(context, 'featureType', featureType); + goog.object.set(context, 'featureNS', member.namespaceURI); + } + var parsers = {}; + var parsersNS = {}; + parsers[featureType] = (localName == 'featureMembers') ? + ol.xml.makeArrayPusher(this.readFeature_, this) : + ol.xml.makeReplacer(this.readFeature_, this); + parsersNS[goog.object.get(context, 'featureNS')] = parsers; + features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); + } + if (!goog.isDef(features)) { + features = []; + } + return features; +}; + + +/** + * @type {Object.>} + */ +ol.format.GMLBase.prototype.FEATURE_COLLECTION_PARSERS = Object({ + 'http://www.opengis.net/gml': { + 'featureMember': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.readFeatures_), + 'featureMembers': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readFeatures_) + } +}); + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.Geometry|undefined} Geometry. + */ +ol.format.GMLBase.prototype.readGeometryElement = function(node, objectStack) { + var context = objectStack[0]; + goog.asserts.assert(goog.isObject(context)); + goog.object.set(context, 'srsName', + node.firstElementChild.getAttribute('srsName')); + var geometry = ol.xml.pushParseAndPop(/** @type {ol.geom.Geometry} */(null), + this.GEOMETRY_PARSERS_, node, objectStack, this); + if (goog.isDefAndNotNull(geometry)) { + return /** @type {ol.geom.Geometry} */ ( + ol.format.Feature.transformWithOptions(geometry, false, context)); + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.Feature} Feature. + * @private + */ +ol.format.GMLBase.prototype.readFeature_ = function(node, objectStack) { + var n; + var fid = node.getAttribute('fid') || + ol.xml.getAttributeNS(node, 'http://www.opengis.net/gml', 'id'); + var values = {}, geometryName; + for (n = node.firstElementChild; !goog.isNull(n); + n = n.nextElementSibling) { + var localName = ol.xml.getLocalName(n); + // Assume attribute elements have one child node and that the child + // is a text node. Otherwise assume it is a geometry node. + if (n.childNodes.length === 0 || + (n.childNodes.length === 1 && + n.firstChild.nodeType === 3)) { + var value = ol.xml.getAllTextContent(n, false); + if (goog.string.isEmpty(value)) { + value = undefined; + } + values[localName] = value; + } else { + // boundedBy is an extent and must not be considered as a geometry + if (localName !== 'boundedBy') { + geometryName = localName; + } + values[localName] = this.readGeometryElement(n, objectStack); + } + } + var feature = new ol.Feature(values); + if (goog.isDef(geometryName)) { + feature.setGeometryName(geometryName); + } + if (fid) { + feature.setId(fid); + } + return feature; +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.Point|undefined} Point. + */ +ol.format.GMLBase.prototype.readPoint = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Point'); + var flatCoordinates = + this.readFlatCoordinatesFromNode_(node, objectStack); + if (goog.isDefAndNotNull(flatCoordinates)) { + var point = new ol.geom.Point(null); + goog.asserts.assert(flatCoordinates.length == 3); + point.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); + return point; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.MultiPoint|undefined} MultiPoint. + */ +ol.format.GMLBase.prototype.readMultiPoint = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'MultiPoint'); + var coordinates = ol.xml.pushParseAndPop( + /** @type {Array.>} */ ([]), + this.MULTIPOINT_PARSERS_, node, objectStack, this); + if (goog.isDef(coordinates)) { + return new ol.geom.MultiPoint(coordinates); + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.MultiLineString|undefined} MultiLineString. + */ +ol.format.GMLBase.prototype.readMultiLineString = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'MultiLineString'); + var lineStrings = ol.xml.pushParseAndPop( + /** @type {Array.} */ ([]), + this.MULTILINESTRING_PARSERS_, node, objectStack, this); + if (goog.isDef(lineStrings)) { + var multiLineString = new ol.geom.MultiLineString(null); + multiLineString.setLineStrings(lineStrings); + return multiLineString; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.MultiPolygon|undefined} MultiPolygon. + */ +ol.format.GMLBase.prototype.readMultiPolygon = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'MultiPolygon'); + var polygons = ol.xml.pushParseAndPop( + /** @type {Array.} */ ([]), + this.MULTIPOLYGON_PARSERS_, node, objectStack, this); + if (goog.isDef(polygons)) { + var multiPolygon = new ol.geom.MultiPolygon(null); + multiPolygon.setPolygons(polygons); + return multiPolygon; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GMLBase.prototype.pointMemberParser_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'pointMember' || + node.localName == 'pointMembers'); + ol.xml.parseNode(this.POINTMEMBER_PARSERS_, + node, objectStack, this); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GMLBase.prototype.lineStringMemberParser_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'lineStringMember' || + node.localName == 'lineStringMembers'); + ol.xml.parseNode(this.LINESTRINGMEMBER_PARSERS_, + node, objectStack, this); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GMLBase.prototype.polygonMemberParser_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'polygonMember' || + node.localName == 'polygonMembers'); + ol.xml.parseNode(this.POLYGONMEMBER_PARSERS_, node, + objectStack, this); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.LineString|undefined} LineString. + */ +ol.format.GMLBase.prototype.readLineString = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'LineString'); + var flatCoordinates = + this.readFlatCoordinatesFromNode_(node, objectStack); + if (goog.isDefAndNotNull(flatCoordinates)) { + var lineString = new ol.geom.LineString(null); + lineString.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); + return lineString; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.|undefined} LinearRing flat coordinates. + */ +ol.format.GMLBase.prototype.readFlatLinearRing_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'LinearRing'); + var ring = ol.xml.pushParseAndPop(/** @type {Array.} */(null), + this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, + objectStack, this); + if (goog.isDefAndNotNull(ring)) { + return ring; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.LinearRing|undefined} LinearRing. + */ +ol.format.GMLBase.prototype.readLinearRing = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'LinearRing'); + var flatCoordinates = + this.readFlatCoordinatesFromNode_(node, objectStack); + if (goog.isDef(flatCoordinates)) { + var ring = new ol.geom.LinearRing(null); + ring.setFlatCoordinates(ol.geom.GeometryLayout.XYZ, flatCoordinates); + return ring; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.geom.Polygon|undefined} Polygon. + */ +ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Polygon'); + var flatLinearRings = ol.xml.pushParseAndPop( + /** @type {Array.>} */ ([null]), + this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); + if (goog.isDef(flatLinearRings) && + !goog.isNull(flatLinearRings[0])) { + var polygon = new ol.geom.Polygon(null); + var flatCoordinates = flatLinearRings[0]; + var ends = [flatCoordinates.length]; + var i, ii; + for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { + ol.array.safeExtend(flatCoordinates, flatLinearRings[i]); + ends.push(flatCoordinates.length); + } + polygon.setFlatCoordinates( + ol.geom.GeometryLayout.XYZ, flatCoordinates, ends); + return polygon; + } else { + return undefined; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.} Flat coordinates. + */ +ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + return /** @type {Array.} */ (ol.xml.pushParseAndPop( + null, + this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, + objectStack, this)); +}; + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.MULTIPOINT_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'pointMember': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.pointMemberParser_), + 'pointMembers': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.pointMemberParser_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.MULTILINESTRING_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'lineStringMember': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.lineStringMemberParser_), + 'lineStringMembers': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.lineStringMemberParser_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.MULTIPOLYGON_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'polygonMember': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.polygonMemberParser_), + 'polygonMembers': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.polygonMemberParser_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.POINTMEMBER_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'Point': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.LINESTRINGMEMBER_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'LineString': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.readLineString) + } +}); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GMLBase.prototype.POLYGONMEMBER_PARSERS_ = Object({ + 'http://www.opengis.net/gml' : { + 'Polygon': ol.xml.makeArrayPusher( + ol.format.GMLBase.prototype.readPolygon) + } +}); + + +/** + * @const + * @type {Object.>} + * @protected + */ +ol.format.GMLBase.prototype.RING_PARSERS = Object({ + 'http://www.opengis.net/gml' : { + 'LinearRing': ol.xml.makeReplacer( + ol.format.GMLBase.prototype.readFlatLinearRing_) + } +}); + + +/** + * @inheritDoc + */ +ol.format.GMLBase.prototype.readGeometryFromNode = + function(node, opt_options) { + var geometry = this.readGeometryElement(node, + [this.getReadOptions(node, goog.isDef(opt_options) ? opt_options : {})]); + return goog.isDef(geometry) ? geometry : null; +}; + + +/** + * Read all features from a GML FeatureCollection. + * + * @function + * @param {ArrayBuffer|Document|Node|Object|string} source Source. + * @param {olx.format.ReadOptions=} opt_options Options. + * @return {Array.} Features. + * @api stable + */ +ol.format.GMLBase.prototype.readFeatures; + + +/** + * @inheritDoc + */ +ol.format.GMLBase.prototype.readFeaturesFromNode = + function(node, opt_options) { + var options = { + 'featureType': this.featureType, + 'featureNS': this.featureNS + }; + if (goog.isDef(opt_options)) { + goog.object.extend(options, this.getReadOptions(node, opt_options)); + } + return this.readFeatures_(node, [options]); +}; + + +/** + * @inheritDoc + */ +ol.format.GMLBase.prototype.readProjectionFromNode = function(node) { + return ol.proj.get(goog.isDef(this.srsName_) ? this.srsName_ : + node.firstElementChild.getAttribute('srsName')); +}; diff --git a/src/ol/format/gpxformat.js b/src/ol/format/gpxformat.js index 23492bbccd..ad40a92393 100644 --- a/src/ol/format/gpxformat.js +++ b/src/ol/format/gpxformat.js @@ -100,7 +100,7 @@ ol.format.GPX.parseLink_ = function(node, objectStack) { if (!goog.isNull(href)) { goog.object.set(values, 'link', href); } - ol.xml.parse(ol.format.GPX.LINK_PARSERS_, node, objectStack); + ol.xml.parseNode(ol.format.GPX.LINK_PARSERS_, node, objectStack); }; @@ -164,7 +164,7 @@ ol.format.GPX.parseTrkSeg_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'trkseg'); var values = /** @type {Object} */ (objectStack[objectStack.length - 1]); - ol.xml.parse(ol.format.GPX.TRKSEG_PARSERS_, node, objectStack); + ol.xml.parseNode(ol.format.GPX.TRKSEG_PARSERS_, node, objectStack); var flatCoordinates = /** @type {Array.} */ (goog.object.get(values, 'flatCoordinates')); var ends = /** @type {Array.} */ (goog.object.get(values, 'ends')); diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js index 42f088ae7a..dc6d457d89 100644 --- a/src/ol/format/kmlformat.js +++ b/src/ol/format/kmlformat.js @@ -1000,7 +1000,7 @@ ol.format.KML.DataParser_ = function(node, objectStack) { ol.format.KML.ExtendedDataParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'ExtendedData'); - ol.xml.parse(ol.format.KML.EXTENDED_DATA_PARSERS_, node, objectStack); + ol.xml.parseNode(ol.format.KML.EXTENDED_DATA_PARSERS_, node, objectStack); }; @@ -1066,7 +1066,7 @@ ol.format.KML.PlacemarkStyleMapParser_ = function(node, objectStack) { ol.format.KML.SchemaDataParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'SchemaData'); - ol.xml.parse(ol.format.KML.SCHEMA_DATA_PARSERS_, node, objectStack); + ol.xml.parseNode(ol.format.KML.SCHEMA_DATA_PARSERS_, node, objectStack); }; @@ -1655,7 +1655,7 @@ ol.format.KML.prototype.readName = function(source) { } else if (ol.xml.isNode(source)) { return this.readNameFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readNameFromDocument(doc); } else { goog.asserts.fail(); diff --git a/src/ol/format/wfsformat.js b/src/ol/format/wfsformat.js index 8e0d7f0468..ea9ab4a6b5 100644 --- a/src/ol/format/wfsformat.js +++ b/src/ol/format/wfsformat.js @@ -3,7 +3,8 @@ goog.provide('ol.format.WFS'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); -goog.require('ol.format.GML'); +goog.require('ol.format.GML3'); +goog.require('ol.format.GMLBase'); goog.require('ol.format.XMLFeature'); goog.require('ol.format.XSD'); goog.require('ol.geom.Geometry'); @@ -15,8 +16,9 @@ goog.require('ol.xml'); /** * @classdesc * Feature format for reading and writing data in the WFS format. - * Currently only supports WFS version 1.1.0. - * Also see {@link ol.format.GML} which is used by this format. + * By default, supports WFS version 1.1.0. You can pass a GML format + * as option if you want to read a WFS that contains GML2 (WFS 1.0.0). + * Also see {@link ol.format.GMLBase} which is used by this format. * * @constructor * @param {olx.format.WFSOptions=} opt_options @@ -40,6 +42,13 @@ ol.format.WFS = function(opt_options) { */ this.featureNS_ = options.featureNS; + /** + * @private + * @type {ol.format.GMLBase} + */ + this.gmlFormat_ = goog.isDef(options.gmlFormat) ? + options.gmlFormat : new ol.format.GML3(); + /** * @private * @type {string} @@ -119,7 +128,8 @@ ol.format.WFS.prototype.readFeaturesFromNode = function(node, opt_options) { goog.isDef(opt_options) ? opt_options : {})); var objectStack = [context]; var features = ol.xml.pushParseAndPop([], - ol.format.GML.FEATURE_COLLECTION_PARSERS, node, objectStack); + this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node, + objectStack, this.gmlFormat_); if (!goog.isDef(features)) { features = []; } @@ -139,7 +149,7 @@ ol.format.WFS.prototype.readTransactionResponse = function(source) { } else if (ol.xml.isNode(source)) { return this.readTransactionResponseFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readTransactionResponseFromDocument(doc); } else { goog.asserts.fail(); @@ -162,7 +172,7 @@ ol.format.WFS.prototype.readFeatureCollectionMetadata = function(source) { return this.readFeatureCollectionMetadataFromNode( /** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readFeatureCollectionMetadataFromDocument(doc); } else { goog.asserts.fail(); @@ -196,7 +206,7 @@ ol.format.WFS.prototype.readFeatureCollectionMetadataFromDocument = ol.format.WFS.FEATURE_COLLECTION_PARSERS_ = { 'http://www.opengis.net/gml': { 'boundedBy': ol.xml.makeObjectPropertySetter( - ol.format.GML.readGeometry, 'bounds') + ol.format.GMLBase.prototype.readGeometryElement, 'bounds') } }; @@ -215,7 +225,7 @@ ol.format.WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) { goog.object.set(result, 'numberOfFeatures', value); return ol.xml.pushParseAndPop( /** @type {ol.format.WFS.FeatureCollectionMetadata} */ (result), - ol.format.WFS.FEATURE_COLLECTION_PARSERS_, node, []); + ol.format.WFS.FEATURE_COLLECTION_PARSERS_, node, [], this.gmlFormat_); }; @@ -268,7 +278,7 @@ ol.format.WFS.OGC_FID_PARSERS_ = { * @private */ ol.format.WFS.fidParser_ = function(node, objectStack) { - ol.xml.parse(ol.format.WFS.OGC_FID_PARSERS_, node, objectStack); + ol.xml.parseNode(ol.format.WFS.OGC_FID_PARSERS_, node, objectStack); }; @@ -363,7 +373,7 @@ ol.format.WFS.writeFeature_ = function(node, feature, objectStack) { var featureNS = goog.object.get(context, 'featureNS'); var child = ol.xml.createElementNS(featureNS, featureType); node.appendChild(child); - ol.format.GML.writeFeature(child, feature, objectStack); + ol.format.GML3.prototype.writeFeatureElement(child, feature, objectStack); }; @@ -457,7 +467,8 @@ ol.format.WFS.writeProperty_ = function(node, pair, objectStack) { var value = ol.xml.createElementNS('http://www.opengis.net/wfs', 'Value'); node.appendChild(value); if (pair.value instanceof ol.geom.Geometry) { - ol.format.GML.writeGeometry(value, pair.value, objectStack); + ol.format.GML3.prototype.writeGeometryElement(value, + pair.value, objectStack); } else { ol.format.XSD.writeStringTextNode(value, pair.value); } @@ -564,7 +575,7 @@ ol.format.WFS.writeOgcBBOX_ = function(node, bbox, objectStack) { var bboxNode = ol.xml.createElementNS('http://www.opengis.net/ogc', 'BBOX'); node.appendChild(bboxNode); ol.format.WFS.writeOgcPropertyName_(bboxNode, geometryName, objectStack); - ol.format.GML.writeGeometry(bboxNode, bbox, objectStack); + ol.format.GML3.prototype.writeGeometryElement(bboxNode, bbox, objectStack); }; @@ -746,7 +757,7 @@ ol.format.WFS.prototype.readProjectionFromNode = function(node) { (n.childNodes.length === 1 && n.firstChild.nodeType === 3))) { var objectStack = [{}]; - ol.format.GML.readGeometry(n, objectStack); + this.gmlFormat_.readGeometryElement(n, objectStack); return ol.proj.get(objectStack.pop().srsName); } } diff --git a/src/ol/format/wktformat.js b/src/ol/format/wktformat.js index 12e220ea9c..e4dd17d239 100644 --- a/src/ol/format/wktformat.js +++ b/src/ol/format/wktformat.js @@ -602,7 +602,7 @@ ol.format.WKT.Parser.prototype.parseGeometry_ = function() { return new ctor(coordinates); } } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -622,7 +622,7 @@ ol.format.WKT.Parser.prototype.parseGeometryCollectionText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -639,7 +639,7 @@ ol.format.WKT.Parser.prototype.parsePointText_ = function() { } else if (this.isEmptyGeometry_()) { return null; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -656,7 +656,7 @@ ol.format.WKT.Parser.prototype.parseLineStringText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -673,7 +673,7 @@ ol.format.WKT.Parser.prototype.parsePolygonText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -695,7 +695,7 @@ ol.format.WKT.Parser.prototype.parseMultiPointText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -713,7 +713,7 @@ ol.format.WKT.Parser.prototype.parseMultiLineStringText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -730,7 +730,7 @@ ol.format.WKT.Parser.prototype.parseMultiPolygonText_ = function() { } else if (this.isEmptyGeometry_()) { return []; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -751,7 +751,7 @@ ol.format.WKT.Parser.prototype.parsePoint_ = function() { if (coordinates.length == this.dimension_) { return coordinates; } - this.raiseError_(); + throw new Error(this.formatErrorMessage_()); }; @@ -822,12 +822,13 @@ ol.format.WKT.Parser.prototype.isEmptyGeometry_ = function() { /** + * Create an error message for an unexpected token error. + * @return {string} Error message. * @private */ -ol.format.WKT.Parser.prototype.raiseError_ = function() { - throw new Error('Unexpected `' + this.token_.value + - '` at position ' + this.token_.position + - ' in `' + this.lexer_.wkt + '`'); +ol.format.WKT.Parser.prototype.formatErrorMessage_ = function() { + return 'Unexpected `' + this.token_.value + '` at position ' + + this.token_.position + ' in `' + this.lexer_.wkt + '`'; }; diff --git a/src/ol/format/xmlfeatureformat.js b/src/ol/format/xmlfeatureformat.js index 3c61ee6574..7dea0579b5 100644 --- a/src/ol/format/xmlfeatureformat.js +++ b/src/ol/format/xmlfeatureformat.js @@ -43,7 +43,7 @@ ol.format.XMLFeature.prototype.readFeature = function(source, opt_options) { } else if (ol.xml.isNode(source)) { return this.readFeatureFromNode(/** @type {Node} */ (source), opt_options); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readFeatureFromDocument(doc, opt_options); } else { goog.asserts.fail(); @@ -86,7 +86,7 @@ ol.format.XMLFeature.prototype.readFeatures = function(source, opt_options) { } else if (ol.xml.isNode(source)) { return this.readFeaturesFromNode(/** @type {Node} */ (source), opt_options); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readFeaturesFromDocument(doc, opt_options); } else { goog.asserts.fail(); @@ -134,7 +134,7 @@ ol.format.XMLFeature.prototype.readGeometry = function(source, opt_options) { } else if (ol.xml.isNode(source)) { return this.readGeometryFromNode(/** @type {Node} */ (source), opt_options); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readGeometryFromDocument(doc, opt_options); } else { goog.asserts.fail(); @@ -170,7 +170,7 @@ ol.format.XMLFeature.prototype.readProjection = function(source) { } else if (ol.xml.isNode(source)) { return this.readProjectionFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readProjectionFromDocument(doc); } else { goog.asserts.fail(); diff --git a/src/ol/format/xmlformat.js b/src/ol/format/xmlformat.js index 111bf5f511..11d46fbe6a 100644 --- a/src/ol/format/xmlformat.js +++ b/src/ol/format/xmlformat.js @@ -25,7 +25,7 @@ ol.format.XML.prototype.read = function(source) { } else if (ol.xml.isNode(source)) { return this.readFromNode(/** @type {Node} */ (source)); } else if (goog.isString(source)) { - var doc = ol.xml.load(source); + var doc = ol.xml.parse(source); return this.readFromDocument(doc); } else { goog.asserts.fail(); diff --git a/src/ol/image.js b/src/ol/image.js index 46d2f065c8..e1881c0cae 100644 --- a/src/ol/image.js +++ b/src/ol/image.js @@ -20,9 +20,10 @@ goog.require('ol.extent'); * @param {Array.} attributions Attributions. * @param {string} src Image source URI. * @param {?string} crossOrigin Cross origin. + * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function. */ -ol.Image = - function(extent, resolution, pixelRatio, attributions, src, crossOrigin) { +ol.Image = function(extent, resolution, pixelRatio, attributions, src, + crossOrigin, imageLoadFunction) { goog.base(this, extent, resolution, pixelRatio, ol.ImageState.IDLE, attributions); @@ -59,6 +60,13 @@ ol.Image = * @type {ol.ImageState} */ this.state = ol.ImageState.IDLE; + + /** + * @private + * @type {ol.ImageLoadFunctionType} + */ + this.imageLoadFunction_ = imageLoadFunction; + }; goog.inherits(ol.Image, ol.ImageBase); @@ -66,8 +74,9 @@ goog.inherits(ol.Image, ol.ImageBase); /** * @param {Object=} opt_context Object. * @return {HTMLCanvasElement|Image|HTMLVideoElement} Image. + * @api */ -ol.Image.prototype.getImageElement = function(opt_context) { +ol.Image.prototype.getImage = function(opt_context) { if (goog.isDef(opt_context)) { var image; var key = goog.getUid(opt_context); @@ -126,7 +135,7 @@ ol.Image.prototype.load = function() { goog.events.listenOnce(this.image_, goog.events.EventType.LOAD, this.handleImageLoad_, false, this) ]; - this.image_.src = this.src_; + this.imageLoadFunction_(this, this.src_); } }; diff --git a/src/ol/imagebase.js b/src/ol/imagebase.js index 881c93dd53..5e0a464fbb 100644 --- a/src/ol/imagebase.js +++ b/src/ol/imagebase.js @@ -95,7 +95,7 @@ ol.ImageBase.prototype.getExtent = function() { * @param {Object=} opt_context Object. * @return {HTMLCanvasElement|Image|HTMLVideoElement} Image. */ -ol.ImageBase.prototype.getImageElement = goog.abstractMethod; +ol.ImageBase.prototype.getImage = goog.abstractMethod; /** diff --git a/src/ol/imagecanvas.js b/src/ol/imagecanvas.js index 3cd7ac9f2b..6cc9b7295b 100644 --- a/src/ol/imagecanvas.js +++ b/src/ol/imagecanvas.js @@ -33,6 +33,6 @@ goog.inherits(ol.ImageCanvas, ol.ImageBase); /** * @inheritDoc */ -ol.ImageCanvas.prototype.getImageElement = function(opt_context) { +ol.ImageCanvas.prototype.getImage = function(opt_context) { return this.canvas_; }; diff --git a/src/ol/imageloadfunction.js b/src/ol/imageloadfunction.js new file mode 100644 index 0000000000..0d4b74cda2 --- /dev/null +++ b/src/ol/imageloadfunction.js @@ -0,0 +1,21 @@ +goog.provide('ol.ImageLoadFunctionType'); + + +/** + * A function that takes an {@link ol.Image} for the image and a `{string}` for + * the src as arguments. It is supposed to make it so the underlying image + * {@link ol.Image#getImage} is assigned the content specified by the src. If + * not specified, the default is + * + * function(image, src) { + * image.getImage().src = src; + * } + * + * Providing a custom `imageLoadFunction` can be useful to load images with + * post requests or - in general - through XHR requests, where the src of the + * image element would be set to a data URI when the content is loaded. + * + * @typedef {function(ol.Image, string)} + * @api + */ +ol.ImageLoadFunctionType; diff --git a/src/ol/layer/layer.js b/src/ol/layer/layer.js index 9415c8b05e..6ad78fafc2 100644 --- a/src/ol/layer/layer.js +++ b/src/ol/layer/layer.js @@ -105,13 +105,7 @@ goog.exportProperty( */ ol.layer.Layer.prototype.getSourceState = function() { var source = this.getSource(); - var state; - if (!goog.isNull(source)) { - state = source.getState(); - } else { - state = ol.source.State.UNDEFINED; - } - return state; + return goog.isNull(source) ? ol.source.State.UNDEFINED : source.getState(); }; diff --git a/src/ol/layer/layerbase.js b/src/ol/layer/layerbase.js index ac63c7dc80..a7722e84d2 100644 --- a/src/ol/layer/layerbase.js +++ b/src/ol/layer/layerbase.js @@ -60,30 +60,26 @@ ol.layer.Base = function(options) { goog.base(this); + /** + * @type {Object.} + */ var properties = goog.object.clone(options); - - /** @type {number} */ - properties.brightness = goog.isDef(properties.brightness) ? - properties.brightness : 0; - /** @type {number} */ - properties.contrast = goog.isDef(properties.contrast) ? - properties.contrast : 1; - /** @type {number} */ - properties.hue = goog.isDef(properties.hue) ? properties.hue : 0; - /** @type {number} */ - properties.opacity = goog.isDef(properties.opacity) ? properties.opacity : 1; - /** @type {number} */ - properties.saturation = goog.isDef(properties.saturation) ? - properties.saturation : 1; - /** @type {boolean} */ - properties.visible = goog.isDef(properties.visible) ? - properties.visible : true; - /** @type {number} */ - properties.maxResolution = goog.isDef(properties.maxResolution) ? - properties.maxResolution : Infinity; - /** @type {number} */ - properties.minResolution = goog.isDef(properties.minResolution) ? - properties.minResolution : 0; + properties[ol.layer.LayerProperty.BRIGHTNESS] = + goog.isDef(options.brightness) ? options.brightness : 0; + properties[ol.layer.LayerProperty.CONTRAST] = + goog.isDef(options.contrast) ? options.contrast : 1; + properties[ol.layer.LayerProperty.HUE] = + goog.isDef(options.hue) ? options.hue : 0; + properties[ol.layer.LayerProperty.OPACITY] = + goog.isDef(options.opacity) ? options.opacity : 1; + properties[ol.layer.LayerProperty.SATURATION] = + goog.isDef(options.saturation) ? options.saturation : 1; + properties[ol.layer.LayerProperty.VISIBLE] = + goog.isDef(options.visible) ? options.visible : true; + properties[ol.layer.LayerProperty.MAX_RESOLUTION] = + goog.isDef(options.maxResolution) ? options.maxResolution : Infinity; + properties[ol.layer.LayerProperty.MIN_RESOLUTION] = + goog.isDef(options.minResolution) ? options.minResolution : 0; this.setProperties(properties); }; diff --git a/src/ol/proj/proj.js b/src/ol/proj/proj.js index 0f0f00b166..5ceccdf600 100644 --- a/src/ol/proj/proj.js +++ b/src/ol/proj/proj.js @@ -678,7 +678,7 @@ ol.proj.cloneTransform = function(input, opt_output, opt_dimension) { */ ol.proj.transform = function(coordinate, source, destination) { var transformFn = ol.proj.getTransform(source, destination); - return transformFn(coordinate); + return transformFn(coordinate, undefined, coordinate.length); }; diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js index bfca200597..c223d84f1c 100644 --- a/src/ol/renderer/canvas/canvasimagelayerrenderer.js +++ b/src/ol/renderer/canvas/canvasimagelayerrenderer.js @@ -69,7 +69,7 @@ ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtPixel = */ ol.renderer.canvas.ImageLayer.prototype.getImage = function() { return goog.isNull(this.image_) ? - null : this.image_.getImageElement(); + null : this.image_.getImage(); }; diff --git a/src/ol/renderer/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js index 46242e14db..ce2ca367c7 100644 --- a/src/ol/renderer/dom/domimagelayerrenderer.js +++ b/src/ol/renderer/dom/domimagelayerrenderer.js @@ -129,7 +129,7 @@ ol.renderer.dom.ImageLayer.prototype.prepareFrame = (imageExtent[0] - viewCenter[0]) / imageResolution, (viewCenter[1] - imageExtent[3]) / imageResolution); if (image != this.image_) { - var imageElement = image.getImageElement(this); + var imageElement = image.getImage(this); // Bootstrap sets the style max-width: 100% for all images, which breaks // prevents the image from being displayed in FireFox. Workaround by // overriding the max-width style. diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js index 9b093e7e44..a29cbd0d4d 100644 --- a/src/ol/renderer/webgl/webglimagelayerrenderer.js +++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js @@ -48,7 +48,7 @@ ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) { // http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support // http://learningwebgl.com/blog/?p=2101 - var imageElement = image.getImageElement(); + var imageElement = image.getImage(); var gl = this.getWebGLMapRenderer().getGL(); var texture = gl.createTexture(); diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js index 81b0dd7e9b..1ceba4d297 100644 --- a/src/ol/source/formatvectorsource.js +++ b/src/ol/source/formatvectorsource.js @@ -91,7 +91,7 @@ ol.source.FormatVector.prototype.loadFeaturesFromURL = source = xhrIo.getResponseXml(); } if (!goog.isDefAndNotNull(source)) { - source = ol.xml.load(xhrIo.getResponseText()); + source = ol.xml.parse(xhrIo.getResponseText()); } } else { goog.asserts.fail(); diff --git a/src/ol/source/imagemapguidesource.js b/src/ol/source/imagemapguidesource.js index 27c7adac6a..3d7c18f11f 100644 --- a/src/ol/source/imagemapguidesource.js +++ b/src/ol/source/imagemapguidesource.js @@ -3,6 +3,7 @@ goog.provide('ol.source.ImageMapGuide'); goog.require('goog.object'); goog.require('goog.uri.utils'); goog.require('ol.Image'); +goog.require('ol.ImageLoadFunctionType'); goog.require('ol.ImageUrlFunction'); goog.require('ol.extent'); goog.require('ol.source.Image'); @@ -59,6 +60,13 @@ ol.source.ImageMapGuide = function(options) { */ this.imageUrlFunction_ = imageUrlFunction; + /** + * @private + * @type {ol.ImageLoadFunctionType} + */ + this.imageLoadFunction_ = goog.isDef(options.imageLoadFunction) ? + options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction; + /** * @private * @type {boolean} @@ -140,7 +148,8 @@ ol.source.ImageMapGuide.prototype.getImage = var imageUrl = this.imageUrlFunction_(extent, size, projection); if (goog.isDef(imageUrl)) { image = new ol.Image(extent, resolution, pixelRatio, - this.getAttributions(), imageUrl, this.crossOrigin_); + this.getAttributions(), imageUrl, this.crossOrigin_, + this.imageLoadFunction_); } else { image = null; } diff --git a/src/ol/source/imagesource.js b/src/ol/source/imagesource.js index 427359ed15..6cab2fe42d 100644 --- a/src/ol/source/imagesource.js +++ b/src/ol/source/imagesource.js @@ -88,3 +88,14 @@ ol.source.Image.prototype.findNearestResolution = * @return {ol.ImageBase} Single image. */ ol.source.Image.prototype.getImage = goog.abstractMethod; + + +/** + * Default image load function for image sources that use ol.Image image + * instances. + * @param {ol.Image} image Image. + * @param {string} src Source. + */ +ol.source.Image.defaultImageLoadFunction = function(image, src) { + image.getImage().src = src; +}; diff --git a/src/ol/source/imagestaticsource.js b/src/ol/source/imagestaticsource.js index 4aea4b4b81..bdc4e14d07 100644 --- a/src/ol/source/imagestaticsource.js +++ b/src/ol/source/imagestaticsource.js @@ -34,6 +34,9 @@ ol.source.ImageStatic = function(options) { var crossOrigin = goog.isDef(options.crossOrigin) ? options.crossOrigin : null; + var imageLoadFunction = goog.isDef(options.imageLoadFunction) ? + options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction; + goog.base(this, { attributions: attributions, logo: options.logo, @@ -46,7 +49,7 @@ ol.source.ImageStatic = function(options) { * @type {ol.Image} */ this.image_ = new ol.Image(imageExtent, resolution, 1, attributions, - options.url, crossOrigin); + options.url, crossOrigin, imageLoadFunction); }; goog.inherits(ol.source.ImageStatic, ol.source.Image); diff --git a/src/ol/source/imagewmssource.js b/src/ol/source/imagewmssource.js index 05c162a141..4ba801d895 100644 --- a/src/ol/source/imagewmssource.js +++ b/src/ol/source/imagewmssource.js @@ -8,6 +8,7 @@ goog.require('goog.string'); goog.require('goog.uri.utils'); goog.require('ol'); goog.require('ol.Image'); +goog.require('ol.ImageLoadFunctionType'); goog.require('ol.extent'); goog.require('ol.proj'); goog.require('ol.source.Image'); @@ -49,6 +50,13 @@ ol.source.ImageWMS = function(opt_options) { */ this.url_ = options.url; + /** + * @private + * @type {ol.ImageLoadFunctionType} + */ + this.imageLoadFunction_ = goog.isDef(options.imageLoadFunction) ? + options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction; + /** * @private * @type {Object} @@ -235,7 +243,7 @@ ol.source.ImageWMS.prototype.getImage = projection, params); this.image_ = new ol.Image(extent, resolution, pixelRatio, - this.getAttributions(), url, this.crossOrigin_); + this.getAttributions(), url, this.crossOrigin_, this.imageLoadFunction_); this.renderedRevision_ = this.getRevision(); diff --git a/src/ol/source/tilejsonsource.js b/src/ol/source/tilejsonsource.js index 0c4b4a6d5d..92982e18fc 100644 --- a/src/ol/source/tilejsonsource.js +++ b/src/ol/source/tilejsonsource.js @@ -39,6 +39,12 @@ ol.source.TileJSON = function(options) { tileLoadFunction: options.tileLoadFunction }); + /** + * @type {boolean|undefined} + * @private + */ + this.wrapX_ = options.wrapX; + var request = new goog.net.Jsonp(options.url); request.send(undefined, goog.bind(this.handleTileJSONResponse, this)); @@ -76,7 +82,8 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) { this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform( tileGrid.createTileCoordTransform({ - extent: extent + extent: extent, + wrapX: this.wrapX_ }), ol.TileUrlFunction.createFromTemplates(tileJSON.tiles)); diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js index 0d37688c8c..8581772b72 100644 --- a/src/ol/source/wmtssource.js +++ b/src/ol/source/wmtssource.js @@ -59,7 +59,8 @@ ol.source.WMTS = function(options) { // FIXME: should we guess this requestEncoding from options.url(s) // structure? that would mean KVP only if a template is not provided. var requestEncoding = goog.isDef(options.requestEncoding) ? - options.requestEncoding : ol.source.WMTSRequestEncoding.KVP; + /** @type {ol.source.WMTSRequestEncoding} */ (options.requestEncoding) : + ol.source.WMTSRequestEncoding.KVP; // FIXME: should we create a default tileGrid? // we could issue a getCapabilities xhr to retrieve missing configuration diff --git a/src/ol/structs/rbush.js b/src/ol/structs/rbush.js index f7c650aa8c..baa0e3a1f1 100644 --- a/src/ol/structs/rbush.js +++ b/src/ol/structs/rbush.js @@ -1,5 +1,3 @@ -// FIXME bulk inserts - goog.provide('ol.structs.RBush'); goog.require('goog.array'); diff --git a/src/ol/style/regularshapestyle.js b/src/ol/style/regularshapestyle.js new file mode 100644 index 0000000000..74850f1225 --- /dev/null +++ b/src/ol/style/regularshapestyle.js @@ -0,0 +1,299 @@ +goog.provide('ol.style.RegularShape'); + +goog.require('goog.dom'); +goog.require('goog.dom.TagName'); +goog.require('ol.color'); +goog.require('ol.render.canvas'); +goog.require('ol.style.Fill'); +goog.require('ol.style.Image'); +goog.require('ol.style.ImageState'); +goog.require('ol.style.Stroke'); + + + +/** + * @classdesc + * Set regular shape style for vector features. + * + * @constructor + * @param {olx.style.RegularShapeOptions=} opt_options Options. + * @extends {ol.style.Image} + * @api + */ +ol.style.RegularShape = function(opt_options) { + + var options = goog.isDef(opt_options) ? opt_options : {}; + + /** + * @private + * @type {HTMLCanvasElement} + */ + this.canvas_ = /** @type {HTMLCanvasElement} */ + (goog.dom.createElement(goog.dom.TagName.CANVAS)); + + /** + * @private + * @type {HTMLCanvasElement} + */ + this.hitDetectionCanvas_ = null; + + /** + * @private + * @type {ol.style.Fill} + */ + this.fill_ = goog.isDef(options.fill) ? options.fill : null; + + /** + * @private + * @type {Array.} + */ + this.origin_ = [0, 0]; + + /** + * @private + * @type {number} + */ + this.points_ = options.points; + + /** + * @private + * @type {number} + */ + this.radius_ = options.radius; + + /** + * @private + * @type {number} + */ + this.radius2_ = + goog.isDef(options.radius2) ? options.radius2 : options.radius; + + /** + * @private + * @type {number} + */ + this.angle_ = goog.isDef(options.angle) ? options.angle : 0; + + /** + * @private + * @type {ol.style.Stroke} + */ + this.stroke_ = goog.isDef(options.stroke) ? options.stroke : null; + + var size = this.render_(); + + /** + * @private + * @type {Array.} + */ + this.anchor_ = [size / 2, size / 2]; + + /** + * @private + * @type {ol.Size} + */ + this.size_ = [size, size]; + + /** + * @type {boolean} + */ + var snapToPixel = goog.isDef(options.snapToPixel) ? + options.snapToPixel : true; + + goog.base(this, { + opacity: 1, + rotateWithView: false, + rotation: 0, + scale: 1, + snapToPixel: snapToPixel + }); + +}; +goog.inherits(ol.style.RegularShape, ol.style.Image); + + +/** + * @inheritDoc + * @api + */ +ol.style.RegularShape.prototype.getAnchor = function() { + return this.anchor_; +}; + + +/** + * @return {ol.style.Fill} Fill style. + * @api + */ +ol.style.RegularShape.prototype.getFill = function() { + return this.fill_; +}; + + +/** + * @inheritDoc + */ +ol.style.RegularShape.prototype.getHitDetectionImage = function(pixelRatio) { + return this.hitDetectionCanvas_; +}; + + +/** + * @inheritDoc + * @api + */ +ol.style.RegularShape.prototype.getImage = function(pixelRatio) { + return this.canvas_; +}; + + +/** + * @inheritDoc + */ +ol.style.RegularShape.prototype.getImageState = function() { + return ol.style.ImageState.LOADED; +}; + + +/** + * @inheritDoc + * @api + */ +ol.style.RegularShape.prototype.getOrigin = function() { + return this.origin_; +}; + + +/** + * @return {number} Radius. + * @api + */ +ol.style.RegularShape.prototype.getRadius = function() { + return this.radius_; +}; + + +/** + * @inheritDoc + * @api + */ +ol.style.RegularShape.prototype.getSize = function() { + return this.size_; +}; + + +/** + * @return {ol.style.Stroke} Stroke style. + * @api + */ +ol.style.RegularShape.prototype.getStroke = function() { + return this.stroke_; +}; + + +/** + * @inheritDoc + */ +ol.style.RegularShape.prototype.listenImageChange = goog.nullFunction; + + +/** + * @inheritDoc + */ +ol.style.RegularShape.prototype.load = goog.nullFunction; + + +/** + * @inheritDoc + */ +ol.style.RegularShape.prototype.unlistenImageChange = goog.nullFunction; + + +/** + * @private + * @return {number} Size. + */ +ol.style.RegularShape.prototype.render_ = function() { + var canvas = this.canvas_; + var strokeStyle, strokeWidth; + + if (goog.isNull(this.stroke_)) { + strokeWidth = 0; + } else { + strokeStyle = ol.color.asString(this.stroke_.getColor()); + strokeWidth = this.stroke_.getWidth(); + if (!goog.isDef(strokeWidth)) { + strokeWidth = ol.render.canvas.defaultLineWidth; + } + } + + var size = 2 * (this.radius_ + strokeWidth) + 1; + + // draw the regular shape on the canvas + + canvas.height = size; + canvas.width = size; + + // canvas.width and height are rounded to the closest integer + size = canvas.width; + + var context = /** @type {CanvasRenderingContext2D} */ + (canvas.getContext('2d')); + var i, angle0, radiusC; + context.beginPath(); + if (this.radius2_ !== this.radius_) { + this.points_ = 2 * this.points_; + } + for (i = 0; i <= this.points_; i++) { + angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; + radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; + context.lineTo(size / 2 + radiusC * Math.cos(angle0), + size / 2 + radiusC * Math.sin(angle0)); + } + + if (!goog.isNull(this.fill_)) { + context.fillStyle = ol.color.asString(this.fill_.getColor()); + context.fill(); + } + if (!goog.isNull(this.stroke_)) { + context.strokeStyle = strokeStyle; + context.lineWidth = strokeWidth; + context.stroke(); + } + + // deal with the hit detection canvas + + if (!goog.isNull(this.fill_)) { + this.hitDetectionCanvas_ = canvas; + } else { + this.hitDetectionCanvas_ = /** @type {HTMLCanvasElement} */ + (goog.dom.createElement(goog.dom.TagName.CANVAS)); + canvas = this.hitDetectionCanvas_; + + canvas.height = size; + canvas.width = size; + + context = /** @type {CanvasRenderingContext2D} */ + (canvas.getContext('2d')); + context.beginPath(); + if (this.radius2_ !== this.radius_) { + this.points_ = 2 * this.points_; + } + for (i = 0; i <= this.points_; i++) { + angle0 = i * 2 * Math.PI / this.points_ - Math.PI / 2 + this.angle_; + radiusC = i % 2 === 0 ? this.radius_ : this.radius2_; + context.lineTo(size / 2 + radiusC * Math.cos(angle0), + size / 2 + radiusC * Math.sin(angle0)); + } + + context.fillStyle = ol.render.canvas.defaultFillStyle; + context.fill(); + if (!goog.isNull(this.stroke_)) { + context.strokeStyle = strokeStyle; + context.lineWidth = strokeWidth; + context.stroke(); + } + } + + return size; +}; diff --git a/src/ol/xml.js b/src/ol/xml.js index be03cdda9a..8f7662da4d 100644 --- a/src/ol/xml.js +++ b/src/ol/xml.js @@ -77,9 +77,12 @@ ol.xml.createElementNS = /** + * Recursively grab all text content of child nodes into a single string. * @param {Node} node Node. - * @param {boolean} normalizeWhitespace Normalize whitespace. + * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line + * breaks. * @return {string} All text content. + * @api */ ol.xml.getAllTextContent = function(node, normalizeWhitespace) { return ol.xml.getAllTextContent_(node, normalizeWhitespace, []).join(''); @@ -88,7 +91,8 @@ ol.xml.getAllTextContent = function(node, normalizeWhitespace) { /** * @param {Node} node Node. - * @param {boolean} normalizeWhitespace Normalize whitespace. + * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line + * breaks. * @param {Array.} accumulator Accumulator. * @private * @return {Array.} Accumulator. @@ -332,10 +336,12 @@ ol.xml.setAttributeNS = /** + * Parse an XML string to a XML Document * @param {string} xml XML. * @return {Document} Document. + * @api */ -ol.xml.load = function(xml) { +ol.xml.parse = function(xml) { return new DOMParser().parseFromString(xml, 'application/xml'); }; @@ -379,7 +385,8 @@ ol.xml.makeArrayPusher = function(valueReader, opt_this) { * @param {Array.<*>} objectStack Object stack. */ function(node, objectStack) { - var value = valueReader.call(opt_this, node, objectStack); + var value = valueReader.call(goog.isDef(opt_this) ? opt_this : this, + node, objectStack); if (goog.isDef(value)) { var array = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isArray(array)); @@ -402,7 +409,8 @@ ol.xml.makeReplacer = function(valueReader, opt_this) { * @param {Array.<*>} objectStack Object stack. */ function(node, objectStack) { - var value = valueReader.call(opt_this, node, objectStack); + var value = valueReader.call(goog.isDef(opt_this) ? opt_this : this, + node, objectStack); if (goog.isDef(value)) { objectStack[objectStack.length - 1] = value; } @@ -426,7 +434,8 @@ ol.xml.makeObjectPropertyPusher = * @param {Array.<*>} objectStack Object stack. */ function(node, objectStack) { - var value = valueReader.call(opt_this, node, objectStack); + var value = valueReader.call(goog.isDef(opt_this) ? opt_this : this, + node, objectStack); if (goog.isDef(value)) { var object = /** @type {Object} */ (objectStack[objectStack.length - 1]); @@ -456,7 +465,8 @@ ol.xml.makeObjectPropertySetter = * @param {Array.<*>} objectStack Object stack. */ function(node, objectStack) { - var value = valueReader.call(opt_this, node, objectStack); + var value = valueReader.call(goog.isDef(opt_this) ? opt_this : this, + node, objectStack); if (goog.isDef(value)) { var object = /** @type {Object} */ (objectStack[objectStack.length - 1]); @@ -494,7 +504,8 @@ ol.xml.makeParsersNS = function(namespaceURIs, parsers, opt_parsersNS) { */ ol.xml.makeChildAppender = function(nodeWriter, opt_this) { return function(node, value, objectStack) { - nodeWriter.call(opt_this, node, value, objectStack); + nodeWriter.call(goog.isDef(opt_this) ? opt_this : this, + node, value, objectStack); var parent = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(parent)); var parentNode = parent.node; @@ -636,7 +647,7 @@ ol.xml.makeStructureNS = function(namespaceURIs, structure, opt_structureNS) { * @param {Array.<*>} objectStack Object stack. * @param {*=} opt_this The object to use as `this`. */ -ol.xml.parse = function(parsersNS, node, objectStack, opt_this) { +ol.xml.parseNode = function(parsersNS, node, objectStack, opt_this) { var n; for (n = node.firstElementChild; !goog.isNull(n); n = n.nextElementSibling) { var parsers = parsersNS[n.namespaceURI]; @@ -663,7 +674,7 @@ ol.xml.parse = function(parsersNS, node, objectStack, opt_this) { ol.xml.pushParseAndPop = function( object, parsersNS, node, objectStack, opt_this) { objectStack.push(object); - ol.xml.parse(parsersNS, node, objectStack, opt_this); + ol.xml.parseNode(parsersNS, node, objectStack, opt_this); return objectStack.pop(); }; diff --git a/test/spec/ol/format/gmlformat.test.js b/test/spec/ol/format/gmlformat.test.js index 9b52a4541a..3aeece75f5 100644 --- a/test/spec/ol/format/gmlformat.test.js +++ b/test/spec/ol/format/gmlformat.test.js @@ -1,19 +1,119 @@ goog.provide('ol.test.format.GML'); var readGeometry = function(format, text, opt_options) { - var doc = ol.xml.load(text); + var doc = ol.xml.parse(text); // we need an intermediate node for testing purposes var node = goog.dom.createElement(goog.dom.TagName.PRE); node.appendChild(doc.documentElement); return format.readGeometryFromNode(node, opt_options); }; -describe('ol.format.GML', function() { +describe('ol.format.GML2', function() { + + var format, formatWGS84, formatNoSrs; + beforeEach(function() { + format = new ol.format.GML2({srsName: 'CRS:84'}); + formatWGS84 = new ol.format.GML2({ + srsName: 'urn:x-ogc:def:crs:EPSG:4326' + }); + formatNoSrs = new ol.format.GML2(); + }); + + + describe('#readGeometry', function() { + + describe('gml 2.1.2', function() { + + it('can read a point geometry', function() { + var text = '' + + ' -90,-180' + + ''; + + var g = readGeometry(format, text); + expect(g).to.be.an(ol.geom.Point); + expect(g.getCoordinates()).to.eql([-180, -90, 0]); + }); + + it('can read a box element', function() { + var text = '' + + ' -0.768746,47.003018 ' + + ' 3.002191,47.925567' + + ''; + + var g = readGeometry(format, text); + expect(g).to.eql([47.003018, -0.768746, 47.925567, 3.002191]); + }); + + it('can read a multipolygon with gml:coordinates', function() { + + var text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' -0.318987,47.003018 ' + + ' -0.768746,47.358268 ' + + ' -0.574463,47.684285 -0.347374,47.854602 ' + + ' -0.006740,47.925567 ' + + ' 0.135191,47.726864 0.149384,47.599127 0.419052,' + + ' 47.670092 0.532597,47.428810 ' + + ' 0.305508,47.443003 0.475824,47.144948 0.064225,' + + ' 47.201721 ' + + ' -0.318987,47.003018 ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' -0.035126,47.485582 -0.035126,' + + ' 47.485582 ' + + ' -0.049319,47.641706 -0.233829,47.655899 ' + + ' -0.375760,47.457196 ' + + ' -0.276408,47.286879 -0.035126,47.485582 ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + + var g = readGeometry(format, text); + expect(g).to.be.an(ol.geom.MultiPolygon); + expect(g.getCoordinates()).to.eql([ + [ + [ + [47.003018, -0.318987, 0], [47.358268, -0.768746, 0], + [47.684285, -0.574463, 0], [47.854602, -0.347374, 0], + [47.925567, -0.00674, 0], [47.726864, 0.135191, 0], + [47.599127, 0.149384, 0], [47.670092, 0.419052, 0], + [47.42881, 0.532597, 0], [47.443003, 0.305508, 0], + [47.144948, 0.475824, 0], [47.201721, 0.064225, 0], + [47.003018, -0.318987, 0] + ], + [ + [47.485582, -0.035126, 0], [47.485582, -0.035126, 0], + [47.641706, -0.049319, 0], [47.655899, -0.233829, 0], + [47.457196, -0.37576, 0], [47.286879, -0.276408, 0], + [47.485582, -0.035126, 0] + ] + ] + ]); + }); + }); + }); +}); + +describe('ol.format.GML3', function() { var format, formatWGS84, formatNoSrs; beforeEach(function() { format = new ol.format.GML({srsName: 'CRS:84'}); - formatWGS84 = new ol.format.GML({srsName: 'urn:x-ogc:def:crs:EPSG:4326'}); + formatWGS84 = new ol.format.GML({ + srsName: 'urn:x-ogc:def:crs:EPSG:4326' + }); formatNoSrs = new ol.format.GML(); }); @@ -31,7 +131,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.Point); expect(g.getCoordinates()).to.eql([1, 2, 0]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read a point geometry with scientific notation', function() { @@ -101,7 +201,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.Point); expect(g.getCoordinates()).to.eql([1, 2, 0]); var serialized = formatWGS84.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -118,7 +218,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.LineString); expect(g.getCoordinates()).to.eql([[1, 2, 0], [3, 4, 0]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read, transform and write a linestring geometry', function() { @@ -157,7 +257,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.LineString); expect(g.getCoordinates()).to.eql([[1, 2, 0], [3, 4, 0]]); var serialized = formatWGS84.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -175,7 +275,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.LineString); expect(g.getCoordinates()).to.eql([[-180, -90, 0], [180, 90, 0]]); var serialized = formatWGS84.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read and write a point geometry with correct axis order', @@ -189,7 +289,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.Point); expect(g.getCoordinates()).to.eql([-180, -90, 0]); var serialized = formatWGS84.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read and write a surface geometry with right axis order', @@ -216,10 +316,11 @@ describe('ol.format.GML', function() { var g = readGeometry(format, text); expect(g.getCoordinates()[0][0][0][0]).to.equal(-77.0081); expect(g.getCoordinates()[0][0][0][1]).to.equal(38.9661); - format = new ol.format.GML({srsName: 'urn:x-ogc:def:crs:EPSG:4326', + format = new ol.format.GML({ + srsName: 'urn:x-ogc:def:crs:EPSG:4326', surface: false}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -252,7 +353,7 @@ describe('ol.format.GML', function() { expect(g.getCoordinates()).to.eql( [[1, 2, 0], [3, 4, 0], [5, 6, 0], [1, 2, 0]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -285,7 +386,7 @@ describe('ol.format.GML', function() { [1, 2, 0]], [[2, 3, 0], [2, 5, 0], [4, 5, 0], [2, 3, 0]], [[3, 4, 0], [3, 6, 0], [5, 6, 0], [3, 4, 0]]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -323,7 +424,7 @@ describe('ol.format.GML', function() { [[3, 4, 0], [3, 6, 0], [5, 6, 0], [3, 4, 0]]]); format = new ol.format.GML({srsName: 'CRS:84', surface: true}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -345,7 +446,7 @@ describe('ol.format.GML', function() { expect(g.getCoordinates()).to.eql([[1, 2, 0], [3, 4, 0]]); format = new ol.format.GML({srsName: 'CRS:84', curve: true}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -391,7 +492,7 @@ describe('ol.format.GML', function() { expect(g).to.be.an(ol.geom.MultiPoint); expect(g.getCoordinates()).to.eql([[1, 2, 0], [2, 3, 0], [3, 4, 0]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read a plural multipoint geometry', function() { @@ -440,7 +541,7 @@ describe('ol.format.GML', function() { [[[1, 2, 0], [2, 3, 0]], [[3, 4, 0], [4, 5, 0]]]); format = new ol.format.GML({srsName: 'CRS:84', multiCurve: false}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read a plural multilinestring geometry', function() { @@ -508,7 +609,7 @@ describe('ol.format.GML', function() { [[[1, 2, 0], [3, 2, 0], [3, 4, 0], [1, 2, 0]]]]); format = new ol.format.GML({srsName: 'CRS:84', multiSurface: false}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read a plural multipolygon geometry', function() { @@ -576,7 +677,7 @@ describe('ol.format.GML', function() { expect(g.getCoordinates()).to.eql( [[[1, 2, 0], [2, 3, 0]], [[3, 4, 0], [4, 5, 0]]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read and write a singular multicurve-curve geometry', function() { @@ -608,7 +709,7 @@ describe('ol.format.GML', function() { [[[1, 2, 0], [2, 3, 0]], [[3, 4, 0], [4, 5, 0]]]); format = new ol.format.GML({srsName: 'CRS:84', curve: true}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -656,7 +757,7 @@ describe('ol.format.GML', function() { [[3, 4, 0], [3, 6, 0], [5, 6, 0], [3, 4, 0]]], [[[1, 2, 0], [3, 2, 0], [3, 4, 0], [1, 2, 0]]]]); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); it('can read a plural multisurface geometry', function() { @@ -751,7 +852,7 @@ describe('ol.format.GML', function() { [[[1, 2, 0], [3, 2, 0], [3, 4, 0], [1, 2, 0]]]]); format = new ol.format.GML({srsName: 'CRS:84', surface: true}); var serialized = format.writeGeometry(g); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -878,7 +979,7 @@ describe('ol.format.GML', function() { it('writes back features as GML', function() { this.timeout(4000); var serialized = gmlFormat.writeFeatures(features); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -971,6 +1072,8 @@ describe('ol.format.GML', function() { goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('ol.format.GML'); +goog.require('ol.format.GML2'); +goog.require('ol.format.GML3'); goog.require('ol.geom.LineString'); goog.require('ol.geom.LinearRing'); goog.require('ol.geom.MultiPoint'); diff --git a/test/spec/ol/format/gpxformat.test.js b/test/spec/ol/format/gpxformat.test.js index d26b101553..482a640856 100644 --- a/test/spec/ol/format/gpxformat.test.js +++ b/test/spec/ol/format/gpxformat.test.js @@ -56,7 +56,7 @@ describe('ol.format.GPX', function() { expect(f.get('number')).to.be(1); expect(f.get('type')).to.be('Type'); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a rte with multiple rtepts', function() { @@ -76,7 +76,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([[2, 1, 0, 0], [4, 3, 0, 0]]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can transform, read and write a rte', function() { @@ -104,7 +104,7 @@ describe('ol.format.GPX', function() { var serialized = format.writeFeatures(fs, { featureProjection: 'EPSG:3857' }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -156,7 +156,7 @@ describe('ol.format.GPX', function() { expect(f.get('number')).to.be(1); expect(f.get('type')).to.be('Type'); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a trk with an empty trkseg', function() { @@ -175,7 +175,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([[]]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read/write a trk with a trkseg with multiple trkpts', function() { @@ -205,7 +205,7 @@ describe('ol.format.GPX', function() { ]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can tranform, read and write a trk with a trkseg', function() { @@ -241,7 +241,7 @@ describe('ol.format.GPX', function() { var serialized = format.writeFeatures(fs, { featureProjection: 'EPSG:3857' }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a trk with multiple trksegs', function() { @@ -282,7 +282,7 @@ describe('ol.format.GPX', function() { ]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -303,7 +303,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([2, 1, 0, 0]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can transform, read and write a wpt', function() { @@ -326,7 +326,7 @@ describe('ol.format.GPX', function() { var serialized = format.writeFeatures(fs, { featureProjection: 'EPSG:3857' }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a wpt with ele', function() { @@ -345,7 +345,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([2, 1, 3, 0]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a wpt with time', function() { @@ -364,7 +364,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([2, 1, 0, 1263115752]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write a wpt with ele and time', function() { @@ -384,7 +384,7 @@ describe('ol.format.GPX', function() { expect(g.getCoordinates()).to.eql([2, 1, 3, 1263115752]); expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('can read and write various wpt attributes', function() { @@ -434,7 +434,7 @@ describe('ol.format.GPX', function() { expect(f.get('ageofdgpsdata')).to.be(9); expect(f.get('dgpsid')).to.be(10); var serialized = format.writeFeatures(fs); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); diff --git a/test/spec/ol/format/kmlformat.test.js b/test/spec/ol/format/kmlformat.test.js index 83b32c4a72..8267cfe1ce 100644 --- a/test/spec/ol/format/kmlformat.test.js +++ b/test/spec/ol/format/kmlformat.test.js @@ -47,7 +47,7 @@ describe('ol.format.KML', function() { ' https://developers.google.com/kml/schema/kml22gx.xsd">' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write a Feature\'s id', function() { @@ -63,7 +63,7 @@ describe('ol.format.KML', function() { ' https://developers.google.com/kml/schema/kml22gx.xsd">' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); }); @@ -94,7 +94,7 @@ describe('ol.format.KML', function() { ' https://developers.google.com/kml/schema/kml22gx.xsd">' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read Point geometries', function() { @@ -206,7 +206,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZ Point geometries', function() { @@ -226,7 +226,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can transform and write XYZ Point geometries', function() { @@ -258,7 +258,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); ol.proj.removeTransform( ol.proj.get('EPSG:4326'), ol.proj.get('double')); @@ -283,7 +283,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZM Point geometries', function() { @@ -303,7 +303,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read LineString geometries', function() { @@ -341,7 +341,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZ LineString geometries', function() { @@ -362,7 +362,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYM LineString geometries', function() { @@ -383,7 +383,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZM LineString geometries', function() { @@ -404,7 +404,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read LinearRing geometries', function() { @@ -443,7 +443,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZ LinearRing geometries', function() { @@ -464,7 +464,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYM LinearRing geometries', function() { @@ -485,7 +485,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZM LinearRing geometries', function() { @@ -506,7 +506,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read Polygon geometries', function() { @@ -554,7 +554,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZ Polygon geometries', function() { @@ -581,7 +581,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYM Polygon geometries', function() { @@ -608,7 +608,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write XYZM Polygon geometries', function() { @@ -634,7 +634,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read complex Polygon geometries', function() { @@ -706,7 +706,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read MultiPoint geometries', function() { @@ -755,7 +755,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read MultiLineString geometries', function() { @@ -805,7 +805,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read MultiPolygon geometries', function() { @@ -873,7 +873,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can read empty GeometryCollection geometries', function() { @@ -1140,7 +1140,7 @@ describe('ol.format.KML', function() { ' My description' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write Feature\'s boolean attributes', function() { @@ -1160,7 +1160,7 @@ describe('ol.format.KML', function() { ' 0' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); }); @@ -1608,7 +1608,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write an feature\'s text style', function() { @@ -1640,7 +1640,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write an feature\'s stroke style', function() { @@ -1668,7 +1668,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); it('can write an feature\'s fill style', function() { @@ -1694,7 +1694,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); }); @@ -2210,7 +2210,7 @@ describe('ol.format.KML', function() { ' ' + ' ' + ''; - expect(node).to.xmleql(ol.xml.load(text)); + expect(node).to.xmleql(ol.xml.parse(text)); }); }); diff --git a/test/spec/ol/format/owsformat.test.js b/test/spec/ol/format/owsformat.test.js index d79c7439fb..03adf24096 100644 --- a/test/spec/ol/format/owsformat.test.js +++ b/test/spec/ol/format/owsformat.test.js @@ -7,7 +7,7 @@ describe('ol.format.OWS 1.1', function() { var parser = new ol.format.OWS(); it('should read ServiceProvider tag properly', function() { - var doc = ol.xml.load( + var doc = ol.xml.parse( '' + '' + @@ -56,7 +56,7 @@ describe('ol.format.OWS 1.1', function() { }); it('should read ServiceIdentification tag properly', function() { - var doc = ol.xml.load( + var doc = ol.xml.parse( '' + '' + @@ -86,7 +86,7 @@ describe('ol.format.OWS 1.1', function() { }); it('should read OperationsMetadata tag properly', function() { - var doc = ol.xml.load( + var doc = ol.xml.parse( '' + '' + diff --git a/test/spec/ol/format/wfs/polygonv2.xml b/test/spec/ol/format/wfs/polygonv2.xml new file mode 100644 index 0000000000..a8140cdf36 --- /dev/null +++ b/test/spec/ol/format/wfs/polygonv2.xml @@ -0,0 +1,89 @@ + + + + + -0.768746,47.003018 3.002191,47.925567 + + + + + + + -0.768746,47.003018 0.532597,47.925567 + + + + + + + + + -0.318987,47.003018 -0.768746,47.358268 -0.574463,47.684285 -0.347374,47.854602 -0.006740,47.925567 0.135191,47.726864 0.149384,47.599127 0.419052,47.670092 0.532597,47.428810 0.305508,47.443003 0.475824,47.144948 0.064225,47.201721 -0.318987,47.003018 + + + + + -0.035126,47.485582 -0.035126,47.485582 -0.049319,47.641706 -0.233829,47.655899 -0.375760,47.457196 -0.276408,47.286879 -0.035126,47.485582 + + + + + + + 1 + My Polygon with hole + 0 + + + + + + + 1.511919,47.088176 3.002191,47.882988 + + + + + + + 1.625463,47.357844 1.511919,47.741057 1.880938,47.882988 2.420275,47.797830 2.789295,47.485582 3.002191,47.457196 2.874453,47.088176 2.178993,47.343651 1.625463,47.357844 + + + + + 2 + My simple Polygon + 0 + + + + + + + 0.000000,45.000000 2.000000,47.000000 + + + + + + + + + 0.000000,45.000000 2.000000,45.000000 2.000000,47.000000 0.000000,47.000000 0.000000,45.000000 + + + + + 0.500000,45.500000 1.500000,45.500000 1.500000,46.500000 0.500000,46.500000 0.500000,45.500000 + + + + + + + 3 + my polygon with hole + 3 + + + \ No newline at end of file diff --git a/test/spec/ol/format/wfsformat.test.js b/test/spec/ol/format/wfsformat.test.js index a68e3b1e55..06f1686986 100644 --- a/test/spec/ol/format/wfsformat.test.js +++ b/test/spec/ol/format/wfsformat.test.js @@ -50,6 +50,45 @@ describe('ol.format.WFS', function() { }); + describe('when parsing mapserver GML2 polygon', function() { + + var features, feature, xml; + var config = { + 'featureNS': 'http://mapserver.gis.umn.edu/mapserver', + 'featureType': 'polygon', + 'gmlFormat': new ol.format.GML2() + }; + + before(function(done) { + proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326')); + afterLoadText('spec/ol/format/wfs/polygonv2.xml', function(data) { + try { + xml = data; + features = new ol.format.WFS(config).readFeatures(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('creates 3 features', function() { + expect(features).to.have.length(3); + }); + + it('creates a polygon for My Polygon with hole', function() { + feature = features[0]; + expect(feature.getId()).to.equal('1'); + expect(feature.get('name')).to.equal('My Polygon with hole'); + expect(feature.get('boundedBy')).to.eql( + [47.003018, -0.768746, 47.925567, 0.532597]); + expect(feature.getGeometry()).to.be.an(ol.geom.MultiPolygon); + expect(feature.getGeometry().getFlatCoordinates()). + to.have.length(60); + }); + + }); + describe('when parsing FeatureCollection', function() { var response; before(function(done) { @@ -140,7 +179,7 @@ describe('ol.format.WFS', function() { srsName: 'urn:ogc:def:crs:EPSG::4326', propertyNames: ['STATE_NAME', 'STATE_FIPS', 'STATE_ABBR'] }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('creates paging headers', function() { @@ -165,7 +204,7 @@ describe('ol.format.WFS', function() { featurePrefix: 'topp', featureTypes: ['states'] }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); it('creates a BBOX filter', function() { @@ -192,7 +231,7 @@ describe('ol.format.WFS', function() { geometryName: 'the_geom', bbox: [1, 2, 3, 4] }); - expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); + expect(serialized.firstElementChild).to.xmleql(ol.xml.parse(text)); }); }); @@ -208,7 +247,7 @@ describe('ol.format.WFS', function() { 'http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"/>'; var serialized = new ol.format.WFS().writeTransaction(null, null, null, {handle: 'handle_t'}); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -239,7 +278,7 @@ describe('ol.format.WFS', function() { featurePrefix: 'feature', gmlOptions: {multiCurve: true, srsName: 'EPSG:900913'} }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -270,7 +309,7 @@ describe('ol.format.WFS', function() { featurePrefix: 'foo', gmlOptions: {srsName: 'EPSG:900913'} }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -311,7 +350,7 @@ describe('ol.format.WFS', function() { featureType: 'states', featurePrefix: 'topp' }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -338,7 +377,7 @@ describe('ol.format.WFS', function() { value: 'Another native line goes here' }] }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -358,7 +397,7 @@ describe('ol.format.WFS', function() { featureTypes: ['states', 'cities'], featurePrefix: 'topp' }); - expect(serialized).to.xmleql(ol.xml.load(text)); + expect(serialized).to.xmleql(ol.xml.parse(text)); }); }); @@ -403,5 +442,6 @@ goog.require('ol.geom.MultiLineString'); goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Polygon'); +goog.require('ol.format.GML2'); goog.require('ol.format.WFS'); goog.require('ol.proj'); diff --git a/test/spec/ol/proj/proj.test.js b/test/spec/ol/proj/proj.test.js index 6dcbbebf34..d800d81e93 100644 --- a/test/spec/ol/proj/proj.test.js +++ b/test/spec/ol/proj/proj.test.js @@ -316,6 +316,49 @@ describe('ol.proj', function() { }); + describe('ol.proj.transform()', function() { + + it('transforms a 2d coordinate', function() { + var got = ol.proj.transform([-10, -20], 'EPSG:4326', 'EPSG:3857'); + expect(got).to.have.length(2); + expect(got[0]).to.roughlyEqual(-1113194.9079327357, 1e-3); + expect(got[1]).to.roughlyEqual(-2273030.92698769, 1e-3); + }); + + it('transforms a 3d coordinate', function() { + var got = ol.proj.transform([-10, -20, 3], 'EPSG:4326', 'EPSG:3857'); + expect(got).to.have.length(3); + expect(got[0]).to.roughlyEqual(-1113194.9079327357, 1e-3); + expect(got[1]).to.roughlyEqual(-2273030.92698769, 1e-3); + expect(got[2]).to.be(3); + }); + + it('transforms a 4d coordinate', function() { + var got = ol.proj.transform([-10, -20, 3, 4], 'EPSG:4326', 'EPSG:3857'); + expect(got).to.have.length(4); + expect(got[0]).to.roughlyEqual(-1113194.9079327357, 1e-3); + expect(got[1]).to.roughlyEqual(-2273030.92698769, 1e-3); + expect(got[2]).to.be(3); + expect(got[3]).to.be(4); + }); + + it('works with 3d points and proj4 defs', function() { + proj4.defs('custom', + '+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 ' + + '+k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel ' + + '+towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs'); + + var got = ol.proj.transform([-111, 45.5, 123], 'EPSG:4326', 'custom'); + expect(got).to.have.length(3); + expect(got[0]).to.roughlyEqual(-6601512.194209638, 1); + expect(got[1]).to.roughlyEqual(6145843.802742112, 1); + expect(got[2]).to.be(123); + + delete proj4.defs.custom; + }); + + }); + describe('ol.proj.Projection.prototype.getMetersPerUnit()', function() { beforeEach(function() { diff --git a/test/spec/ol/source/imagewmssource.test.js b/test/spec/ol/source/imagewmssource.test.js index b407a27913..5031017338 100644 --- a/test/spec/ol/source/imagewmssource.test.js +++ b/test/spec/ol/source/imagewmssource.test.js @@ -134,6 +134,16 @@ describe('ol.source.ImageWMS', function() { expect(queryData.get('DPI')).to.be('180'); }); + it('creates an image with a custom imageLoadFunction', function() { + var imageLoadFunction = sinon.spy(); + options.imageLoadFunction = imageLoadFunction; + var source = new ol.source.ImageWMS(options); + var image = source.getImage(extent, resolution, pixelRatio, projection); + image.load(); + expect(imageLoadFunction).to.be.called(); + expect(imageLoadFunction.calledWith(image, image.src_)).to.be(true); + }); + }); describe('#getGetFeatureInfo', function() {