diff --git a/examples/bing-tiles-restrictedzoom.html b/examples/bing-tiles-restrictedzoom.html index 992bd143ab..afbd6a9fb6 100644 --- a/examples/bing-tiles-restrictedzoom.html +++ b/examples/bing-tiles-restrictedzoom.html @@ -2,7 +2,7 @@ - + Basic Bing Tiles with a Subset of Resolutions Example diff --git a/examples/canvas-hit-detection.html b/examples/canvas-hit-detection.html index 5148b70633..2f86ea739b 100644 --- a/examples/canvas-hit-detection.html +++ b/examples/canvas-hit-detection.html @@ -3,7 +3,7 @@ OpenLayers Canvas Hit Detection Example - + diff --git a/examples/draw-undo-redo.html b/examples/draw-undo-redo.html index 40ad3e2995..6d5fa720ea 100644 --- a/examples/draw-undo-redo.html +++ b/examples/draw-undo-redo.html @@ -3,7 +3,7 @@ OpenLayers Undo/Redo Drawing Methods - + diff --git a/examples/editing-methods.html b/examples/editing-methods.html index eeab9166de..5a28710407 100644 --- a/examples/editing-methods.html +++ b/examples/editing-methods.html @@ -3,7 +3,7 @@ OpenLayers Editing Methods - + diff --git a/examples/mobile-wmts-vienna.css b/examples/mobile-wmts-vienna.css new file mode 100644 index 0000000000..a5e3f5e167 --- /dev/null +++ b/examples/mobile-wmts-vienna.css @@ -0,0 +1,160 @@ +html, body, #map { + margin: 0; + height: 100%; + width: 100%; +} +#map { + cursor: move; +} +#title, #tags, #shortdesc { + display: none; +} +div.olControlAttribution { + position: absolute; + font-size: 10px; + text-align: right; + color: #BFEFFF; + bottom: 0; + right: 0; + background: rgba(0,0,100,0.2); + font-family: Arial, Helvetica, sans-serif; + font-weight: bold; + padding: 2px 4px; + border-radius: 5px 0 0 0; +} +.olControlAttribution a { + font-weight: bold; + color: #BFEFFF; + text-decoration: none; +} +div.olControlZoomPanel { + height: 108px; + width: 36px; + position: absolute; + top: 20px; + left: inherit; + right: 20px; +} +div.olControlZoomPanel div { + cursor: pointer; + width: 36px; + height: 36px; + left: 0; + background-color: #ccc; + background-image: none; +} +div.olControlZoomPanel .olControlZoomInItemInactive, +div.olControlZoomPanel .olControlZoomOutItemInactive { + top: 0; + background: rgba(0,0,100,0.4); + position: absolute; +} +div.olControlZoomPanel .olControlZoomInItemInactive { + border-radius: 5px 5px 0 0; +} +div.olControlZoomPanel .olControlZoomOutItemInactive { + border-radius: 0 0 5px 5px; + top: 37px; +} +div.olControlZoomPanel .olControlZoomOutItemInactive:after, +div.olControlZoomPanel .olControlZoomInItemInactive:after { + font-weight: bold; + content: '+'; + font-size: 36px; + padding: 7px; + z-index: 2000; + color: #BFEFFF; + line-height: 1em; +} +div.olControlZoomPanel .olControlZoomOutItemInactive:after { + content: '–'; + line-height: 0.9em; + padding: 0 8px; +} +div.olControlZoomPanel .olControlZoomToMaxExtentItemInactive { + display: none; +} +div.olControlZoomPanel div.olControlGeolocateItemInactive, +div.olControlZoomPanel div.olControlGeolocateItemActive { + position: absolute; + right: 20px; + top: 98px; + border-radius: 5px 5px 5px 5px; + background: #ccc url(img/locate.png) center no-repeat; + background-color: rgba(0,0,100,0.4); +} +div.olControlZoomPanel div.olControlGeolocateItemActive { + background-color: rgba(0,0,100,0.2); +} +div.olControlGeolocateItemInactive:after { + font-weight: bold; + font-size: 36px; + padding: 7px; + z-index: 2000; + color: #BFEFFF; + line-height: 1em; + background: none; +} +.layerPanel { + position: absolute; + top: 20px; + right: 82px; +} +div.layerPanel div { + display: inline; + margin-left: 5px; + cursor: pointer; +} +div.layerPanel div:after { + font-weight: bold; + font-size: 18px; + font-family: arial; + padding: 8px; + color: #BFEFFF; + line-height: 36px; + border-radius: 5px 5px 5px 5px; + background-color: #ccc; + background: rgba(0,0,100,0.4); +} +div.layerPanel div.labelButtonItemInactive:after, +div.layerPanel div.labelButtonItemActive:after { + content: 'Labels'; +} +:lang(de) div.layerPanel div.labelButtonItemInactive:after, +:lang(de) div.layerPanel div.labelButtonItemActive:after { + content: 'Text'; +} +div.layerPanel div.labelButtonItemActive:after { + text-decoration: underline; + background: rgba(0,0,100,0.2); +} +div.layerPanel div.aerialButtonItemInactive:after, +div.layerPanel div.aerialButtonItemActive:after { + content: 'Aerial'; + border-radius: 5px 0 0 5px; +} +:lang(de) div.layerPanel div.aerialButtonItemInactive:after, +:lang(de) div.layerPanel div.aerialButtonItemActive:after { + content: 'Luftbild'; +} +div.layerPanel div.aerialButtonItemActive:after { + text-decoration: underline; + background: rgba(0,0,100,0.2); +} +div.layerPanel div.mapButtonItemInactive:after, +div.layerPanel div.mapButtonItemActive:after { + content: 'Map'; + border-radius: 0 5px 5px 0; +} +:lang(de) div.layerPanel div.mapButtonItemInactive:after, +:lang(de) div.layerPanel div.mapButtonItemActive:after { + content: 'Karte'; +} +div.layerPanel div.mapButtonItemActive:after { + text-decoration: underline; + background: rgba(0,0,100,0.2); +} +div.layerPanel div.mapButtonItemInactive, +div.layerPanel div.mapButtonItemActive { + margin-left: 1px; +} \ No newline at end of file diff --git a/examples/mobile-wmts-vienna.html b/examples/mobile-wmts-vienna.html new file mode 100644 index 0000000000..280f66ce74 --- /dev/null +++ b/examples/mobile-wmts-vienna.html @@ -0,0 +1,27 @@ + + + + City of Vienna WMTS with REST Encoding and Geolocate + + + + + + + + +

