summaryrefslogtreecommitdiff
path: root/misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js')
-rw-r--r--misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js319
1 files changed, 319 insertions, 0 deletions
diff --git a/misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js b/misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js
new file mode 100644
index 0000000..f647238
--- /dev/null
+++ b/misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js
@@ -0,0 +1,319 @@
+/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the 2-clause BSD license.
+ * See license.txt in the OpenLayers distribution or repository for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Layer.js
+ */
+
+/**
+ * Class: OpenLayers.Layer.FixedZoomLevels
+ * Some Layers will already have established zoom levels (like google
+ * or ve). Instead of trying to determine them and populate a resolutions[]
+ * Array with those values, we will hijack the resolution functionality
+ * here.
+ *
+ * When you subclass FixedZoomLevels:
+ *
+ * The initResolutions() call gets nullified, meaning no resolutions[] array
+ * is set up. Which would be a big problem getResolution() in Layer, since
+ * it merely takes map.zoom and indexes into resolutions[]... but....
+ *
+ * The getResolution() call is also overridden. Instead of using the
+ * resolutions[] array, we simply calculate the current resolution based
+ * on the current extent and the current map size. But how will we be able
+ * to calculate the current extent without knowing the resolution...?
+ *
+ * The getExtent() function is also overridden. Instead of calculating extent
+ * based on the center point and the current resolution, we instead
+ * calculate the extent by getting the lonlats at the top-left and
+ * bottom-right by using the getLonLatFromViewPortPx() translation function,
+ * taken from the pixel locations (0,0) and the size of the map. But how
+ * will we be able to do lonlat-px translation without resolution....?
+ *
+ * The getZoomForResolution() method is overridden. Instead of indexing into
+ * the resolutions[] array, we call OpenLayers.Layer.getExent(), passing in
+ * the desired resolution. With this extent, we then call getZoomForExtent()
+ *
+ *
+ * Whenever you implement a layer using OpenLayers.Layer.FixedZoomLevels,
+ * it is your responsibility to provide the following three functions:
+ *
+ * - getLonLatFromViewPortPx
+ * - getViewPortPxFromLonLat
+ * - getZoomForExtent
+ *
+ * ...those three functions should generally be provided by any reasonable
+ * API that you might be working from.
+ *
+ */
+OpenLayers.Layer.FixedZoomLevels = OpenLayers.Class({
+
+ /********************************************************/
+ /* */
+ /* Baselayer Functions */
+ /* */
+ /* The following functions must all be implemented */
+ /* by all base layers */
+ /* */
+ /********************************************************/
+
+ /**
+ * Constructor: OpenLayers.Layer.FixedZoomLevels
+ * Create a new fixed zoom levels layer.
+ */
+ initialize: function() {
+ //this class is only just to add the following functions...
+ // nothing to actually do here... but it is probably a good
+ // idea to have layers that use these functions call this
+ // inititalize() anyways, in case at some point we decide we
+ // do want to put some functionality or state in here.
+ },
+
+ /**
+ * Method: initResolutions
+ * Populate the resolutions array
+ */
+ initResolutions: function() {
+
+ var props = ['minZoomLevel', 'maxZoomLevel', 'numZoomLevels'];
+
+ for(var i=0, len=props.length; i<len; i++) {
+ var property = props[i];
+ this[property] = (this.options[property] != null)
+ ? this.options[property]
+ : this.map[property];
+ }
+
+ if ( (this.minZoomLevel == null) ||
+ (this.minZoomLevel < this.MIN_ZOOM_LEVEL) ){
+ this.minZoomLevel = this.MIN_ZOOM_LEVEL;
+ }
+
+ //
+ // At this point, we know what the minimum desired zoom level is, and
+ // we must calculate the total number of zoom levels.
+ //
+ // Because we allow for the setting of either the 'numZoomLevels'
+ // or the 'maxZoomLevel' properties... on either the layer or the
+ // map, we have to define some rules to see which we take into
+ // account first in this calculation.
+ //
+ // The following is the precedence list for these properties:
+ //
+ // (1) numZoomLevels set on layer
+ // (2) maxZoomLevel set on layer
+ // (3) numZoomLevels set on map
+ // (4) maxZoomLevel set on map*
+ // (5) none of the above*
+ //
+ // *Note that options (4) and (5) are only possible if the user
+ // _explicitly_ sets the 'numZoomLevels' property on the map to
+ // null, since it is set by default to 16.
+ //
+
+ //
+ // Note to future: In 3.0, I think we should remove the default
+ // value of 16 for map.numZoomLevels. Rather, I think that value
+ // should be set as a default on the Layer.WMS class. If someone
+ // creates a 3rd party layer and does not specify any 'minZoomLevel',
+ // 'maxZoomLevel', or 'numZoomLevels', and has not explicitly
+ // specified any of those on the map object either.. then I think
+ // it is fair to say that s/he wants all the zoom levels available.
+ //
+ // By making map.numZoomLevels *null* by default, that will be the
+ // case. As it is, I don't feel comfortable changing that right now
+ // as it would be a glaring API change and actually would probably
+ // break many peoples' codes.
+ //
+
+ //the number of zoom levels we'd like to have.
+ var desiredZoomLevels;
+
+ //this is the maximum number of zoom levels the layer will allow,
+ // given the specified starting minimum zoom level.
+ var limitZoomLevels = this.MAX_ZOOM_LEVEL - this.minZoomLevel + 1;
+
+ if ( ((this.options.numZoomLevels == null) &&
+ (this.options.maxZoomLevel != null)) // (2)
+ ||
+ ((this.numZoomLevels == null) &&
+ (this.maxZoomLevel != null)) // (4)
+ ) {
+ //calculate based on specified maxZoomLevel (on layer or map)
+ desiredZoomLevels = this.maxZoomLevel - this.minZoomLevel + 1;
+ } else {
+ //calculate based on specified numZoomLevels (on layer or map)
+ // this covers cases (1) and (3)
+ desiredZoomLevels = this.numZoomLevels;
+ }
+
+ if (desiredZoomLevels != null) {
+ //Now that we know what we would *like* the number of zoom levels
+ // to be, based on layer or map options, we have to make sure that
+ // it does not conflict with the actual limit, as specified by
+ // the constants on the layer itself (and calculated into the
+ // 'limitZoomLevels' variable).
+ this.numZoomLevels = Math.min(desiredZoomLevels, limitZoomLevels);
+ } else {
+ // case (5) -- neither 'numZoomLevels' not 'maxZoomLevel' was
+ // set on either the layer or the map. So we just use the
+ // maximum limit as calculated by the layer's constants.
+ this.numZoomLevels = limitZoomLevels;
+ }
+
+ //now that the 'numZoomLevels' is appropriately, safely set,
+ // we go back and re-calculate the 'maxZoomLevel'.
+ this.maxZoomLevel = this.minZoomLevel + this.numZoomLevels - 1;
+
+ if (this.RESOLUTIONS != null) {
+ var resolutionsIndex = 0;
+ this.resolutions = [];
+ for(var i= this.minZoomLevel; i <= this.maxZoomLevel; i++) {
+ this.resolutions[resolutionsIndex++] = this.RESOLUTIONS[i];
+ }
+ this.maxResolution = this.resolutions[0];
+ this.minResolution = this.resolutions[this.resolutions.length - 1];
+ }
+ },
+
+ /**
+ * APIMethod: getResolution
+ * Get the current map resolution
+ *
+ * Returns:
+ * {Float} Map units per Pixel
+ */
+ getResolution: function() {
+
+ if (this.resolutions != null) {
+ return OpenLayers.Layer.prototype.getResolution.apply(this, arguments);
+ } else {
+ var resolution = null;
+
+ var viewSize = this.map.getSize();
+ var extent = this.getExtent();
+
+ if ((viewSize != null) && (extent != null)) {
+ resolution = Math.max( extent.getWidth() / viewSize.w,
+ extent.getHeight() / viewSize.h );
+ }
+ return resolution;
+ }
+ },
+
+ /**
+ * APIMethod: getExtent
+ * Calculates using px-> lonlat translation functions on tl and br
+ * corners of viewport
+ *
+ * Returns:
+ * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
+ * bounds of the current viewPort.
+ */
+ getExtent: function () {
+ var size = this.map.getSize();
+ var tl = this.getLonLatFromViewPortPx({
+ x: 0, y: 0
+ });
+ var br = this.getLonLatFromViewPortPx({
+ x: size.w, y: size.h
+ });
+
+ if ((tl != null) && (br != null)) {
+ return new OpenLayers.Bounds(tl.lon, br.lat, br.lon, tl.lat);
+ } else {
+ return null;
+ }
+ },
+
+ /**
+ * Method: getZoomForResolution
+ * Get the zoom level for a given resolution
+ *
+ * Parameters:
+ * resolution - {Float}
+ *
+ * Returns:
+ * {Integer} A suitable zoom level for the specified resolution.
+ * If no baselayer is set, returns null.
+ */
+ getZoomForResolution: function(resolution) {
+
+ if (this.resolutions != null) {
+ return OpenLayers.Layer.prototype.getZoomForResolution.apply(this, arguments);
+ } else {
+ var extent = OpenLayers.Layer.prototype.getExtent.apply(this, []);
+ return this.getZoomForExtent(extent);
+ }
+ },
+
+
+
+
+ /********************************************************/
+ /* */
+ /* Translation Functions */
+ /* */
+ /* The following functions translate GMaps and OL */
+ /* formats for Pixel, LonLat, Bounds, and Zoom */
+ /* */
+ /********************************************************/
+
+
+ //
+ // TRANSLATION: MapObject Zoom <-> OpenLayers Zoom
+ //
+
+ /**
+ * Method: getOLZoomFromMapObjectZoom
+ * Get the OL zoom index from the map object zoom level
+ *
+ * Parameters:
+ * moZoom - {Integer}
+ *
+ * Returns:
+ * {Integer} An OpenLayers Zoom level, translated from the passed in zoom
+ * Returns null if null value is passed in
+ */
+ getOLZoomFromMapObjectZoom: function(moZoom) {
+ var zoom = null;
+ if (moZoom != null) {
+ zoom = moZoom - this.minZoomLevel;
+ if (this.map.baseLayer !== this) {
+ zoom = this.map.baseLayer.getZoomForResolution(
+ this.getResolutionForZoom(zoom)
+ );
+ }
+ }
+ return zoom;
+ },
+
+ /**
+ * Method: getMapObjectZoomFromOLZoom
+ * Get the map object zoom level from the OL zoom level
+ *
+ * Parameters:
+ * olZoom - {Integer}
+ *
+ * Returns:
+ * {Integer} A MapObject level, translated from the passed in olZoom
+ * Returns null if null value is passed in
+ */
+ getMapObjectZoomFromOLZoom: function(olZoom) {
+ var zoom = null;
+ if (olZoom != null) {
+ zoom = olZoom + this.minZoomLevel;
+ if (this.map.baseLayer !== this) {
+ zoom = this.getZoomForResolution(
+ this.map.baseLayer.getResolutionForZoom(zoom)
+ );
+ }
+ }
+ return zoom;
+ },
+
+ CLASS_NAME: "OpenLayers.Layer.FixedZoomLevels"
+});
+