[Commits] r1876 - in core/trunk/geoext: examples lib lib/GeoExt/plugins tests tests/lib/GeoExt/plugins
commits at geoext.org
commits at geoext.org
Tue Feb 9 15:49:35 CET 2010
Author: ahocevar
Date: 2010-02-09 15:49:35 +0100 (Tue, 09 Feb 2010)
New Revision: 1876
Added:
core/trunk/geoext/examples/print-extent.html
core/trunk/geoext/examples/print-extent.js
core/trunk/geoext/lib/GeoExt/plugins/PrintExtent.js
core/trunk/geoext/tests/lib/GeoExt/plugins/PrintExtent.html
Modified:
core/trunk/geoext/lib/GeoExt.js
core/trunk/geoext/tests/list-tests.html
Log:
added a MapPanel plugin for interactively modifying the print extent. Thanks elemoine for refactoring this to become a plugin instead of a component. p=elemoine,me, r=elemoine,me (closes #204)
Added: core/trunk/geoext/examples/print-extent.html
===================================================================
--- core/trunk/geoext/examples/print-extent.html (rev 0)
+++ core/trunk/geoext/examples/print-extent.html 2010-02-09 14:49:35 UTC (rev 1876)
@@ -0,0 +1,35 @@
+<html>
+ <head>
+ <title>GeoExt PrintExtent Example</title>
+
+ <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+ <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
+ <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+ <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+ <script src="http://www.openlayers.org/dev/OpenLayers.js"></script>
+ <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+ <script type="text/javascript" src="print-extent.js"></script>
+
+ <!-- The script below will load the capabilities of the print service
+ and save them into the global printCapabilities variable. Instead
+ of this, the PrintProvider can be configured with a url and take
+ care of fetching the capabilities. -->
+ <script type="text/javascript" src="http://demo.opengeo.org/geoserver/pdf/info.json?var=printCapabilities"></script>
+
+ </head>
+ <body>
+ <h1>Setting the Print Extent on the Map Interactively</h1>
+ <p>This example shows the how to set the bounds of a printable PDF
+ interactively with a dynamic print extent rectangle. It requires
+ the <a href="http://trac.mapfish.org/trac/mapfish/wiki/PrintModuleInstallation">MapFish</a>
+ or <a href="http://geoserver.org/display/GEOS/Printing+2.0+HOWTO">GeoServer</a>
+ print module.</p>
+ <p>Drag one of the handles to control the scale. Grab one of the
+ corner handles at its edge to rotate the extent. Hold the SHIFT key to
+ rotate in 45° increments only. Drag the extent rectangle to change the
+ center.</p>
+ <p>The js is not minified so it is readable. See <a href="print-extent.js">print-extent.js</a>.</p>
+ <div id="content"></div>
+ </body>
+</html>
Added: core/trunk/geoext/examples/print-extent.js
===================================================================
--- core/trunk/geoext/examples/print-extent.js (rev 0)
+++ core/trunk/geoext/examples/print-extent.js 2010-02-09 14:49:35 UTC (rev 1876)
@@ -0,0 +1,51 @@
+ /**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ *
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+/** api: example[print-extent]
+ * Setting the Print Extent interactively
+ * --------------------------------------
+ * Using the PrintExtent component to interactively change scale, center and
+ * rotation of a print page.
+ */
+
+var mapPanel, printProvider;
+
+Ext.onReady(function() {
+ // The printProvider that connects us to the print service
+ printProvider = new GeoExt.data.PrintProvider({
+ method: "GET", // "POST" recommended for production use
+ capabilities: printCapabilities, // from the info.json script in the html
+ customParams: {
+ mapTitle: "Printing Demo",
+ comment: "This is a map printed from GeoExt."
+ }
+ });
+
+ // The map we want to print, with the PrintExtent added as item.
+ mapPanel = new GeoExt.MapPanel({
+ renderTo: "content",
+ width: 450,
+ height: 320,
+ layers: [new OpenLayers.Layer.WMS("Tasmania", "http://demo.opengeo.org/geoserver/wms",
+ {layers: "topp:tasmania_state_boundaries"}, {singleTile: true})],
+ center: [146.56, -41.56],
+ zoom: 6,
+ plugins: [
+ new GeoExt.plugins.PrintExtent({
+ printProvider: printProvider
+ })
+ ],
+ bbar: [{
+ text: "Create PDF",
+ handler: function() {
+ // the PrintExtent plugin is the mapPanel's 1st plugin
+ mapPanel.plugins[0].print();
+ }
+ }]
+ });
+});
Added: core/trunk/geoext/lib/GeoExt/plugins/PrintExtent.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/plugins/PrintExtent.js (rev 0)
+++ core/trunk/geoext/lib/GeoExt/plugins/PrintExtent.js 2010-02-09 14:49:35 UTC (rev 1876)
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ *
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+Ext.namespace("GeoExt.plugins")
+
+/** api: (define)
+ * module = GeoExt.plugins
+ * class = PrintExtent
+ */
+
+/** api: example
+ * Sample code to create a MapPanel with a PrintExtent, and print it
+ * immediately:
+ *
+ * .. code-block:: javascript
+ *
+ * var printExtent = new GeoExt.plugins.PrintExtent({
+ * printProvider: new GeoExt.data.PrintProvider({
+ * capabilities: printCapabilities
+ * })
+ * });
+ *
+ * var mapPanel = new GeoExt.MapPanel({
+ * border: false,
+ * renderTo: "div-id",
+ * layers: [new OpenLayers.Layer.WMS("Tasmania", "http://demo.opengeo.org/geoserver/wms",
+ * {layers: "topp:tasmania_state_boundaries"}, {singleTile: true})],
+ * center: [146.56, -41.56],
+ * zoom: 6,
+ * plugins: printExtent
+ * });
+ *
+ * // print the map
+ * printExtent.print();
+ */
+
+/** api: constructor
+ * .. class:: PrintExtent
+ *
+ * Provides a way to show and modify the extents of print pages on the map. It
+ * uses a layer to render the page extent and handle features of print pages,
+ * and provides a control to modify them. Must be set as a plugin to a
+ * :class:`GeoExt.MapPanel`.
+ */
+
+GeoExt.plugins.PrintExtent = function(config) {
+ config = config || {};
+
+ Ext.apply(this, config);
+ this.initialConfig = config;
+
+ if(!this.pages) {
+ this.pages = [new GeoExt.data.PrintPage({
+ printProvider: this.printProvider
+ })];
+ }
+
+ if(!this.printProvider) {
+ this.printProvider = this.pages[0].printProvider;
+ }
+};
+
+GeoExt.plugins.PrintExtent.prototype = {
+
+ /** private: initialConfig
+ * ``Object`` Holds the initial config object passed to the
+ * constructor.
+ */
+ initialConfig: null,
+
+ /** api: config[printProvider]
+ * :class:`GeoExt.data.PrintProvider` The print provider this form
+ * is connected to. Optional if pages are provided.
+ */
+ /** api: property[printProvider]
+ * :class:`GeoExt.data.PrintProvider` The print provider this form
+ * is connected to. Read-only.
+ */
+ printProvider: null,
+
+ /** private: property[mapPanel]
+ * ``OpenLayers.Map`` The map the layer and control are added to.
+ */
+ map: null,
+
+ /** api: config[layer]
+ * ``OpenLayers.Layer.Vector`` The layer used to render extent and handle
+ * features to. Optional, will be created if not provided.
+ */
+ /** private: property[layer]
+ * ``OpenLayers.Layer.Vector`` The layer used to render extent and handle
+ * features to.
+ */
+ layer: null,
+
+ /** private: property[control]
+ * ``OpenLayers.Control.TransformFeature`` The control used to change
+ * extent, center, rotation and scale.
+ */
+ control: null,
+
+ /** api: config[pages]
+ * Array of :class:`GeoExt.data.PrintPage` The pages that this form
+ * controls. Optional. If not provided, it will be created with one page
+ * that fits the current map extent.
+ *
+ * .. note:: All pages must use the same PrintProvider.
+ */
+ /** api: property[pages]
+ * Array of :class:`GeoExt.data.PrintPage` The pages that this component
+ * controls. Read-only.
+ */
+ pages: null,
+
+ /** api: property[page]
+ * :class:`GeoExt.data.PrintPage` The page currently set for
+ * transformation.
+ */
+ page: null,
+
+ /** api: method[print]
+ * :param options: ``Object`` Options to send to the PrintProvider's
+ * print method. See :ref:`GeoExt.data.PrintProvider.print`.
+ *
+ * Prints all pages as shown on the map.
+ */
+ print: function(options) {
+ this.printProvider.print(this.map, this.pages, options);
+ },
+
+ /** private: method[init]
+ * :param mapPanel: class:`GeoExt.MapPanel`
+ *
+ * Initializes the plugin.
+ */
+ init: function(mapPanel) {
+ this.map = mapPanel.map;
+ mapPanel.on("destroy", this.onMapPanelDestroy, this);
+ this.setUp();
+ },
+
+ /** api: method[setUp]
+ * Sets up the plugin, initializing the ``OpenLayers.Layer.Vector``
+ * layer and ``OpenLayers.Control.TransformFeature``, and centering
+ * the first page if no pages were specified in the configuration.
+ */
+ setUp: function() {
+ this.initLayer();
+
+ this.initControl();
+ this.map.addControl(this.control);
+ this.control.activate();
+
+ this.printProvider.on("layoutchange", this.updateBox, this);
+
+ if(!this.initialConfig.pages) {
+ this.page = this.pages[0];
+ var map = this.map;
+ if(map.getCenter()) {
+ this.fitPage();
+ } else {
+ map.events.register("moveend", this, function() {
+ map.events.unregister("moveend", this, arguments.callee);
+ this.fitPage();
+ });
+ }
+ }
+ },
+
+ /** private: method[tearDown]
+ * Tear downs the plugin, removing the
+ * ``OpenLayers.Control.TransformFeature`` control and
+ * the ``OpenLayers.Layer.Vector`` layer.
+ */
+ tearDown: function() {
+ // note: we need to be extra cautious when destroying OpenLayers
+ // objects here (the tests will fail if we're not cautious anyway).
+ // We use obj.events to test whether an OpenLayers object is
+ // destroyed or not.
+
+ this.printProvider.un("layoutchange", this.updateBox, this);
+
+ var map = this.map;
+
+ var control = this.control;
+ if(control && control.events) {
+ control.deactivate();
+ if(map && map.events && control.map) {
+ map.removeControl(control);
+ }
+ }
+
+ var layer = this.layer;
+ if(layer && layer.events) {
+ for(var i=0, len=this.pages.length; i<len; ++i) {
+ var page = this.pages[i];
+ page.un("change", this.onPageChange, this);
+ layer.removeFeatures([page.feature]);
+ }
+ }
+
+ if(!this.initialConfig.layer &&
+ map && map.events &&
+ layer && layer.map) {
+ map.removeLayer(layer);
+ }
+ },
+
+ /** private: method[onMapPanelDestroy]
+ */
+ onMapPanelDestroy: function() {
+ this.tearDown();
+
+ var map = this.map;
+
+ var control = this.control;
+ if(map && map.events &&
+ control && control.events) {
+ control.destroy()
+ }
+
+ var layer = this.layer;
+ if(!this.initialConfig.layer &&
+ map && map.events &&
+ layer && layer.events) {
+ layer.destroy();
+ }
+
+ delete this.layer;
+ delete this.control;
+ delete this.page;
+ this.map = null;
+ },
+
+ /** private: method[initLayer]
+ */
+ initLayer: function() {
+ if(!this.layer) {
+ this.layer = new OpenLayers.Layer.Vector(null, {
+ displayInLayerSwitcher: false
+ });
+ }
+ for(var i=0, len=this.pages.length; i<len; ++i) {
+ var page = this.pages[i];
+ this.layer.addFeatures([page.feature]);
+ page.on("change", this.onPageChange, this);
+ }
+ if(!this.layer.map) {
+ this.map.addLayer(this.layer);
+ }
+ },
+
+ /** private: method[initControl]
+ */
+ initControl: function() {
+ var pages = this.pages;
+
+ if(!this.control) {
+ this.control = new OpenLayers.Control.TransformFeature(this.layer, {
+ preserveAspectRatio: true,
+ eventListeners: {
+ "beforesetfeature": function(e) {
+ for(var i=0, len=this.pages.length; i<len; ++i) {
+ if(this.pages[i].feature === e.feature) {
+ this.page = this.pages[i];
+ e.object.rotation = -this.pages[i].rotation;
+ break;
+ }
+ }
+ },
+ "beforetransform": function(e) {
+ var page = this.page;
+ if(e.rotation) {
+ if(this.printProvider.layout.get("rotation")) {
+ page.setRotation(-e.object.rotation);
+ } else {
+ e.object.setFeature(page.feature);
+ }
+ } else {
+ page.fit(e.object.box);
+ var minScale = this.printProvider.scales.getAt(0);
+ var maxScale = this.printProvider.scales.getAt(
+ this.printProvider.scales.getCount() - 1);
+ var boxBounds = e.object.box.geometry.getBounds();
+ var pageBounds = page.feature.geometry.getBounds();
+ var tooLarge = page.scale === minScale &&
+ boxBounds.containsBounds(pageBounds);
+ var tooSmall = page.scale === maxScale &&
+ pageBounds.containsBounds(boxBounds);
+ if(tooLarge === true || tooSmall === true) {
+ this.updateBox();
+ }
+ }
+ return false;
+ },
+ "transformcomplete": this.updateBox,
+ scope: this
+ }
+ });
+ }
+ },
+
+ /** private: method[fitPage]
+ * Fits the current print page to the map.
+ */
+ fitPage: function() {
+ if(this.page) {
+ this.page.fit(this.map);
+ }
+ },
+
+ /** private: method[updateBox]
+ * Updates the transformation box after setting a new scale or
+ * layout, or to fit the box to the extent feature after a tranform.
+ */
+ updateBox: function() {
+ var page = this.page;
+ this.control.setFeature(page.feature, {rotation: -page.rotation});
+ },
+
+ /** private: method[onPageChange]
+ * Handler for a page's change event.
+ */
+ onPageChange: function(page, mods) {
+ if(mods.scale || this.control.feature !== page.feature) {
+ this.control.setFeature(page.feature, {rotation: -page.rotation});
+ }
+ }
+};
+
+/** api: ptype = gx_printextent */
+Ext.preg && Ext.preg("gx_printextent", GeoExt.plugins.PrintExtent);
Modified: core/trunk/geoext/lib/GeoExt.js
===================================================================
--- core/trunk/geoext/lib/GeoExt.js 2010-02-09 10:56:57 UTC (rev 1875)
+++ core/trunk/geoext/lib/GeoExt.js 2010-02-09 14:49:35 UTC (rev 1876)
@@ -112,6 +112,7 @@
"GeoExt/data/PrintProvider.js",
"GeoExt/plugins/PrintPageField.js",
"GeoExt/plugins/PrintProviderField.js",
+ "GeoExt/plugins/PrintExtent.js",
"GeoExt/widgets/PrintMapPanel.js"
);
Added: core/trunk/geoext/tests/lib/GeoExt/plugins/PrintExtent.html
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/plugins/PrintExtent.html (rev 0)
+++ core/trunk/geoext/tests/lib/GeoExt/plugins/PrintExtent.html 2010-02-09 14:49:35 UTC (rev 1876)
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html debug="true">
+ <head>
+ <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script>
+ <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script>
+ <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script>
+ <script type="text/javascript" src="../../../../lib/GeoExt.js"></script>
+
+ <script type="text/javascript">
+ var printCapabilities = {"scales":[{"name":"1:25,000","value":"25000"},{"name":"1:50,000","value":"50000"},{"name":"1:100,000","value":"100000"},{"name":"1:200,000","value":"200000"},{"name":"1:500,000","value":"500000"},{"name":"1:1,000,000","value":"1000000"},{"name":"1:2,000,000","value":"2000000"},{"name":"1:4,000,000","value":"4000000"}],"dpis":[{"name":"75","value":"75"},{"name":"150","value":"150"},{"name":"300","value":"300"}],"layouts":[{"name":"A4 portrait","map":{"width":440,"height":483},"rotation":true},{"name":"Legal","map":{"width":440,"height":483},"rotation":false}],"printURL":"http://demo.opengeo.org/geoserver/pdf/print.pdf","createURL":"http://demo.opengeo.org/geoserver/pdf/create.json"};
+
+ function test_ctor(t) {
+ t.plan(2);
+
+ var printProvider = new GeoExt.data.PrintProvider({
+ capabilities: printCapabilities
+ })
+
+ var printExtent = new GeoExt.plugins.PrintExtent({
+ printProvider: printProvider
+ });
+
+ t.ok(printExtent.printProvider === printProvider,
+ "ctor sets printProvider in the instance");
+ t.ok(printExtent.pages[0] instanceof GeoExt.data.PrintPage,
+ "ctor creates a PrintPage");
+ }
+
+ function test_init(t) {
+ t.plan(2);
+
+ var printExtent = new GeoExt.plugins.PrintExtent({
+ printProvider: new GeoExt.data.PrintProvider({
+ capabilities: printCapabilities
+ })
+ });
+
+ var mapPanel = new GeoExt.MapPanel({
+ renderTo: "mappanel",
+ width: 256,
+ height: 256,
+ map: {controls: []},
+ layers: [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ center: [146.56, -41.56],
+ zoom: 7,
+ plugins: [printExtent]
+ });
+
+ t.ok(printExtent.map === mapPanel.map,
+ "init sets mapPanel");
+ t.ok(mapPanel.hasListener("destroy"),
+ "plugin listens to the panel destroy event");
+
+ mapPanel.destroy();
+ }
+
+ function test_destroy(t) {
+ t.plan(3);
+
+ var printExtent = new GeoExt.plugins.PrintExtent({
+ printProvider: new GeoExt.data.PrintProvider({
+ capabilities: printCapabilities
+ })
+ });
+
+ var mapPanel = new GeoExt.MapPanel({
+ renderTo: "mappanel",
+ width: 256,
+ height: 256,
+ map: {controls: []},
+ layers: [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ center: [146.56, -41.56],
+ zoom: 7,
+ items: [printExtent]
+ });
+
+ mapPanel.destroy();
+
+ t.eq(printExtent.layer, undefined,
+ "layer destroyed");
+ t.eq(printExtent.control, undefined,
+ "control destroyed.");
+ t.eq(printExtent.mapPanel, null,
+ "mapPanel set to null");
+ }
+
+ function test_setUp(t) {
+ t.plan(4);
+
+ var printExtent = new GeoExt.plugins.PrintExtent({
+ printProvider: new GeoExt.data.PrintProvider({
+ capabilities: printCapabilities
+ })
+ });
+
+ var mapPanel = new GeoExt.MapPanel({
+ renderTo: "mappanel",
+ width: 256,
+ height: 256,
+ map: {controls: []},
+ layers: [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ center: [146.56, -41.56],
+ zoom: 7,
+ plugins: [printExtent]
+ });
+
+ t.ok(printExtent.pages[0].getCenter().equals(mapPanel.map.getCenter()),
+ "print page centered to map center");
+ t.ok(printExtent.layer.map == mapPanel.map,
+ "auto-generated layer added to map.");
+ t.ok(printExtent.pages[0].feature.layer == printExtent.layer,
+ "extent feature was added to the layer.");
+ t.ok(printExtent.control.map == mapPanel.map,
+ "control created and added to map.");
+
+ mapPanel.destroy();
+ }
+
+ function test_tearDown(t) {
+ t.plan(3);
+
+ var printExtent = new GeoExt.plugins.PrintExtent({
+ printProvider: new GeoExt.data.PrintProvider({
+ capabilities: printCapabilities
+ })
+ });
+
+ var mapPanel = new GeoExt.MapPanel({
+ renderTo: "mappanel",
+ width: 256,
+ height: 256,
+ map: {controls: []},
+ layers: [
+ new OpenLayers.Layer("layer", {isBaseLayer: true})
+ ],
+ center: [146.56, -41.56],
+ zoom: 7,
+ plugins: [printExtent]
+ });
+
+ printExtent.tearDown();
+
+ t.eq(mapPanel.map.layers.length, 1,
+ "layer was removed.");
+ t.eq(mapPanel.map.controls.length, 0,
+ "control was removed.");
+ t.eq(printExtent.pages[0].feature.layer, null,
+ "feature was removed from the layer.")
+
+ mapPanel.destroy();
+ }
+ </script>
+ <body>
+ <div id="mappanel"></div>
+ </body>
+</html>
Modified: core/trunk/geoext/tests/list-tests.html
===================================================================
--- core/trunk/geoext/tests/list-tests.html 2010-02-09 10:56:57 UTC (rev 1875)
+++ core/trunk/geoext/tests/list-tests.html 2010-02-09 14:49:35 UTC (rev 1876)
@@ -17,6 +17,7 @@
<li>lib/GeoExt/data/WMCReader.html</li>
<li>lib/GeoExt/plugins/PrintPageField.html</li>
<li>lib/GeoExt/plugins/PrintProviderField.html</li>
+ <li>lib/GeoExt/plugins/PrintExtent.html</li>
<li>lib/GeoExt/widgets/Action.html</li>
<li>lib/GeoExt/widgets/FeatureRenderer.html</li>
<li>lib/GeoExt/widgets/LayerOpacitySlider.html</li>
More information about the Commits
mailing list