City of Vienna WMTS for Desktop and Mobile Devices

+
+ mobile, vienna, ogdwien, rest, restful, wmts, geolocate, permalink +
+

+ A full-screen map for both desktop and mobile devices. Uses + language dependent CSS content and the WMTSCapabilities format to + retrieve layers from the ogdwien open data initiative of the City + of Vienna. Also has a lightweight custom anchor permalink + functionality and uses the Geolocate control. +

+
+ + + diff --git a/examples/mobile-wmts-vienna.js b/examples/mobile-wmts-vienna.js new file mode 100644 index 0000000000..595897051f --- /dev/null +++ b/examples/mobile-wmts-vienna.js @@ -0,0 +1,230 @@ +var map; + +(function() { + OpenLayers.ProxyHost = "proxy.cgi?url="; + + // Set document language for css content + document.documentElement.lang = (navigator.userLanguage || navigator.language).split("-")[0]; + + // A panel for switching between Aerial and Map, and for turning labels + // on and off. + var layerPanel = new OpenLayers.Control.Panel({ + displayClass: "layerPanel", + autoActivate: true + }); + var aerialButton = new OpenLayers.Control({ + type: OpenLayers.Control.TYPE_TOOL, + displayClass: "aerialButton", + eventListeners: { + activate: function() { + if (aerial) {map.setBaseLayer(aerial);} + } + } + }); + var mapButton = new OpenLayers.Control({ + type: OpenLayers.Control.TYPE_TOOL, + displayClass: "mapButton", + eventListeners: { + activate: function() { + if (fmzk) {map.setBaseLayer(fmzk);} + } + } + }); + var labelButton = new OpenLayers.Control({ + type: OpenLayers.Control.TYPE_TOGGLE, + displayClass: "labelButton", + eventListeners: { + activate: function() { + if (labels) {labels.setVisibility(true);} + }, + deactivate: function() { + if (labels) {labels.setVisibility(false);} + } + } + }); + layerPanel.addControls([aerialButton, mapButton, labelButton]); + + var zoomPanel = new OpenLayers.Control.ZoomPanel(); + + // Geolocate control for the Locate button - the locationupdated handler + // draws a cross at the location and a circle showing the accuracy radius. + zoomPanel.addControls([ + new OpenLayers.Control.Geolocate({ + type: OpenLayers.Control.TYPE_TOGGLE, + geolocationOptions: { + enableHighAccuracy: false, + maximumAge: 0, + timeout: 7000 + }, + eventListeners: { + activate: function() { + map.addLayer(vector); + }, + deactivate: function() { + map.removeLayer(vector); + vector.removeAllFeatures(); + }, + locationupdated: function(e) { + vector.removeAllFeatures(); + vector.addFeatures([ + new OpenLayers.Feature.Vector(e.point, null, { + graphicName: 'cross', + strokeColor: '#f00', + strokeWidth: 2, + fillOpacity: 0, + pointRadius: 10 + }), + new OpenLayers.Feature.Vector( + OpenLayers.Geometry.Polygon.createRegularPolygon( + new OpenLayers.Geometry.Point(e.point.x, e.point.y), + e.position.coords.accuracy / 2, 50, 0 + ), null, { + fillOpacity: 0.1, + fillColor: '#000', + strokeColor: '#f00', + strokeOpacity: 0.6 + } + ) + ]); + map.zoomToExtent(vector.getDataExtent()); + } + } + }) + ]); + + // Map with navigation controls optimized for touch devices + map = new OpenLayers.Map({ + div: "map", + theme: null, + projection: "EPSG:3857", + units: "m", + maxExtent: new OpenLayers.Bounds( + -20037508.34, -20037508.34, 20037508.34, 20037508.34 + ), + maxResolution: 156543.0339, + numZoomLevels: 20, + controls: [ + new OpenLayers.Control.TouchNavigation({ + mouseWheelOptions: { + cumulative: false, + interval: 20 + }, + dragPanOptions: { + enableKinetic: { + deceleration: 0.02 + } + }, + zoomBoxEnabled: false + }), + new OpenLayers.Control.Attribution(), + zoomPanel, + layerPanel + ], + eventListeners: { + moveend: function() { + // update anchor for permalinks + var ctr = map.getCenter(); + window.location.hash = "x="+ctr.lon+"&y="+ctr.lat+"&z="+map.getZoom(); + } + } + }); + layerPanel.activateControl(mapButton); + layerPanel.activateControl(labelButton); + + // Vector layer for the location cross and circle + var vector = new OpenLayers.Layer.Vector("Vector Layer"); + + // The WMTS layers we're going to add + var fmzk, aerial, labels; + + // The WMTSCapabilities format and the default options for the layers + var format = new OpenLayers.Format.WMTSCapabilities(), defaults = { + requestEncoding: "REST", + matrixSet: "google3857", + transitionEffect: "resize", + tileLoadingDelay: 0, + attribution: 'Datenquelle: Stadt Wien - data.wien.gv.at' + }; + + // Request capabilities and create layers + OpenLayers.Request.GET({ + url: "http://maps.wien.gv.at/wmts/1.0.0/WMTSCapabilities.xml", + success: function(request) { + var doc = request.responseText, + caps = format.read(doc); + fmzk = format.createLayer(caps, OpenLayers.Util.applyDefaults( + {layer:"fmzk", requestEncoding:"REST"}, defaults + )); + aerial = format.createLayer(caps, OpenLayers.Util.applyDefaults( + {layer:"lb", requestEncoding:"REST"}, defaults + )); + labels = format.createLayer(caps, OpenLayers.Util.applyDefaults( + {layer:"beschriftung", requestEncoding:"REST", isBaseLayer: false}, + defaults + )); + map.addLayers([fmzk, aerial, labels]); + + // zoom to initial extent or restore position from permalink + var extent = fmzk.tileFullExtent, + ctr = extent.getCenterLonLat(), + zoom = map.getZoomForExtent(extent, true), + params = OpenLayers.Util.getParameters("?"+window.location.hash.substr(1)); + OpenLayers.Util.applyDefaults(params, {x:ctr.lon, y:ctr.lat, z:zoom}); + map.setCenter(new OpenLayers.LonLat(params.x, params.y), params.z); + } + }); +})(); + +// Reliably hide the address bar on Android and iOS devices. From +// http://blog.nateps.com/how-to-hide-the-address-bar-in-a-full-screen +(function() { + var page = document.getElementById("map"), + ua = navigator.userAgent, + iphone = ~ua.indexOf('iPhone') || ~ua.indexOf('iPod'), + ipad = ~ua.indexOf('iPad'), + ios = iphone || ipad, + // Detect if this is running as a fullscreen app from the homescreen + fullscreen = window.navigator.standalone, + android = ~ua.indexOf('Android'), + lastWidth = 0; + + if (android) { + // Android's browser adds the scroll position to the innerHeight, just to + // make this really fucking difficult. Thus, once we are scrolled, the + // page height value needs to be corrected in case the page is loaded + // when already scrolled down. The pageYOffset is of no use, since it always + // returns 0 while the address bar is displayed. + window.onscroll = function() { + page.style.height = window.innerHeight + 'px'; + }; + } + var setupScroll = window.onload = function() { + // Start out by adding the height of the location bar to the width, so that + // we can scroll past it + if (ios) { + // iOS reliably returns the innerWindow size for documentElement.clientHeight + // but window.innerHeight is sometimes the wrong value after rotating + // the orientation + var height = document.documentElement.clientHeight; + // Only add extra padding to the height on iphone / ipod, since the ipad + // browser doesn't scroll off the location bar. + if (iphone && !fullscreen) height += 60; + page.style.height = height + 'px'; + } else if (android) { + // The stock Android browser has a location bar height of 56 pixels, but + // this very likely could be broken in other Android browsers. + page.style.height = (window.innerHeight + 56) + 'px'; + } + // Scroll after a timeout, since iOS will scroll to the top of the page + // after it fires the onload event + setTimeout(scrollTo, 0, 0, 1); + }; + (window.onresize = function() { + var pageWidth = page.offsetWidth; + // Android doesn't support orientation change, so check for when the width + // changes to figure out when the orientation changes + if (lastWidth == pageWidth) return; + lastWidth = pageWidth; + setupScroll(); + })(); +})(); diff --git a/examples/point-grid.html b/examples/point-grid.html index 4cff89d85b..8508fdb473 100644 --- a/examples/point-grid.html +++ b/examples/point-grid.html @@ -1,7 +1,7 @@ - + OpenLayers Point Grid Example diff --git a/examples/proxy.cgi b/examples/proxy.cgi index c668218c48..4358e2ca03 100755 --- a/examples/proxy.cgi +++ b/examples/proxy.cgi @@ -21,7 +21,8 @@ allowedHosts = ['www.openlayers.org', 'openlayers.org', 'sigma.openplans.org', 'demo.opengeo.org', 'www.openstreetmap.org', 'sample.azavea.com', 'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', - 'vmap0.tiles.osgeo.org', 'www.openrouteservice.org'] + 'vmap0.tiles.osgeo.org', 'www.openrouteservice.org', + 'maps.wien.gv.at'] method = os.environ["REQUEST_METHOD"] diff --git a/examples/snap-grid.html b/examples/snap-grid.html index b6b592d23e..9d0604bd69 100644 --- a/examples/snap-grid.html +++ b/examples/snap-grid.html @@ -1,7 +1,7 @@ - + OpenLayers Snap Grid Example diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index b378b7d24b..22fb1b8500 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -121,7 +121,6 @@ "OpenLayers/Marker/Box.js", "OpenLayers/Popup.js", "OpenLayers/Tile.js", - "OpenLayers/Tile/BackBufferable.js", "OpenLayers/Tile/Image.js", "OpenLayers/Tile/Image/IFrame.js", "OpenLayers/Tile/WFS.js", diff --git a/lib/OpenLayers/Format/OWSCommon/v1.js b/lib/OpenLayers/Format/OWSCommon/v1.js index 7ee97593ce..00f4e2b91b 100644 --- a/lib/OpenLayers/Format/OWSCommon/v1.js +++ b/lib/OpenLayers/Format/OWSCommon/v1.js @@ -171,12 +171,24 @@ OpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, { this.readChildNodes(node, dcp.http); }, "Get": function(node, http) { - http.get = this.getAttributeNS(node, - this.namespaces.xlink, "href"); + if (!http.get) { + http.get = []; + } + var obj = { + url: this.getAttributeNS(node, this.namespaces.xlink, "href") + }; + this.readChildNodes(node, obj); + http.get.push(obj); }, "Post": function(node, http) { - http.post = this.getAttributeNS(node, - this.namespaces.xlink, "href"); + if (!http.post) { + http.post = []; + } + var obj = { + url: this.getAttributeNS(node, this.namespaces.xlink, "href") + }; + this.readChildNodes(node, obj); + http.post.push(obj); }, "Parameter": function(node, operation) { if (!operation.parameters) { @@ -186,6 +198,14 @@ OpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, { operation.parameters[name] = {}; this.readChildNodes(node, operation.parameters[name]); }, + "Constraint": function(node, obj) { + if (!obj.constraints) { + obj.constraints = {}; + } + var name = node.getAttribute("name"); + obj.constraints[name] = {}; + this.readChildNodes(node, obj.constraints[name]); + }, "Value": function(node, allowedValues) { allowedValues[this.getChildValue(node)] = true; }, diff --git a/lib/OpenLayers/Format/WMTSCapabilities.js b/lib/OpenLayers/Format/WMTSCapabilities.js index bc5d35d211..d2dca6172e 100644 --- a/lib/OpenLayers/Format/WMTSCapabilities.js +++ b/lib/OpenLayers/Format/WMTSCapabilities.js @@ -114,10 +114,13 @@ OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.Vers layer = new OpenLayers.Layer.WMTS( OpenLayers.Util.applyDefaults(config, { - url: capabilities.operationsMetadata.GetTile.dcp.http.get, + url: config.requestEncoding === "REST" && layerDef.resourceUrl ? + layerDef.resourceUrl.tile.template : + capabilities.operationsMetadata.GetTile.dcp.http.get[0].url, name: layerDef.title, style: style.identifier, - matrixIds: matrixSet.matrixIds + matrixIds: matrixSet.matrixIds, + tileFullExtent: matrixSet.bounds }) ); } diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index 06940d117a..fcc919833f 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -314,13 +314,6 @@ OpenLayers.Layer = OpenLayers.Class({ */ transitionEffect: null, - /** - * Property: SUPPORTED_TRANSITIONS - * {Array} An immutable (that means don't change it!) list of supported - * transitionEffect values. - */ - SUPPORTED_TRANSITIONS: ['resize'], - /** * Property: metadata * {Object} This object can be used to store additional information on a diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 30021877cb..ce6332a3c9 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -111,6 +111,34 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ timerId: null, + /** + * Property: backBuffer + * {DOMElement} The back buffer. + */ + backBuffer: null, + + /** + * Property: gridResolution + * {Number} The resolution of the current grid. Used for backbuffering. + * This property is updated each the grid is initialized. + */ + gridResolution: null, + + /** + * Property: backBufferResolution + * {Number} The resolution of the current back buffer. This property is + * updated each time a back buffer is created. + */ + backBufferResolution: null, + + /** + * Property: backBufferLonLat + * {Object} The top-left corner of the current back buffer. Includes lon + * and lat properties. This object is updated each time a back buffer + * is created. + */ + backBufferLonLat: null, + /** * Constructor: OpenLayers.Layer.Grid * Create a new grid layer @@ -133,7 +161,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.events.addEventType("tileloaded"); this.grid = []; - + this._moveGriddedTiles = OpenLayers.Function.bind( this.moveGriddedTiles, this ); @@ -159,6 +187,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ destroy: function() { this.clearGrid(); + // clearGrid should remove any back buffer from the layer, + // so no need to call removeBackBuffer here + this.grid = null; this.tileSize = null; OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments); @@ -180,6 +211,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } } this.grid = []; + this.gridResolution = null; } }, @@ -212,6 +244,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // we do not want to copy reference to grid, so we make a new array obj.grid = []; + obj.gridResolution = null; return obj; }, @@ -240,14 +273,37 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // total bounds of the tiles var tilesBounds = this.getTilesBounds(); - + + // the new map resolution + var resolution = this.map.getResolution(); + + // the server-supported resolution for the new map resolution + var serverResolution = this.getServerResolution(resolution); + if (this.singleTile) { // We want to redraw whenever even the slightest part of the // current bounds is not contained by our tile. // (thus, we do not specify partial -- its default is false) + if ( forceReTile || (!dragging && !tilesBounds.containsBounds(bounds))) { + + // In single tile mode with no transition effect, we insert + // a non-scaled backbuffer when the layer is moved. But if + // a zoom occurs right after a move, i.e. before the new + // image is received, we need to remove the backbuffer, or + // an ill-positioned image will be visible during the zoom + // transition. + + if(zoomChanged && this.transitionEffect !== 'resize') { + this.removeBackBuffer(); + } + + if(!zoomChanged || this.transitionEffect === 'resize') { + this.applyBackBuffer(serverResolution); + } + this.initSingleTile(bounds); } } else { @@ -260,10 +316,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { forceReTile = forceReTile || !tilesBounds.containsBounds(bounds, true); - var resolution = this.map.getResolution(); - var serverResolution = - this.getServerResolution(resolution); - if(resolution !== serverResolution) { bounds = this.map.calculateBounds(null, serverResolution); if(forceReTile) { @@ -281,6 +333,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } if(forceReTile) { + if(zoomChanged && this.transitionEffect === 'resize') { + this.applyBackBuffer(serverResolution); + } this.initGriddedTiles(bounds); } else { this.scheduleMoveGriddedTiles(); @@ -306,7 +361,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { if(this.serverResolutions && OpenLayers.Util.indexOf(this.serverResolutions, resolution) === -1) { var i, serverResolution; - for(var i=this.serverResolutions.length-1; i>= 0; i--) { + for(i=this.serverResolutions.length-1; i>= 0; i--) { serverResolution = this.serverResolutions[i]; if(serverResolution > resolution) { resolution = serverResolution; @@ -352,14 +407,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { var size = this.map.getSize(); var lcX = parseInt(this.map.layerContainerDiv.style.left, 10); var lcY = parseInt(this.map.layerContainerDiv.style.top, 10); - var x = (lcX - (size.w / 2.)) * (scale - 1); - var y = (lcY - (size.h / 2.)) * (scale - 1); + var x = (lcX - (size.w / 2.0)) * (scale - 1); + var y = (lcY - (size.h / 2.0)) * (scale - 1); this.div.style.left = x + '%'; this.div.style.top = y + '%'; }, - /** * Method: getResolutionScale * Return the value by which the layer is currently scaled. @@ -371,6 +425,96 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { return parseInt(this.div.style.width, 10) / 100; }, + /** + * Method: applyBackBuffer + * Create, insert, scale and position a back buffer for the layer. + * + * Parameters: + * resolution - {Number} The resolution to transition to. + */ + applyBackBuffer: function(resolution) { + var backBuffer = this.backBuffer; + if(!backBuffer) { + backBuffer = this.createBackBuffer(); + if(!backBuffer) { + return; + } + this.div.insertBefore(backBuffer, this.div.firstChild); + this.backBuffer = backBuffer; + + // set some information in the instance for subsequent + // calls to applyBackBuffer where the same back buffer + // is reused + var topLeftTileBounds = this.grid[0][0].bounds; + this.backBufferLonLat = { + lon: topLeftTileBounds.left, + lat: topLeftTileBounds.top + }; + this.backBufferResolution = this.gridResolution; + } + + var style = backBuffer.style; + + // scale the back buffer + var ratio = this.backBufferResolution / resolution; + style.width = 100 * ratio + '%'; + style.height = 100 * ratio + '%'; + + // and position it (based on the grid's top-left corner) + var position = this.getViewPortPxFromLonLat( + this.backBufferLonLat, resolution); + var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10); + var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10); + backBuffer.style.left = (position.x - leftOffset) + '%'; + backBuffer.style.top = (position.y - topOffset) + '%'; + }, + + /** + * Method: createBackBuffer + * Create a back buffer. + * + * Returns: + * {DOMElement} The DOM element for the back buffer, undefined if the + * grid isn't initialized yet. + */ + createBackBuffer: function() { + var backBuffer; + if(this.grid.length > 0) { + backBuffer = document.createElement('div'); + backBuffer.id = this.div.id + '_bb'; + backBuffer.className = 'olBackBuffer'; + backBuffer.style.position = 'absolute'; + backBuffer.style.width = '100%'; + backBuffer.style.height = '100%'; + for(var i=0, lenI=this.grid.length; i. */ url: null, @@ -416,39 +419,59 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { var center = bounds.getCenterLonLat(); var info = this.getTileInfo(center); var matrixId = this.matrix.identifier; + var dimensions = this.dimensions, params; if (this.requestEncoding.toUpperCase() === "REST") { - - // include 'version', 'layer' and 'style' in tile resource url - var path = this.version + "/" + this.layer + "/" + this.style + "/"; - - // append optional dimension path elements - if (this.dimensions) { - for (var i=0; i=0; --i) { + dimension = dimensions[i]; + context[dimension] = params[dimension.toUpperCase()]; } } - } - - // append other required path elements - path = path + this.matrixSet + "/" + this.matrix.identifier + - "/" + info.row + "/" + info.col + "." + this.formatSuffix; - - if (OpenLayers.Util.isArray(this.url)) { - url = this.selectUrl(path, this.url); + url = OpenLayers.String.format(template, context); } else { - url = this.url; - } - if (!url.match(/\/$/)) { - url = url + "/"; - } - url = url + path; + // include 'version', 'layer' and 'style' in tile resource url + var path = this.version + "/" + this.layer + "/" + this.style + "/"; + // append optional dimension path elements + if (dimensions) { + for (var i=0; i"; - var containerElement = (this.map) ? this.map.layerContainerDiv + var containerElement = (this.map) ? this.map.div : document.body; var realSize = OpenLayers.Util.getRenderedDimensions( preparedHTML, null, { diff --git a/lib/OpenLayers/Tile/BackBufferable.js b/lib/OpenLayers/Tile/BackBufferable.js deleted file mode 100644 index 47c3e3198c..0000000000 --- a/lib/OpenLayers/Tile/BackBufferable.js +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for - * full list of contributors). Published under the Clear BSD license. - * See http://svn.openlayers.org/trunk/openlayers/license.txt for the - * full text of the license. */ - - -/** - * @requires OpenLayers/Tile.js - * @requires OpenLayers/Util.js - */ - -/** - * Class: OpenLayers.Tile.BackBufferable - * Base class for tiles that can have backbuffers during transitions. Do not - * create instances of this class. - */ -OpenLayers.Tile.BackBufferable = OpenLayers.Class(OpenLayers.Tile, { - - /** - * Property: backBufferMode - * {Integer} Bitmap: 0 for no backbuffering at all, 1 for singleTile - * layers, 2 for transition effect set, 3 for both. - */ - backBufferMode: null, - - /** - * Property: backBufferData - * {Object} Object including the necessary data for the back - * buffer. - * - * The object includes three properties: - * tile - {DOMElement} The DOM element for the back buffer. - * bounds - {} The bounds of the tile to back. - * resolution - {Number} The resolution of the tile to back. - */ - backBufferData: null, - - /** - * Method: initialize - * Determines the backBuffer mode and registers events - */ - initialize: function() { - OpenLayers.Tile.prototype.initialize.apply(this, arguments); - - var transitionSupported = OpenLayers.Util.indexOf( - this.layer.SUPPORTED_TRANSITIONS, - this.layer.transitionEffect) != -1; - this.backBufferMode = (this.layer.singleTile && 1) | - (transitionSupported && 2); - - this.backBufferData = {}; - if (!this.size) { - this.size = new OpenLayers.Size(256, 256); - } - }, - - /** - * Method: draw - * Check that a tile should be drawn, and draw it. - * - * Returns: - * {Boolean} Was a tile drawn? - */ - draw: function() { - var draw = OpenLayers.Tile.prototype.shouldDraw.apply(this, arguments); - if (draw) { - this.updateBackBuffer(); - } - this.clear(); - if (!draw) { - this.resetBackBuffer(); - }; - return draw; - }, - - /** - * Method: getTile - * Get the tile's markup. To be implemented by subclasses. - * - * Returns: - * {DOMElement} The tile's markup - */ - - /** - * Method: createBackBuffer - * Create a copy of this tile's markup for the back buffer. To be - * implemented by subclasses. - * - * Returns: - * {DOMElement} A copy of the tile's markup. - */ - - /** - * Method: getTileResolution - * Get the tile's actual resolution. - * - * Returns: - * {Number} - */ - getTileResolution: function() { - var layer = this.layer, - map = layer.map, - mapResolution = map.getResolution(); - return layer.getServerResolution ? - layer.getServerResolution(mapResolution) : - mapResolution; - }, - - /** - * Method: setBackBufferData - * Stores the current bounds and resolution, for offset and ratio - * calculations - */ - setBackBufferData: function() { - this.backBufferData = OpenLayers.Util.extend(this.backBufferData, { - bounds: this.bounds, - resolution: this.getTileResolution() - }); - }, - - /** - * Method: updateBackBuffer - * Update the , and return a new or reposition the - * backBuffer. When a backbuffer is returned, the tile's markup is not - * available any more. - * - * Returns: - * {HTMLDivElement} the tile's markup in a cloned element, or undefined if - * no backbuffer is currently available or needed - */ - updateBackBuffer: function() { - var layer = this.layer, map = layer.map, - backBufferMode = this.backBufferMode, - data = this.backBufferData, - tile = this.getTile(), - backBuffer = data.tile, - prevResolution = data.resolution, - nextResolution = this.getTileResolution(), - ratio = prevResolution ? prevResolution / nextResolution : 1, - - // Cases where we don't position and return a back buffer, but only - // update backBufferData and return undefined: - // (1) current ratio and backBufferMode dont't require a backbuffer - notNeeded = !(ratio == 1 ? backBufferMode & 1 : backBufferMode & 2), - // (2) the tile is not appended to the layer's div - noParent = tile && tile.parentNode !== layer.div, - // (3) we don't have a tile available that we could use as buffer - noTile = !(tile && tile.childNodes.length > 0), - // (4) no backbuffer is displayed for a tile that's still loading - noBackBuffer = !backBuffer && this.isLoading; - - if (notNeeded || noParent || noTile || noBackBuffer) { - this.setBackBufferData(); - return; - } - - // Create a back buffer tile and add it to the DOM - if (!backBuffer) { - backBuffer = this.insertBackBuffer(); - // some browsers fire the onload event before the image is - // displayed, so we keep the buffer until the whole layer finished - // loading to avoid visual glitches - layer.events.register("loadend", this, this.resetBackBuffer); - data.tile = backBuffer; - } - - // Position the back buffer now that we have one - var lonLat = {lon: data.bounds.left, lat: data.bounds.top}, - position = layer.getViewPortPxFromLonLat(lonLat, nextResolution), - containerStyle = map.layerContainerDiv.style, - leftOffset = parseInt(containerStyle.left, 10), - topOffset = parseInt(containerStyle.top, 10), - style = backBuffer.style; - - style.left = (position.x - leftOffset) + "%"; - style.top = (position.y - topOffset) + "%"; - style.width = (this.size.w * ratio) + "%"; - style.height = (this.size.h * ratio) + "%"; - - return backBuffer; - }, - - /** - * Method: resetBackBuffer - * Handler for the layer's loadend event. - */ - resetBackBuffer: function() { - this.layer.events.unregister("loadend", this, this.resetBackBuffer); - this.removeBackBuffer(); - this.setBackBufferData(); - }, - - /** - * Method: removeBackBuffer - * Removes the backBuffer for this tile. - */ - removeBackBuffer: function() { - var backBufferData = this.backBufferData; - var backBuffer = backBufferData.tile; - delete backBufferData.tile; - var parent = backBuffer && backBuffer.parentNode; - if (backBuffer) { - parent.removeChild(backBuffer); - } - }, - - /** - * APIMethod: destroy - * nullify references to prevent circular references and memory leaks - */ - destroy: function() { - this.removeBackBuffer(); - this.layer.events.unregister("loadend", this, this.resetBackBuffer); - this.backBufferData = null; - OpenLayers.Tile.prototype.destroy.apply(this, arguments); - } - -}); diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js index 087693d79f..ee35ed76bb 100644 --- a/lib/OpenLayers/Tile/Image.js +++ b/lib/OpenLayers/Tile/Image.js @@ -5,7 +5,7 @@ /** - * @requires OpenLayers/Tile/BackBufferable.js + * @requires OpenLayers/Tile.js */ /** @@ -15,9 +15,9 @@ * constructor. * * Inherits from: - * - + * - */ -OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, { +OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, { /** * Property: url @@ -96,7 +96,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, { * options - {Object} */ initialize: function(layer, position, bounds, url, size, options) { - OpenLayers.Tile.BackBufferable.prototype.initialize.apply(this, arguments); + OpenLayers.Tile.prototype.initialize.apply(this, arguments); this.url = url; //deprecated remove me @@ -123,7 +123,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, { } // don't handle async requests any more this.asyncRequestId = null; - OpenLayers.Tile.BackBufferable.prototype.destroy.apply(this, arguments); + OpenLayers.Tile.prototype.destroy.apply(this, arguments); }, /** @@ -134,7 +134,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, { * {Boolean} Was a tile drawn? */ draw: function() { - var drawn = OpenLayers.Tile.BackBufferable.prototype.draw.apply(this, arguments); + var drawn = OpenLayers.Tile.prototype.draw.apply(this, arguments); if (drawn) { if (this.layer != this.layer.map.baseLayer && this.layer.reproject) { this.bounds = this.getBoundsFromBaseLayer(this.position); @@ -320,19 +320,23 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, { }, /** - * Method: insertBackBuffer - * Create a copy of this tile's markup and insert it to the layer - * div. + * Method: createBackBuffer + * Create a backbuffer for this tile. A backbuffer isn't exactly a clone + * of the tile's markup, because we want to avoid the reloading of the + * image. So we clone the frame, and steal the image from the tile. * * Returns: - * {DOMElement} The back buffer. + * {DOMElement} The markup, or undefined if the tile has no image + * or if it's currently loading. */ - insertBackBuffer: function() { - var frame = this.frame.cloneNode(false); - this.layer.div.insertBefore(frame, this.frame); - frame.appendChild(this.imgDiv); + createBackBuffer: function() { + if(!this.imgDiv || this.isLoading) { + return; + } + var backBuffer = this.frame.cloneNode(false); + backBuffer.appendChild(this.imgDiv); this.imgDiv = null; - return frame; + return backBuffer; }, /** diff --git a/lib/OpenLayers/Tile/Image/IFrame.js b/lib/OpenLayers/Tile/Image/IFrame.js index 9616036815..d67db5f70e 100644 --- a/lib/OpenLayers/Tile/Image/IFrame.js +++ b/lib/OpenLayers/Tile/Image/IFrame.js @@ -15,9 +15,6 @@ * * This mixin will be applied to instances * configured with set. - * - * Inherits from: - * - */ OpenLayers.Tile.Image.IFrame = { @@ -29,40 +26,52 @@ OpenLayers.Tile.Image.IFrame = { useIFrame: null, /** - * Method: updateBackBuffer - * Update the , and return a new or reposition the - * backBuffer. When a backbuffer is returned, the tile's markup is not - * available any more. - * - * Returns: - * {HTMLDivElement} the tile's markup in a cloned element, or undefined if - * no backbuffer is currently available or needed + * Method: draw + * Set useIFrame in the instance, and operate the image/iframe switch. + * Then call Tile.Image.draw. + * + * Returns: + * {Boolean} */ - updateBackBuffer: function() { - this.url = this.layer.getURL(this.bounds); - var usedIFrame = this.useIFrame; - this.useIFrame = this.maxGetUrlLength !== null && !this.layer.async && - this.url.length > this.maxGetUrlLength; - var fromIFrame = usedIFrame && !this.useIFrame; - var toIFrame = !usedIFrame && this.useIFrame; - if (fromIFrame || toIFrame) { - // switch between get (image) and post (iframe) - this.clear(); - if (this.imgDiv && this.imgDiv.parentNode === this.frame) { - this.frame.removeChild(this.imgDiv); - } - this.imgDiv = null; - if (fromIFrame) { - // remove eventPane - this.frame.removeChild(this.frame.firstChild); - this.resetBackBuffer(); + draw: function() { + var draw = OpenLayers.Tile.Image.prototype.shouldDraw.call(this); + if(draw) { + + // this.url isn't set to the currect value yet, so we call getURL + // on the layer and store the result in a local variable + var url = this.layer.getURL(this.bounds); + + var usedIFrame = this.useIFrame; + this.useIFrame = this.maxGetUrlLength !== null && + !this.layer.async && + url.length > this.maxGetUrlLength; + + var fromIFrame = usedIFrame && !this.useIFrame; + var toIFrame = !usedIFrame && this.useIFrame; + + if(fromIFrame || toIFrame) { + + // Switching between GET (image) and POST (iframe). + + // We remove the imgDiv (really either an image or an iframe) + // from the frame and set it to null to make sure initImage + // will call createImage. + + if(this.imgDiv && this.imgDiv.parentNode === this.frame) { + this.frame.removeChild(this.imgDiv); + } + this.imgDiv = null; + + // And if we had an iframe we also remove the event pane. + + if(fromIFrame) { + this.frame.removeChild(this.frame.firstChild); + } } } - if (!this.useIFrame) { - OpenLayers.Tile.Image.prototype.updateBackBuffer.apply(this, arguments); - } + return OpenLayers.Tile.Image.prototype.draw.apply(this, arguments); }, - + /** * Method: createImage * Creates the content for the frame on the tile. @@ -183,6 +192,22 @@ OpenLayers.Tile.Image.IFrame = { } else { OpenLayers.Tile.Image.prototype.setImgSrc.apply(this, arguments); } - } + }, + /** + * Method: createBackBuffer + * Override createBackBuffer to do nothing when we use an iframe. Moving an + * iframe from one element to another makes it necessary to reload the iframe + * because its content is lost. So we just give up. + * + * Returns: + * {DOMElement} + */ + createBackBuffer: function() { + var backBuffer; + if(!this.useIFrame) { + backBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer.call(this); + } + return backBuffer; + } }; diff --git a/tests/Format/OWSCommon/v1_1_0.html b/tests/Format/OWSCommon/v1_1_0.html index e899ea8486..1cdf7ee281 100644 --- a/tests/Format/OWSCommon/v1_1_0.html +++ b/tests/Format/OWSCommon/v1_1_0.html @@ -6,7 +6,7 @@ function test_read_exception(t) { t.plan(6); var text = '' + -'' + ' ' + @@ -18,7 +18,7 @@ var format = new OpenLayers.Format.OWSCommon(); var result = format.read(text); var report = result.exceptionReport; - t.eq(report.version, "1.0.0", "Version parsed correctly"); + t.eq(report.version, "1.1.0", "Version parsed correctly"); t.eq(report.language, "en", "Language parsed correctly"); var exception = report.exceptions[0]; t.eq(exception.code, "InvalidParameterValue", "exceptionCode properly parsed"); diff --git a/tests/Format/SOSCapabilities/v1_0_0.html b/tests/Format/SOSCapabilities/v1_0_0.html index ed7f25eb65..6713685903 100644 --- a/tests/Format/SOSCapabilities/v1_0_0.html +++ b/tests/Format/SOSCapabilities/v1_0_0.html @@ -40,7 +40,7 @@ t.eq(obj.serviceProvider.serviceContact.contactInfo.phone.voice, "+49-251-83-30088", "Voice phone correctly parsed"); // operationsMetadata (from OWSCommon) - t.eq(obj.operationsMetadata.DescribeSensor.dcp.http.post, "http://v-swe.uni-muenster.de:8080/WeatherSOS/sos", "POST url for DescribeSensor correctly parsed"); + t.eq(obj.operationsMetadata.DescribeSensor.dcp.http.post[0].url, "http://v-swe.uni-muenster.de:8080/WeatherSOS/sos", "POST url for DescribeSensor correctly parsed"); var counter = 0; for (var key in obj.operationsMetadata.DescribeSensor.parameters.procedure.allowedValues) { if (counter == 0) { diff --git a/tests/Format/WMTSCapabilities/v1_0_0.html b/tests/Format/WMTSCapabilities/v1_0_0.html index 9ed58b3580..f8b5a37215 100644 --- a/tests/Format/WMTSCapabilities/v1_0_0.html +++ b/tests/Format/WMTSCapabilities/v1_0_0.html @@ -4,7 +4,7 @@ diff --git a/tests/Layer/WMTS.html b/tests/Layer/WMTS.html index 5b87d32e49..079e87876d 100644 --- a/tests/Layer/WMTS.html +++ b/tests/Layer/WMTS.html @@ -220,6 +220,39 @@ t.eq(tileurl1, "http://example.com/wmts/1.0.0/world/blue_marble/arcgis_online/1/0/0.jpg", "layer1 getURL returns correct url"); map.destroy(); } + + function test_getURL_resourceUrl(t) { + t.plan(2); + + var xml = document.getElementById("capabilities").firstChild.nodeValue; + var doc = new OpenLayers.Format.XML().read(xml); + var obj = new OpenLayers.Format.WMTSCapabilities().read(doc); + + var template = "http://www.example.com/{style}/{Time}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"; + var layer = new OpenLayers.Layer.WMTS({ + requestEncoding: "REST", + url: template, + layer: "GeoWebCache_USA_WMTS", + style: "foo", + matrixSet: "arcgis-online", + params: {Time: "2011"}, + dimensions: ["Time"] + }); + + var map = new OpenLayers.Map("map", { + layers: [layer], + projection: "EPSG:4326", + maxResolution: 0.3515625, + maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90) + }); + map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1); + t.eq(layer.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0)), + "http://www.example.com/foo/2011/foo/arcgis-online/1/1/1.png", "getURL returns correct url"); + map.zoomIn(); + t.eq(layer.getURL(new OpenLayers.Bounds(-180.0, 0.0, -90.0, 90.0)), + "http://www.example.com/foo/2011/foo/arcgis-online/2/2/2.png", "getURL returns correct url"); + map.destroy(); + } function test_destroy (t) { t.plan(3); diff --git a/tests/Tile/BackBufferable.html b/tests/Tile/BackBufferable.html deleted file mode 100644 index 97275891e7..0000000000 --- a/tests/Tile/BackBufferable.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - -
- - diff --git a/tests/Tile/Image.html b/tests/Tile/Image.html index 0bfa4ae2ec..22aa3ab6fa 100644 --- a/tests/Tile/Image.html +++ b/tests/Tile/Image.html @@ -317,8 +317,8 @@ map.destroy(); } - function test_insertBackBuffer(t) { - t.plan(4); + function test_createBackBuffer(t) { + t.plan(3); var map = new OpenLayers.Map('map'); var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", @@ -326,11 +326,18 @@ map.addLayer(layer); map.setCenter(new OpenLayers.LonLat(0,0), 5); var tile = layer.grid[0][0]; + + // we're going to create a back buffer while the image + // is actually loading, so we call stopObservingElement + // to avoid any unexpected behavior + tile.isLoading = false; + OpenLayers.Event.stopObservingElement(tile.imgDiv); + var img = tile.imgDiv; - var backBuffer = tile.insertBackBuffer(); - t.eq(backBuffer.style.left, tile.frame.style.left, "backBuffer tile has same left style as frame"); - t.ok(backBuffer.parentNode === layer.div, "backBuffer inserted into layer div"); - t.ok(backBuffer.firstChild === img, "image appended to backBuffer"); + var bb = tile.createBackBuffer(); + t.eq(bb.style.left, tile.frame.style.left, + "backbuffer has same left style as frame"); + t.ok(bb.firstChild === img, "image appended to bb"); t.ok(tile.imgDiv == null, "image reference removed from tile"); map.destroy(); } diff --git a/tests/Tile/Image/IFrame.html b/tests/Tile/Image/IFrame.html index ce57a31c6a..ab119ade38 100644 --- a/tests/Tile/Image/IFrame.html +++ b/tests/Tile/Image/IFrame.html @@ -15,7 +15,7 @@ var wmsUrl = "http://labs.metacarta.com/wms/vmap0?"; function test_Tile_Image_IFrame_create (t) { - t.plan( 5 ); + t.plan( 3 ); map = new OpenLayers.Map('map'); var bar = new Array(205).join("1234567890"); layer = new OpenLayers.Layer.WMS(name, wmsUrl, @@ -25,7 +25,6 @@ map.addLayer(layer); var tile = layer.addTile(bounds, position); - t.eq(tile.backBufferMode, 2, "backBufferMode is 2 after tile creation"); tile.draw(); t.eq(tile.imgDiv.nodeName.toLowerCase(), "iframe", "IFrame used for long URL"); @@ -33,7 +32,6 @@ layer.mergeNewParams({foo: null}); tile.draw(); t.eq(tile.imgDiv.nodeName.toLowerCase(), "img", "IMG used for short URL"); - t.eq(tile.backBufferMode, 2, "backBufferMode reset to 2"); tile.maxGetUrlLength = 0; tile.draw(); diff --git a/tests/list-tests.html b/tests/list-tests.html index b5d052093f..4983e0b4f8 100644 --- a/tests/list-tests.html +++ b/tests/list-tests.html @@ -224,7 +224,6 @@
  • Symbolizer/Text.html
  • Tile.html
  • Tile/Image.html
  • -
  • Tile/BackBufferable.html
  • Tile/Image/IFrame.html
  • Tile/WFS.html
  • Tween.html
  • diff --git a/tools/closure.py b/tools/closure.py index ab60be7eb0..03edbc351d 100644 --- a/tools/closure.py +++ b/tools/closure.py @@ -7,16 +7,14 @@ if not os.path.exists(path): raise Exception("No closure-compiler.jar at %s; read README.txt!" % path) def minimize(code): - ntf = tempfile.NamedTemporaryFile(delete=False) + ntf = tempfile.NamedTemporaryFile() ntf.write(code) ntf.flush() - ntf2 = tempfile.NamedTemporaryFile(delete=False) - ntf.close() - ntf2.close() + ntf2 = tempfile.NamedTemporaryFile() os.system("java -jar %s --js %s --js_output_file %s" % (path, ntf.name, ntf2.name)) data = open(ntf2.name).read() - os.unlink(ntf.name) - os.unlink(ntf2.name) + ntf.close() + ntf2.close() return data diff --git a/tools/update_dev_dir.sh b/tools/update_dev_dir.sh index 7637c4e64c..743bfc8f15 100755 --- a/tools/update_dev_dir.sh +++ b/tools/update_dev_dir.sh @@ -4,14 +4,17 @@ # Get current 'Last Changed Rev' -REV=`svn info http://svn.openlayers.org/ | grep 'Revision' | awk '{print $2}'` +GITREV=`svn info https://github.com/openlayers/openlayers/ | grep 'Revision' | awk '{print $2}'` +SVNREV=`svn info http://svn.openlayers.org/ | grep 'Revision' | awk '{print $2}'` # Get the last svn rev +touch /tmp/ol_git_rev touch /tmp/ol_svn_rev -OLD_REV="o`cat /tmp/ol_svn_rev`" +OLD_GITREV="o`cat /tmp/ol_git_rev`" +OLD_SVNREV="o`cat /tmp/ol_svn_rev`" # If they're not equal, do some work. -if [ ! o$REV = $OLD_REV ]; then +if [ ! o$GITREV = $OLD_GITREV ]; then svn revert -R /osgeo/openlayers/docs/dev svn up /osgeo/openlayers/docs/dev @@ -37,10 +40,14 @@ if [ ! o$REV = $OLD_REV ]; then sed -i -e 's!../lib/OpenLayers.js!../OpenLayers.js!' examples/*.html naturaldocs -i /osgeo/openlayers/docs/dev/lib -o HTML /osgeo/openlayers/dev/apidocs -p /osgeo/openlayers/docs/dev/apidoc_config -s Default OL >/dev/null naturaldocs -i /osgeo/openlayers/docs/dev/lib -o HTML /osgeo/openlayers/dev/docs -p /osgeo/openlayers/docs/dev/doc_config -s Default OL >/dev/null - - svn up /osgeo/openlayers/dev/sandbox/ # Record the revision - echo -n $REV > /tmp/ol_svn_rev + echo -n $GITREV > /tmp/ol_git_rev +fi +if [ ! o$SVNREV = $OLD_SVNREV ]; then + svn up /osgeo/openlayers/dev/sandbox/ + svn up /osgeo/openlayers/dev/addins/ + # Record the revision + echo -n $SVNREV > /tmp/ol_svn_rev fi svn up /osgeo/openlayers/documentation-checkout