From 7a71f107cb3c7c0f3cf59a95fc9f11a12661e607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 28 Mar 2013 11:21:10 +0100 Subject: [PATCH 1/6] Export and externalize Control.setMap --- build.py | 1 + buildcfg/base.json | 1 + buildcfg/ol-all.json | 1 + buildcfg/ol-simple.json | 1 + buildcfg/ol-whitespace.json | 1 + buildcfg/ol.json | 1 + externs/oli.js | 21 +++++++++++++++++++++ src/objectliterals.jsdoc | 7 +++++++ src/ol/control/control.exports | 2 ++ src/ol/control/control.js | 17 ++++------------- 10 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 externs/oli.js create mode 100644 src/ol/control/control.exports diff --git a/build.py b/build.py index a2f90bdcbc..7533eb1d38 100755 --- a/build.py +++ b/build.py @@ -309,6 +309,7 @@ def examples_star_json(name, match): '../externs/bingmaps.js', '../externs/bootstrap.js', '../externs/geojson.js', + '../externs/oli.js', '../externs/proj4js.js', '../externs/tilejson.js', ], diff --git a/buildcfg/base.json b/buildcfg/base.json index 10924bb5e8..557581927e 100644 --- a/buildcfg/base.json +++ b/buildcfg/base.json @@ -42,6 +42,7 @@ "//json.js", "../externs/bingmaps.js", "../externs/geojson.js", + "../externs/oli.js", "../externs/proj4js.js", "../externs/tilejson.js" ], diff --git a/buildcfg/ol-all.json b/buildcfg/ol-all.json index 8b4f9dfa31..340936188c 100644 --- a/buildcfg/ol-all.json +++ b/buildcfg/ol-all.json @@ -7,6 +7,7 @@ "../build/src/external/externs/types.js", "../externs/bingmaps.js", "../externs/geojson.js", + "../externs/oli.js", "../externs/proj4js.js", "../externs/tilejson.js" ], diff --git a/buildcfg/ol-simple.json b/buildcfg/ol-simple.json index 3f2b82544e..c21ae1528e 100644 --- a/buildcfg/ol-simple.json +++ b/buildcfg/ol-simple.json @@ -16,6 +16,7 @@ "//json.js", "../externs/bingmaps.js", "../externs/geojson.js", + "../externs/oli.js", "../externs/proj4js.js", "../externs/tilejson.js" ], diff --git a/buildcfg/ol-whitespace.json b/buildcfg/ol-whitespace.json index 94089465b6..fb99f44cc3 100644 --- a/buildcfg/ol-whitespace.json +++ b/buildcfg/ol-whitespace.json @@ -17,6 +17,7 @@ "//json.js", "../externs/bingmaps.js", "../externs/geojson.js", + "../externs/oli.js", "../externs/proj4js.js", "../externs/tilejson.js" ], diff --git a/buildcfg/ol.json b/buildcfg/ol.json index 28f8d9c4ec..cb689bbddc 100644 --- a/buildcfg/ol.json +++ b/buildcfg/ol.json @@ -17,6 +17,7 @@ "../build/src/external/externs/types.js", "../externs/bingmaps.js", "../externs/geojson.js", + "../externs/oli.js", "../externs/proj4js.js", "../externs/tilejson.js" ], diff --git a/externs/oli.js b/externs/oli.js new file mode 100644 index 0000000000..4e4ce0a325 --- /dev/null +++ b/externs/oli.js @@ -0,0 +1,21 @@ +/** + * @externs + */ + + +/** + * @type {Object} + */ +var oli; + + +/** + * @interface + */ +oli.control.Control = function() {}; + +/** + * @param {ol.Map} map Map. + * @return {undefined} Undefined. + */ +oli.control.Control.prototype.setMap = function(map) {}; diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index d4423fa0f5..be7b0760e2 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -109,6 +109,13 @@ * @property {Element|undefined} target Target. */ + /** + * @typedef {Object} ol.control.ControlOptions + * @property {Element|undefined} element Element. + * @property {ol.Map|undefined} map Map. + * @property {Element|undefined} target Target. + */ + /** * @typedef {Object} ol.control.DefaultsOptions * @property {boolean|undefined} attribution Attribution. diff --git a/src/ol/control/control.exports b/src/ol/control/control.exports new file mode 100644 index 0000000000..203e867251 --- /dev/null +++ b/src/ol/control/control.exports @@ -0,0 +1,2 @@ +@exportClass ol.control.Control ol.control.ControlOptions +@exportProperty ol.control.Control.prototype.setMap diff --git a/src/ol/control/control.js b/src/ol/control/control.js index 6ae418f8b7..f9b7d16cca 100644 --- a/src/ol/control/control.js +++ b/src/ol/control/control.js @@ -1,5 +1,4 @@ goog.provide('ol.control.Control'); -goog.provide('ol.control.ControlOptions'); goog.require('goog.Disposable'); goog.require('goog.array'); @@ -8,14 +7,6 @@ goog.require('goog.events'); goog.require('ol.MapEventType'); -/** - * @typedef {{element: (Element|undefined), - * map: (ol.Map|undefined), - * target: (Element|undefined)}} - */ -ol.control.ControlOptions; - - /** * A thing which is painted over the map to provide a means for interaction @@ -23,6 +14,7 @@ ol.control.ControlOptions; * * @constructor * @extends {goog.Disposable} + * @implements {oli.control.Control} * @param {ol.control.ControlOptions} options Control options. */ ol.control.Control = function(options) { @@ -85,10 +77,9 @@ ol.control.Control.prototype.handleMapPostrender = goog.nullFunction; /** - * Removes the control from its current map and attaches it to the new map. - * Subtypes might also wish set up event handlers to get notified about changes - * to the map here. - * + * Remove the control from its current map and attach it to the new map. + * Subclasses may set up event handlers to get notified about changes to + * the map here. * @param {ol.Map} map Map. */ ol.control.Control.prototype.setMap = function(map) { From 9685c87bc9625e8a243fed5d401b64361d4620f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 28 Mar 2013 13:55:58 +0100 Subject: [PATCH 2/6] Create ol.inherits alias, and export it --- src/ol/ol.exports | 1 + src/ol/ol.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/ol/ol.exports create mode 100644 src/ol/ol.js diff --git a/src/ol/ol.exports b/src/ol/ol.exports new file mode 100644 index 0000000000..e6371ba44b --- /dev/null +++ b/src/ol/ol.exports @@ -0,0 +1 @@ +@exportSymbol ol.inherits diff --git a/src/ol/ol.js b/src/ol/ol.js new file mode 100644 index 0000000000..d118ba330f --- /dev/null +++ b/src/ol/ol.js @@ -0,0 +1,14 @@ +goog.provide('ol'); + + +/** + * ol.inherits is an alias to the goog.inherits function. It is exported + * for use in non-compiled application code. See ol.exports. + * + * FIXME: We use a new line to fake the linter. Without the new line the + * linter complains with: + * + * "Missing newline between constructor and goog.inherits" + */ +ol.inherits = + goog.inherits; From 4e5188865142ad79bdfd5fa7a0ccbc46c9c4d7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 28 Mar 2013 14:06:15 +0100 Subject: [PATCH 3/6] Add a custom controls example Inspired from @cedricmoullet's ZoomExtent example in https://github.com/cedricmoullet/ol3/commit/3312c37ed0ac93e9b3c2cb0cea76a070ea1c2cf4. --- examples/custom-controls.html | 94 +++++++++++++++++++++++++++++ examples/custom-controls.js | 109 ++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 examples/custom-controls.html create mode 100644 examples/custom-controls.js diff --git a/examples/custom-controls.html b/examples/custom-controls.html new file mode 100644 index 0000000000..257a02e3d9 --- /dev/null +++ b/examples/custom-controls.html @@ -0,0 +1,94 @@ + + + + + + + + + + + ol3 custom controls example + + + + + +
+ +
+
+
+
+
+ +
+
+

Custom controls

+

This example shows how to create custom controls.

+
+

+ This example creates a "zoom to extent" button. + See the custom-controls.js + source to see how this is done. + Per default, the zoom extent control use the map projection extent. +

+
+
+ custom, control +
+
+
+
+ + + + + + + diff --git a/examples/custom-controls.js b/examples/custom-controls.js new file mode 100644 index 0000000000..9ddadcc92d --- /dev/null +++ b/examples/custom-controls.js @@ -0,0 +1,109 @@ +goog.require('ol'); +goog.require('ol.Map'); +goog.require('ol.RendererHints'); +goog.require('ol.View2D'); +goog.require('ol.control.Control'); +goog.require('ol.control.defaults'); +goog.require('ol.layer.TileLayer'); +goog.require('ol.source.OSM'); + + +/** + * Define a namespace for the application. + */ +window.app = {}; +var app = window.app; + + +// +// Define zoom extent control. +// + + + +/** + * @constructor + * @extends {ol.control.Control} + * @param {Object=} opt_options Control options. + */ +app.ZoomExtentControl = function(opt_options) { + + var options = opt_options || {}; + this.extent_ = options.extent; + + var anchor = document.createElement('a'); + anchor.href = '#zoom-to'; + anchor.className = 'zoom-to'; + + var this_ = this; + var handleZoomTo = function(e) { + this_.handleZoomTo(e); + }; + + anchor.addEventListener('click', handleZoomTo, false); + anchor.addEventListener('touchstart', handleZoomTo, false); + + var element = document.createElement('div'); + element.className = 'zoom-extent ol-unselectable'; + element.appendChild(anchor); + + ol.control.Control.call(this, { + element: element, + map: options.map, + target: options.target + }); + +}; +ol.inherits(app.ZoomExtentControl, ol.control.Control); + + +/** + * @param {Event} e Browser event. + */ +app.ZoomExtentControl.prototype.handleZoomTo = function(e) { + // prevent #zoomTo anchor from getting appended to the url + e.preventDefault(); + + var map = this.getMap(); + var view = map.getView(); + view.fitExtent(this.extent_, map.getSize()); +}; + + +/** + * Overload setMap to use the view projection's validity extent + * if no extent was passed to the constructor. + * @param {ol.Map} map Map. + */ +app.ZoomExtentControl.prototype.setMap = function(map) { + ol.control.Control.prototype.setMap.call(this, map); + if (map && !this.extent_) { + this.extent_ = map.getView().getProjection().getExtent(); + } +}; + + +// +// Create map, giving it a zoom extent control. +// + + +var map = new ol.Map({ + controls: ol.control.defaults({}, [ + new app.ZoomExtentControl({ + extent: [813079.7791264898, 848966.9639063801, + 5929220.284081122, 5936863.986909639] + }) + ]), + layers: [ + new ol.layer.TileLayer({ + source: new ol.source.OSM() + }) + ], + renderers: ol.RendererHints.createFromQueryData(), + target: 'map', + view: new ol.View2D({ + center: [0, 0], + zoom: 2 + }) +}); From c845682ecbe9657ea7dd80e598a5935c095cf774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 28 Mar 2013 14:17:55 +0100 Subject: [PATCH 4/6] Export Control.getMap --- src/ol/control/control.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol/control/control.exports b/src/ol/control/control.exports index 203e867251..ad6eba3825 100644 --- a/src/ol/control/control.exports +++ b/src/ol/control/control.exports @@ -1,2 +1,3 @@ @exportClass ol.control.Control ol.control.ControlOptions +@exportProperty ol.control.Control.prototype.getMap @exportProperty ol.control.Control.prototype.setMap From 88352092ee14e249c91dcd5cf12fcf6d5acc0a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 9 May 2013 23:23:54 +0200 Subject: [PATCH 5/6] Externalize Control.handleMapPostrender --- externs/oli.js | 7 +++++++ src/ol/control/control.exports | 1 + src/ol/control/control.js | 3 +++ 3 files changed, 11 insertions(+) diff --git a/externs/oli.js b/externs/oli.js index 4e4ce0a325..f6feed46c6 100644 --- a/externs/oli.js +++ b/externs/oli.js @@ -14,6 +14,13 @@ var oli; */ oli.control.Control = function() {}; + +/** + * @param {ol.MapEvent} mapEvent Map event. + */ +oli.control.Control.prototype.handleMapPostrender = function(mapEvent) {}; + + /** * @param {ol.Map} map Map. * @return {undefined} Undefined. diff --git a/src/ol/control/control.exports b/src/ol/control/control.exports index ad6eba3825..d44b62ce15 100644 --- a/src/ol/control/control.exports +++ b/src/ol/control/control.exports @@ -1,3 +1,4 @@ @exportClass ol.control.Control ol.control.ControlOptions +@exportProperty ol.control.Control.prototype.handleMapPostrender @exportProperty ol.control.Control.prototype.getMap @exportProperty ol.control.Control.prototype.setMap diff --git a/src/ol/control/control.js b/src/ol/control/control.js index f9b7d16cca..7760d6e3f2 100644 --- a/src/ol/control/control.js +++ b/src/ol/control/control.js @@ -71,6 +71,9 @@ ol.control.Control.prototype.getMap = function() { /** + * Function called on each map render. Executes in a requestAnimationFrame + * callback. Can be implemented in sub-classes to re-render the control's + * UI. * @param {ol.MapEvent} mapEvent Map event. */ ol.control.Control.prototype.handleMapPostrender = goog.nullFunction; From 3a4fc2a99a5eda0df297dec4f8b5939b8aab09e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Fri, 10 May 2013 10:56:39 +0200 Subject: [PATCH 6/6] Use our own null function for handleMapPostrender If we use ol.control.Control.prototype.handleMapPostrender = goog.nullFunction the API doc doesn't show the mapEvent parameter of the handleMapPostRender function. --- src/ol/control/control.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ol/control/control.js b/src/ol/control/control.js index 7760d6e3f2..e63ba7671a 100644 --- a/src/ol/control/control.js +++ b/src/ol/control/control.js @@ -76,7 +76,7 @@ ol.control.Control.prototype.getMap = function() { * UI. * @param {ol.MapEvent} mapEvent Map event. */ -ol.control.Control.prototype.handleMapPostrender = goog.nullFunction; +ol.control.Control.prototype.handleMapPostrender = function(mapEvent) {}; /** @@ -98,7 +98,8 @@ ol.control.Control.prototype.setMap = function(map) { var target = goog.isDef(this.target_) ? this.target_ : map.getOverlayContainer(); goog.dom.appendChild(target, this.element); - if (this.handleMapPostrender !== goog.nullFunction) { + if (this.handleMapPostrender !== + ol.control.Control.prototype.handleMapPostrender) { this.listenerKeys.push(goog.events.listen(map, ol.MapEventType.POSTRENDER, this.handleMapPostrender, false, this)); }