Merge branch 'master' into multiple-builds
This commit is contained in:
@@ -79,7 +79,42 @@
|
||||
}
|
||||
}
|
||||
return (function() { return l; });
|
||||
})()
|
||||
})(),
|
||||
|
||||
/**
|
||||
* APIProperty: ImgPath
|
||||
* {String} Set this to the path where control images are stored, a path
|
||||
* given here must end with a slash. If set to '' (which is the default)
|
||||
* OpenLayers will use its script location + "img/".
|
||||
*
|
||||
* You will need to set this property when you have a singlefile build of
|
||||
* OpenLayers that either is not named "OpenLayers.js" or if you move
|
||||
* the file in a way such that the image directory cannot be derived from
|
||||
* the script location.
|
||||
*
|
||||
* If your custom OpenLayers build is named "my-custom-ol.js" and the images
|
||||
* of OpenLayers are in a folder "/resources/external/images/ol" a correct
|
||||
* way of including OpenLayers in your HTML would be:
|
||||
*
|
||||
* (code)
|
||||
* <script src="/path/to/my-custom-ol.js" type="text/javascript"></script>
|
||||
* <script type="text/javascript">
|
||||
* // tell OpenLayers where the control images are
|
||||
* // remember the trailing slash
|
||||
* OpenLayers.ImgPath = "/resources/external/images/ol/";
|
||||
* </script>
|
||||
* (end code)
|
||||
*
|
||||
* Please remember that when your OpenLayers script is not named
|
||||
* "OpenLayers.js" you will have to make sure that the default theme is
|
||||
* loaded into the page by including an appropriate <link>-tag,
|
||||
* e.g.:
|
||||
*
|
||||
* (code)
|
||||
* <link rel="stylesheet" href="/path/to/default/style.css" type="text/css">
|
||||
* (end code)
|
||||
*/
|
||||
ImgPath : ''
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -124,6 +159,7 @@
|
||||
"OpenLayers/Tile.js",
|
||||
"OpenLayers/Tile/Image.js",
|
||||
"OpenLayers/Tile/Image/IFrame.js",
|
||||
"OpenLayers/Tile/UTFGrid.js",
|
||||
"OpenLayers/Layer/Image.js",
|
||||
"OpenLayers/Layer/SphericalMercator.js",
|
||||
"OpenLayers/Layer/EventPane.js",
|
||||
@@ -146,6 +182,7 @@
|
||||
"OpenLayers/Layer/GeoRSS.js",
|
||||
"OpenLayers/Layer/Boxes.js",
|
||||
"OpenLayers/Layer/XYZ.js",
|
||||
"OpenLayers/Layer/UTFGrid.js",
|
||||
"OpenLayers/Layer/OSM.js",
|
||||
"OpenLayers/Layer/Bing.js",
|
||||
"OpenLayers/Layer/TMS.js",
|
||||
@@ -203,6 +240,7 @@
|
||||
"OpenLayers/Control/WMTSGetFeatureInfo.js",
|
||||
"OpenLayers/Control/Graticule.js",
|
||||
"OpenLayers/Control/TransformFeature.js",
|
||||
"OpenLayers/Control/UTFGrid.js",
|
||||
"OpenLayers/Control/SLDSelect.js",
|
||||
"OpenLayers/Control/Zoom.js",
|
||||
"OpenLayers/Geometry.js",
|
||||
|
||||
@@ -56,15 +56,19 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Bounds
|
||||
* Construct a new bounds object.
|
||||
* Construct a new bounds object. Coordinates can either be passed as four
|
||||
* arguments, or as a single argument.
|
||||
*
|
||||
* Parameters:
|
||||
* Parameters (four arguments):
|
||||
* left - {Number} The left bounds of the box. Note that for width
|
||||
* calculations, this is assumed to be less than the right value.
|
||||
* bottom - {Number} The bottom bounds of the box. Note that for height
|
||||
* calculations, this is assumed to be more than the top value.
|
||||
* right - {Number} The right bounds.
|
||||
* top - {Number} The top bounds.
|
||||
*
|
||||
* Parameters (single argument):
|
||||
* bounds - {Array(Number)} [left, bottom, right, top]
|
||||
*/
|
||||
initialize: function(left, bottom, right, top) {
|
||||
if (OpenLayers.Util.isArray(left)) {
|
||||
|
||||
@@ -27,15 +27,19 @@ OpenLayers.LonLat = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.LonLat
|
||||
* Create a new map location.
|
||||
* Create a new map location. Coordinates can be passed either as two
|
||||
* arguments, or as a single argument.
|
||||
*
|
||||
* Parameters:
|
||||
* Parameters (two arguments):
|
||||
* lon - {Number} The x-axis coordinate in map units. If your map is in
|
||||
* a geographic projection, this will be the Longitude. Otherwise,
|
||||
* it will be the x coordinate of the map location in your map units.
|
||||
* lat - {Number} The y-axis coordinate in map units. If your map is in
|
||||
* a geographic projection, this will be the Latitude. Otherwise,
|
||||
* it will be the y coordinate of the map location in your map units.
|
||||
*
|
||||
* Parameters (single argument):
|
||||
* location - {Array(Float)} [lon, lat]
|
||||
*/
|
||||
initialize: function(lon, lat) {
|
||||
if (OpenLayers.Util.isArray(lon)) {
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
/**
|
||||
* @requires OpenLayers/Control.js
|
||||
* @requires OpenLayers/Lang.js
|
||||
* @requires OpenLayers/Rule.js
|
||||
* @requires OpenLayers/StyleMap.js
|
||||
* @requires OpenLayers/Layer/Vector.js
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
240
lib/OpenLayers/Control/UTFGrid.js
Normal file
240
lib/OpenLayers/Control/UTFGrid.js
Normal file
@@ -0,0 +1,240 @@
|
||||
/* Copyright (c) 2006-2012 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/Control.js
|
||||
* @requires OpenLayers/Handler/Hover.js
|
||||
* @requires OpenLayers/Handler/Click.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Control.UTFGrid
|
||||
*
|
||||
* This Control provides behavior associated with UTFGrid Layers.
|
||||
* These 'hit grids' provide underlying feature attributes without
|
||||
* calling the server (again). This control allows Mousemove, Hovering
|
||||
* and Click events to trigger callbacks that use the attributes in
|
||||
* whatever way you need.
|
||||
*
|
||||
* The most common example may be a UTFGrid layer containing feature
|
||||
* attributes that are displayed in a div as you mouseover.
|
||||
*
|
||||
* Example Code:
|
||||
*
|
||||
* (start code)
|
||||
* var world_utfgrid = new OpenLayers.Layer.UTFGrid(
|
||||
* 'UTFGrid Layer',
|
||||
* "http://tiles/world_utfgrid/${z}/${x}/${y}.json"
|
||||
* );
|
||||
* map.addLayer(world_utfgrid);
|
||||
*
|
||||
* var control = new OpenLayers.Control.UTFGrid({
|
||||
* layers: [world_utfgrid],
|
||||
* handlerMode: 'move',
|
||||
* callback: function(infoLookup) {
|
||||
* // do something with returned data
|
||||
*
|
||||
* }
|
||||
* })
|
||||
* (end code)
|
||||
*
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Control>
|
||||
*/
|
||||
OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: autoActivate
|
||||
* {Boolean} Activate the control when it is added to a map. Default is
|
||||
* true.
|
||||
*/
|
||||
autoActivate: true,
|
||||
|
||||
/**
|
||||
* APIProperty: Layers
|
||||
* List of layers to consider. Must be Layer.UTFGrids
|
||||
* `null` is the default indicating all UTFGrid Layers are queried.
|
||||
* {Array} <OpenLayers.Layer.UTFGrid>
|
||||
*/
|
||||
layers: null,
|
||||
|
||||
/* Property: defaultHandlerOptions
|
||||
* The default opts passed to the handler constructors
|
||||
*/
|
||||
defaultHandlerOptions: {
|
||||
'delay': 300,
|
||||
'pixelTolerance': 4,
|
||||
'stopMove': false,
|
||||
'single': true,
|
||||
'double': false,
|
||||
'stopSingle': false,
|
||||
'stopDouble': false
|
||||
},
|
||||
|
||||
/* APIProperty: handlerMode
|
||||
* Defaults to 'click'. Can be 'hover' or 'move'.
|
||||
*/
|
||||
handlerMode: 'click',
|
||||
|
||||
/**
|
||||
* APIMethod: setHandler
|
||||
* sets this.handlerMode and calls resetHandler()
|
||||
*
|
||||
* Parameters:
|
||||
* hm - {String} Handler Mode string; 'click', 'hover' or 'move'.
|
||||
*/
|
||||
setHandler: function(hm) {
|
||||
this.handlerMode = hm;
|
||||
this.resetHandler();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: resetHandler
|
||||
* Deactivates the old hanlder and creates a new
|
||||
* <OpenLayers.Handler> based on the mode specified in
|
||||
* this.handlerMode
|
||||
*
|
||||
*/
|
||||
resetHandler: function() {
|
||||
if (this.handler) {
|
||||
this.handler.deactivate();
|
||||
this.handler.destroy();
|
||||
this.handler = null;
|
||||
}
|
||||
|
||||
if (this.handlerMode == 'hover') {
|
||||
// Handle this event on hover
|
||||
this.handler = new OpenLayers.Handler.Hover(
|
||||
this,
|
||||
{'pause': this.handleEvent, 'move': this.reset},
|
||||
this.handlerOptions
|
||||
);
|
||||
} else if (this.handlerMode == 'click') {
|
||||
// Handle this event on click
|
||||
this.handler = new OpenLayers.Handler.Click(
|
||||
this, {
|
||||
'click': this.handleEvent
|
||||
}, this.handlerOptions
|
||||
);
|
||||
} else if (this.handlerMode == 'move') {
|
||||
this.handler = new OpenLayers.Handler.Hover(
|
||||
this,
|
||||
// Handle this event while hovering OR moving
|
||||
{'pause': this.handleEvent, 'move': this.handleEvent},
|
||||
this.handlerOptions
|
||||
);
|
||||
}
|
||||
if (this.handler) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor: <OpenLayers.Control.UTFGrid>
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object}
|
||||
*/
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
options.handlerOptions = options.handlerOptions || this.defaultHandlerOptions;
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
this.resetHandler();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: handleEvent
|
||||
* Internal method called when specified event is triggered.
|
||||
*
|
||||
* This method does several things:
|
||||
*
|
||||
* Gets the lonLat of the event.
|
||||
*
|
||||
* Loops through the appropriate hit grid layers and gathers the attributes.
|
||||
*
|
||||
* Passes the attributes to the callback
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*/
|
||||
handleEvent: function(evt) {
|
||||
if (evt == null) {
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
var lonLat = this.map.getLonLatFromPixel(evt.xy);
|
||||
if (!lonLat) {
|
||||
return;
|
||||
}
|
||||
|
||||
var layers = this.findLayers();
|
||||
if (layers.length > 0) {
|
||||
var infoLookup = {};
|
||||
var layer, idx;
|
||||
for (var i=0, len=layers.length; i<len; i++) {
|
||||
layer = layers[i];
|
||||
idx = OpenLayers.Util.indexOf(this.map.layers, layer);
|
||||
infoLookup[idx] = layer.getFeatureInfo(lonLat);
|
||||
}
|
||||
this.callback(infoLookup, lonLat, evt.xy);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: callback
|
||||
* Function to be called when a mouse event corresponds with a location that
|
||||
* includes data in one of the configured UTFGrid layers.
|
||||
*
|
||||
* Parameters:
|
||||
* infoLookup - {Object} Keys of this object are layer indexes and can be
|
||||
* used to resolve a layer in the map.layers array. The structure of
|
||||
* the property values depend on the data included in the underlying
|
||||
* UTFGrid and may be any valid JSON type.
|
||||
*/
|
||||
callback: function(infoLookup) {
|
||||
// to be provided in the constructor
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: reset
|
||||
* Calls the callback with null.
|
||||
*/
|
||||
reset: function(evt) {
|
||||
this.callback(null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: findLayers
|
||||
* Internal method to get the layers, independent of whether we are
|
||||
* inspecting the map or using a client-provided array
|
||||
*
|
||||
* The default value of this.layers is null; this causes the
|
||||
* findLayers method to return ALL UTFGrid layers encountered.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returns:
|
||||
* {Array} Layers to handle on each event
|
||||
*/
|
||||
findLayers: function() {
|
||||
var candidates = this.layers || this.map.layers;
|
||||
var layers = [];
|
||||
var layer;
|
||||
for (var i=candidates.length-1; i>=0; --i) {
|
||||
layer = candidates[i];
|
||||
if (layer instanceof OpenLayers.Layer.UTFGrid ) {
|
||||
layers.push(layer);
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.UTFGrid"
|
||||
});
|
||||
@@ -87,7 +87,7 @@ OpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(
|
||||
"TextSymbolizer": function(symbolizer) {
|
||||
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
|
||||
var node = writers["sld"]["TextSymbolizer"].apply(this, arguments);
|
||||
if (symbolizer.externalGraphic || symbolizer.graphicName) {
|
||||
if (symbolizer.graphic !== false && (symbolizer.externalGraphic || symbolizer.graphicName)) {
|
||||
this.writeNode("Graphic", symbolizer, node);
|
||||
}
|
||||
if ("priority" in symbolizer) {
|
||||
|
||||
@@ -88,7 +88,6 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
* Supported map event types:
|
||||
* loadstart - Triggered when layer loading starts.
|
||||
* loadend - Triggered when layer loading ends.
|
||||
* loadcancel - Triggered when layer loading is canceled.
|
||||
* visibilitychanged - Triggered when layer visibility is changed.
|
||||
* move - Triggered when layer moves (triggered with every mousemove
|
||||
* during a drag).
|
||||
@@ -229,7 +228,11 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: maxExtent
|
||||
* {<OpenLayers.Bounds>} The center of these bounds will not stray outside
|
||||
* {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* The maximum extent for the layer. Defaults to null.
|
||||
*
|
||||
* The center of these bounds will not stray outside
|
||||
* of the viewport extent during panning. In addition, if
|
||||
* <displayOutsideMaxExtent> is set to false, data will not be
|
||||
* requested that falls completely outside of these bounds.
|
||||
@@ -238,7 +241,9 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: minExtent
|
||||
* {<OpenLayers.Bounds>}
|
||||
* {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* The minimum extent for the layer. Defaults to null.
|
||||
*/
|
||||
minExtent: null,
|
||||
|
||||
|
||||
@@ -196,6 +196,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
* element - {DOMElement} A reference to layer.events.element.
|
||||
*
|
||||
* Supported event types:
|
||||
* tileloadstart - Triggered when a tile starts loading. Listeners receive
|
||||
* an object as first argument, which has a tile property that
|
||||
* references the tile that starts loading.
|
||||
* tileloaded - Triggered when each new tile is
|
||||
* loaded, as a means of progress update to listeners.
|
||||
* listeners can access 'numLoadingTiles' if they wish to keep
|
||||
@@ -416,6 +419,64 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getTileData
|
||||
* Given a map location, retrieve a tile and the pixel offset within that
|
||||
* tile corresponding to the location. If there is not an existing
|
||||
* tile in the grid that covers the given location, null will be
|
||||
* returned.
|
||||
*
|
||||
* Parameters:
|
||||
* loc - {<OpenLayers.LonLat>} map location
|
||||
*
|
||||
* Returns:
|
||||
* {Object} Object with the following properties: tile ({<OpenLayers.Tile>}),
|
||||
* i ({Number} x-pixel offset from top left), and j ({Integer} y-pixel
|
||||
* offset from top left).
|
||||
*/
|
||||
getTileData: function(loc) {
|
||||
var data = null,
|
||||
x = loc.lon,
|
||||
y = loc.lat,
|
||||
numRows = this.grid.length;
|
||||
|
||||
if (this.map && numRows) {
|
||||
var res = this.map.getResolution(),
|
||||
tileWidth = this.tileSize.w,
|
||||
tileHeight = this.tileSize.h,
|
||||
bounds = this.grid[0][0].bounds,
|
||||
left = bounds.left,
|
||||
top = bounds.top;
|
||||
|
||||
if (x < left) {
|
||||
// deal with multiple worlds
|
||||
if (this.map.baseLayer.wrapDateLine) {
|
||||
var worldWidth = this.map.getMaxExtent().getWidth();
|
||||
var worldsAway = Math.ceil((left - x) / worldWidth);
|
||||
x += worldWidth * worldsAway;
|
||||
}
|
||||
}
|
||||
// tile distance to location (fractional number of tiles);
|
||||
var dtx = (x - left) / (res * tileWidth);
|
||||
var dty = (top - y) / (res * tileHeight);
|
||||
// index of tile in grid
|
||||
var col = Math.floor(dtx);
|
||||
var row = Math.floor(dty);
|
||||
if (row >= 0 && row < numRows) {
|
||||
var tile = this.grid[row][col];
|
||||
if (tile) {
|
||||
data = {
|
||||
tile: tile,
|
||||
// pixel index within tile
|
||||
i: Math.floor((dtx - col) * tileWidth),
|
||||
j: Math.floor((dty - row) * tileHeight)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: queueTileDraw
|
||||
@@ -718,15 +779,36 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
|
||||
//determine new tile bounds
|
||||
var center = bounds.getCenterLonLat();
|
||||
|
||||
var tileWidth = bounds.getWidth() * this.ratio;
|
||||
var tileHeight = bounds.getHeight() * this.ratio;
|
||||
|
||||
|
||||
var tileBounds =
|
||||
new OpenLayers.Bounds(center.lon - (tileWidth/2),
|
||||
center.lat - (tileHeight/2),
|
||||
center.lon + (tileWidth/2),
|
||||
center.lat + (tileHeight/2));
|
||||
|
||||
|
||||
// adjust tile bounds so they do not exceed maxExtent, except when the
|
||||
// layer's maxExtent equals the world bounds or displayOutsideMaxExtent
|
||||
// is set to true
|
||||
var ignoreMaxExtent =
|
||||
(this.map.baseLayer.wrapDateLine &&
|
||||
this.maxExtent.equals(this.map.getMaxExtent())) ||
|
||||
this.displayOutsideMaxExtent;
|
||||
if(!ignoreMaxExtent) {
|
||||
tileBounds.bottom = Math.max(this.maxExtent.bottom, tileBounds.bottom);
|
||||
tileBounds.top = Math.min(this.maxExtent.top, tileBounds.top);
|
||||
tileBounds.left = Math.max(this.maxExtent.left, tileBounds.left);
|
||||
tileBounds.right = Math.min(this.maxExtent.right, tileBounds.right);
|
||||
tileWidth = tileBounds.getWidth();
|
||||
tileHeight = tileBounds.getHeight();
|
||||
}
|
||||
var resolution = this.map.getResolution(),
|
||||
size = this.tileSize;
|
||||
size.w = (tileWidth / resolution) | 0;
|
||||
size.h = (tileHeight / resolution) | 0;
|
||||
|
||||
var px = this.map.getLayerPxFromLonLat({
|
||||
lon: tileBounds.left,
|
||||
lat: tileBounds.top
|
||||
@@ -971,6 +1053,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
if (this.numLoadingTiles == 0) {
|
||||
this.events.triggerEvent("loadstart");
|
||||
}
|
||||
this.events.triggerEvent("tileloadstart", {tile: tile});
|
||||
this.numLoadingTiles++;
|
||||
};
|
||||
|
||||
|
||||
178
lib/OpenLayers/Layer/UTFGrid.js
Normal file
178
lib/OpenLayers/Layer/UTFGrid.js
Normal file
@@ -0,0 +1,178 @@
|
||||
/* Copyright (c) 2006-2012 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/Layer/XYZ.js
|
||||
* @requires OpenLayers/Tile/UTFGrid.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Layer.UTFGrid
|
||||
* This Layer reads from UTFGrid tiled data sources. Since UTFGrids are
|
||||
* essentially JSON-based ASCII art with attached attributes, they are not
|
||||
* visibly rendered. In order to use them in the map, you must add a
|
||||
* <OpenLayers.Control.UTFGrid> ontrol as well.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (start code)
|
||||
* var world_utfgrid = new OpenLayers.Layer.UTFGrid({
|
||||
* url: "/tiles/world_utfgrid/${z}/${x}/${y}.json",
|
||||
* utfgridResolution: 4,
|
||||
* displayInLayerSwitcher: false
|
||||
* );
|
||||
* map.addLayer(world_utfgrid);
|
||||
*
|
||||
* var control = new OpenLayers.Control.UTFGrid({
|
||||
* layers: [world_utfgrid],
|
||||
* handlerMode: 'move',
|
||||
* callback: function(dataLookup) {
|
||||
* // do something with returned data
|
||||
* }
|
||||
* })
|
||||
* (end code)
|
||||
*
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Layer.XYZ>
|
||||
*/
|
||||
OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
|
||||
|
||||
/**
|
||||
* APIProperty: isBaseLayer
|
||||
* Default is true, as this is designed to be a base tile source.
|
||||
*/
|
||||
isBaseLayer: false,
|
||||
|
||||
/**
|
||||
* APIProperty: projection
|
||||
* {<OpenLayers.Projection>}
|
||||
* Source projection for the UTFGrids. Default is "EPSG:900913".
|
||||
*/
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
|
||||
/**
|
||||
* Property: useJSONP
|
||||
* {Boolean}
|
||||
* Should we use a JSONP script approach instead of a standard AJAX call?
|
||||
*
|
||||
* Set to true for using utfgrids from another server.
|
||||
* Avoids same-domain policy restrictions.
|
||||
* Note that this only works if the server accepts
|
||||
* the callback GET parameter and dynamically
|
||||
* wraps the returned json in a function call.
|
||||
*
|
||||
* Default is false
|
||||
*/
|
||||
useJSONP: false,
|
||||
|
||||
/**
|
||||
* APIProperty: url
|
||||
* {String}
|
||||
* URL tempate for UTFGrid tiles. Include x, y, and z parameters.
|
||||
* E.g. "/tiles/${z}/${x}/${y}.json"
|
||||
*/
|
||||
|
||||
/**
|
||||
* APIProperty: utfgridResolution
|
||||
* {Number}
|
||||
* Ratio of the pixel width to the width of a UTFGrid data point. If an
|
||||
* entry in the grid represents a 4x4 block of pixels, the
|
||||
* utfgridResolution would be 4. Default is 2 (specified in
|
||||
* <OpenLayers.Tile.UTFGrid>).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Property: tileClass
|
||||
* {<OpenLayers.Tile>} The tile class to use for this layer.
|
||||
* Defaults is <OpenLayers.Tile.UTFGrid>.
|
||||
*/
|
||||
tileClass: OpenLayers.Tile.UTFGrid,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Layer.UTFGrid
|
||||
* Create a new UTFGrid layer.
|
||||
*
|
||||
* Parameters:
|
||||
* config - {Object} Configuration properties for the layer.
|
||||
*
|
||||
* Required configuration properties:
|
||||
* url - {String} The url template for UTFGrid tiles. See the <url> property.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Layer.Grid.prototype.initialize.apply(
|
||||
this, [options.name, options.url, {}, options]
|
||||
);
|
||||
this.tileOptions = OpenLayers.Util.extend({
|
||||
utfgridResolution: this.utfgridResolution
|
||||
}, this.tileOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: clone
|
||||
* Create a clone of this layer
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {Object} Only used by a subclass of this layer.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.UTFGrid>} An exact clone of this OpenLayers.Layer.UTFGrid
|
||||
*/
|
||||
clone: function (obj) {
|
||||
if (obj == null) {
|
||||
obj = new OpenLayers.Layer.UTFGrid(this.getOptions());
|
||||
}
|
||||
|
||||
// get all additions from superclasses
|
||||
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIProperty: getFeatureInfo
|
||||
* Get details about a feature associated with a map location. The object
|
||||
* returned will have id and data properties. If the given location
|
||||
* doesn't correspond to a feature, null will be returned.
|
||||
*
|
||||
* Parameters:
|
||||
* location - {<OpenLayers.LonLat>} map location
|
||||
*
|
||||
* Returns:
|
||||
* {Object} Object representing the feature id and UTFGrid data
|
||||
* corresponding to the given map location. Returns null if the given
|
||||
* location doesn't hit a feature.
|
||||
*/
|
||||
getFeatureInfo: function(location) {
|
||||
var info = null;
|
||||
var tileInfo = this.getTileData(location);
|
||||
if (tileInfo.tile) {
|
||||
info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);
|
||||
}
|
||||
return info;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: getFeatureId
|
||||
* Get the identifier for the feature associated with a map location.
|
||||
*
|
||||
* Parameters:
|
||||
* location - {<OpenLayers.LonLat>} map location
|
||||
*
|
||||
* Returns:
|
||||
* {String} The feature identifier corresponding to the given map location.
|
||||
* Returns null if the location doesn't hit a feature.
|
||||
*/
|
||||
getFeatureId: function(location) {
|
||||
var id = null;
|
||||
var info = this.getTileData(location);
|
||||
if (info.tile) {
|
||||
id = info.tile.getFeatureId(info.i, info.j);
|
||||
}
|
||||
return id;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Layer.UTFGrid"
|
||||
});
|
||||
@@ -537,6 +537,9 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
if (OpenLayers.Renderer.NG && this.renderer instanceof OpenLayers.Renderer.NG) {
|
||||
this.drawn = false;
|
||||
}
|
||||
this.resolution = null; // this is to force Layer.redraw set
|
||||
// zoomChanged to true in the moveTo
|
||||
// call
|
||||
return OpenLayers.Layer.prototype.redraw.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -1023,4 +1026,4 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Layer.Vector"
|
||||
});
|
||||
});
|
||||
|
||||
@@ -307,7 +307,9 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: maxExtent
|
||||
* {<OpenLayers.Bounds>} The maximum extent for the map. Defaults to the
|
||||
* {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* The maximum extent for the map. Defaults to the
|
||||
* whole world in decimal degrees (-180, -90, 180, 90). Specify a
|
||||
* different extent in the map options if you are not using a geographic
|
||||
* projection and displaying the whole world. To restrict user panning
|
||||
@@ -318,13 +320,17 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: minExtent
|
||||
* {<OpenLayers.Bounds>}
|
||||
* {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* The minimum extent for the map. Defaults to null.
|
||||
*/
|
||||
minExtent: null,
|
||||
|
||||
/**
|
||||
* APIProperty: restrictedExtent
|
||||
* {<OpenLayers.Bounds>} Limit map navigation to this extent where possible.
|
||||
* {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* Limit map navigation to this extent where possible.
|
||||
* If a non-null restrictedExtent is set, panning will be restricted
|
||||
* to the given bounds. In addition, zooming to a resolution that
|
||||
* displays more than the restricted extent will center the map
|
||||
@@ -436,6 +442,24 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
* provided or if you intend to call the <render> method later.
|
||||
* options - {Object} Optional object with properties to tag onto the map.
|
||||
*
|
||||
* Valid options (in addition to the listed API properties):
|
||||
* center - {<OpenLayers.LonLat>|Array} The default initial center of the map.
|
||||
* If provided as array, the first value is the x coordinate,
|
||||
* and the 2nd value is the y coordinate.
|
||||
* Only specify if <layers> is provided.
|
||||
* Note that if an ArgParser/Permalink control is present,
|
||||
* and the querystring contains coordinates, center will be set
|
||||
* by that, and this option will be ignored.
|
||||
* zoom - {Number} The initial zoom level for the map. Only specify if
|
||||
* <layers> is provided.
|
||||
* Note that if an ArgParser/Permalink control is present,
|
||||
* and the querystring contains a zoom level, zoom will be set
|
||||
* by that, and this option will be ignored.
|
||||
* extent - {<OpenLayers.Bounds>|Array} The initial extent of the map.
|
||||
* If provided as an array, the array should consist of
|
||||
* four values (left, bottom, right, top).
|
||||
* Only specify if <center> and <zoom> are not provided.
|
||||
*
|
||||
* Examples:
|
||||
* (code)
|
||||
* // create a map with default options in an element with the id "map1"
|
||||
@@ -443,28 +467,26 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
*
|
||||
* // create a map with non-default options in an element with id "map2"
|
||||
* var options = {
|
||||
* projection: "EPSG:3857",
|
||||
* maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
|
||||
* maxResolution: 156543,
|
||||
* units: 'm',
|
||||
* projection: "EPSG:41001"
|
||||
* center: new OpenLayers.LonLat(-12356463.476333, 5621521.4854095)
|
||||
* };
|
||||
* var map = new OpenLayers.Map("map2", options);
|
||||
*
|
||||
* // map with non-default options - same as above but with a single argument
|
||||
* // map with non-default options - same as above but with a single argument,
|
||||
* // a restricted extent, and using arrays for bounds and center
|
||||
* var map = new OpenLayers.Map({
|
||||
* div: "map_id",
|
||||
* maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
|
||||
* maxResolution: 156543,
|
||||
* units: 'm',
|
||||
* projection: "EPSG:41001"
|
||||
* projection: "EPSG:3857",
|
||||
* maxExtent: [-18924313.432222, -15538711.094146, 18924313.432222, 15538711.094146],
|
||||
* restrictedExtent: [-13358338.893333, -9608371.5085962, 13358338.893333, 9608371.5085962],
|
||||
* center: [-12356463.476333, 5621521.4854095]
|
||||
* });
|
||||
*
|
||||
* // create a map without a reference to a container - call render later
|
||||
* var map = new OpenLayers.Map({
|
||||
* maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
|
||||
* maxResolution: 156543,
|
||||
* units: 'm',
|
||||
* projection: "EPSG:41001"
|
||||
* projection: "EPSG:3857",
|
||||
* maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000)
|
||||
* });
|
||||
* (end)
|
||||
*/
|
||||
@@ -500,6 +522,9 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
|
||||
this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
|
||||
}
|
||||
if (this.minExtent && !(this.minExtent instanceof OpenLayers.Bounds)) {
|
||||
this.minExtent = new OpenLayers.Bounds(this.minExtent);
|
||||
}
|
||||
if (this.restrictedExtent && !(this.restrictedExtent instanceof OpenLayers.Bounds)) {
|
||||
this.restrictedExtent = new OpenLayers.Bounds(this.restrictedExtent);
|
||||
}
|
||||
@@ -625,7 +650,7 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
if (options && options.layers) {
|
||||
/**
|
||||
* If you have set options.center, the map center property will be
|
||||
* set at this point. However, since setCenter has not been caleld,
|
||||
* set at this point. However, since setCenter has not been called,
|
||||
* addLayers gets confused. So we delete the map center in this
|
||||
* case. Because the check below uses options.center, it will
|
||||
* be properly set below.
|
||||
@@ -1662,7 +1687,9 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
* Set the map center (and optionally, the zoom level).
|
||||
*
|
||||
* Parameters:
|
||||
* lonlat - {<OpenLayers.LonLat>} The new center location.
|
||||
* lonlat - {<OpenLayers.LonLat>|Array} The new center location.
|
||||
* If provided as array, the first value is the x coordinate,
|
||||
* and the 2nd value is the y coordinate.
|
||||
* zoom - {Integer} Optional zoom level.
|
||||
* dragging - {Boolean} Specifies whether or not to trigger
|
||||
* movestart/end events
|
||||
@@ -2282,7 +2309,8 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
* Zoom to the passed in bounds, recenter
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bounds>}
|
||||
* bounds - {<OpenLayers.Bounds>|Array} If provided as an array, the array
|
||||
* should consist of four values (left, bottom, right, top).
|
||||
* closest - {Boolean} Find the zoom level that most closely fits the
|
||||
* specified bounds. Note that this may result in a zoom that does
|
||||
* not exactly contain the entire extent.
|
||||
|
||||
@@ -39,5 +39,40 @@ var OpenLayers = {
|
||||
}
|
||||
}
|
||||
return (function() { return l; });
|
||||
})()
|
||||
})(),
|
||||
|
||||
/**
|
||||
* Property: ImgPath
|
||||
* {String} Set this to the path where control images are stored, a path
|
||||
* given here must end with a slash. If set to '' (which is the default)
|
||||
* OpenLayers will use its script location + "img/".
|
||||
*
|
||||
* You will need to set this property when you have a singlefile build of
|
||||
* OpenLayers that either is not named "OpenLayers.js" or if you move
|
||||
* the file in a way such that the image directory cannot be derived from
|
||||
* the script location.
|
||||
*
|
||||
* If your custom OpenLayers build is named "my-custom-ol.js" and the images
|
||||
* of OpenLayers are in a folder "/resources/external/images/ol" a correct
|
||||
* way of including OpenLayers in your HTML would be:
|
||||
*
|
||||
* (code)
|
||||
* <script src="/path/to/my-custom-ol.js" type="text/javascript"></script>
|
||||
* <script type="text/javascript">
|
||||
* // tell OpenLayers where the control images are
|
||||
* // remember the trailing slash
|
||||
* OpenLayers.ImgPath = "/resources/external/images/ol/";
|
||||
* </script>
|
||||
* (end code)
|
||||
*
|
||||
* Please remember that when your OpenLayers script is not named
|
||||
* "OpenLayers.js" you will have to make sure that the default theme is
|
||||
* loaded into the page by including an appropriate <link>-tag,
|
||||
* e.g.:
|
||||
*
|
||||
* (code)
|
||||
* <link rel="stylesheet" href="/path/to/default/style.css" type="text/css">
|
||||
* (end code)
|
||||
*/
|
||||
ImgPath : ''
|
||||
};
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||
|
||||
/**
|
||||
* Property: url
|
||||
* APIProperty: url
|
||||
* {String} The URL of the image being requested. No default. Filled in by
|
||||
* layer.getURL() function.
|
||||
* layer.getURL() function. May be modified by loadstart listeners.
|
||||
*/
|
||||
url: null,
|
||||
|
||||
@@ -166,10 +166,10 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||
}
|
||||
if (this.isLoading) {
|
||||
//if we're already loading, send 'reload' instead of 'loadstart'.
|
||||
this.events.triggerEvent("reload");
|
||||
this._loadEvent = "reload";
|
||||
} else {
|
||||
this.isLoading = true;
|
||||
this.events.triggerEvent("loadstart");
|
||||
this._loadEvent = "loadstart";
|
||||
}
|
||||
this.positionTile();
|
||||
this.renderTile();
|
||||
@@ -287,6 +287,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||
* Creates the content for the frame on the tile.
|
||||
*/
|
||||
initImage: function() {
|
||||
this.events.triggerEvent(this._loadEvent);
|
||||
var img = this.getImage();
|
||||
if (this.url && img.getAttribute("src") == this.url) {
|
||||
this.onImageLoad();
|
||||
@@ -315,8 +316,8 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||
} else {
|
||||
OpenLayers.Event.observe(img, "load", load);
|
||||
OpenLayers.Event.observe(img, "error", load);
|
||||
if (img.crossOrigin) {
|
||||
img.crossOrigin = null;
|
||||
if (this.crossOriginKeyword) {
|
||||
img.removeAttribute("crossorigin");
|
||||
}
|
||||
img.src = this.blankImageUrl;
|
||||
}
|
||||
@@ -336,8 +337,12 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||
img.style.opacity = 0;
|
||||
if (url) {
|
||||
// don't set crossOrigin if the url is a data URL
|
||||
if (this.crossOriginKeyword && url.substr(0, 5 !== 'data:')) {
|
||||
img.crossOrigin = this.crossOriginKeyword;
|
||||
if (this.crossOriginKeyword) {
|
||||
if (url.substr(0, 5) !== 'data:') {
|
||||
img.setAttribute("crossorigin", this.crossOriginKeyword);
|
||||
} else {
|
||||
img.removeAttribute("crossorigin");
|
||||
}
|
||||
}
|
||||
img.src = url;
|
||||
}
|
||||
|
||||
251
lib/OpenLayers/Tile/UTFGrid.js
Normal file
251
lib/OpenLayers/Tile/UTFGrid.js
Normal file
@@ -0,0 +1,251 @@
|
||||
/* Copyright (c) 2006-2012 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/Format/JSON.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Tile.UTFGrid
|
||||
* Instances of OpenLayers.Tile.UTFGrid are used to manage
|
||||
* UTFGrids. This is an unusual tile type in that it doesn't have a
|
||||
* rendered image; only a 'hit grid' that can be used to
|
||||
* look up feature attributes.
|
||||
*
|
||||
* See the <OpenLayers.Tile.UTFGrid> constructor for details on constructing a
|
||||
* new instance.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Tile>
|
||||
*/
|
||||
OpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {
|
||||
|
||||
/**
|
||||
* Property: url
|
||||
* {String}
|
||||
* The URL of the UTFGrid file being requested. Provided by the <getURL>
|
||||
* method.
|
||||
*/
|
||||
url: null,
|
||||
|
||||
/**
|
||||
* Property: utfgridResolution
|
||||
* {Number}
|
||||
* Ratio of the pixel width to the width of a UTFGrid data point. If an
|
||||
* entry in the grid represents a 4x4 block of pixels, the
|
||||
* utfgridResolution would be 4. Default is 2.
|
||||
*/
|
||||
utfgridResolution: 2,
|
||||
|
||||
/**
|
||||
* Property: json
|
||||
* {Object}
|
||||
* Stores the parsed JSON tile data structure.
|
||||
*/
|
||||
json: null,
|
||||
|
||||
/**
|
||||
* Property: format
|
||||
* {OpenLayers.Format.JSON}
|
||||
* Parser instance used to parse JSON for cross browser support. The native
|
||||
* JSON.parse method will be used where available (all except IE<8).
|
||||
*/
|
||||
format: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Tile.UTFGrid
|
||||
* Constructor for a new <OpenLayers.Tile.UTFGrid> instance.
|
||||
*
|
||||
* Parameters:
|
||||
* layer - {<OpenLayers.Layer>} layer that the tile will go in.
|
||||
* position - {<OpenLayers.Pixel>}
|
||||
* bounds - {<OpenLayers.Bounds>}
|
||||
* url - {<String>} Deprecated. Remove me in 3.0.
|
||||
* size - {<OpenLayers.Size>}
|
||||
* options - {Object}
|
||||
*/
|
||||
|
||||
/**
|
||||
* APIMethod: destroy
|
||||
* Clean up.
|
||||
*/
|
||||
destroy: function() {
|
||||
this.clear();
|
||||
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: draw
|
||||
* Check that a tile should be drawn, and draw it.
|
||||
* In the case of UTFGrids, "drawing" it means fetching and
|
||||
* parsing the json.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} Was a tile drawn?
|
||||
*/
|
||||
draw: function() {
|
||||
var drawn = OpenLayers.Tile.prototype.draw.apply(this, arguments);
|
||||
if (drawn) {
|
||||
if (this.isLoading) {
|
||||
this.abortLoading();
|
||||
//if we're already loading, send 'reload' instead of 'loadstart'.
|
||||
this.events.triggerEvent("reload");
|
||||
} else {
|
||||
this.isLoading = true;
|
||||
this.events.triggerEvent("loadstart");
|
||||
}
|
||||
this.url = this.layer.getURL(this.bounds);
|
||||
|
||||
if (this.layer.useJSONP) {
|
||||
// Use JSONP method to avoid xbrowser policy
|
||||
var ols = new OpenLayers.Protocol.Script({
|
||||
url: this.url,
|
||||
callback: function(response) {
|
||||
this.isLoading = false;
|
||||
this.events.triggerEvent("loadend");
|
||||
this.json = response.data;
|
||||
},
|
||||
scope: this
|
||||
});
|
||||
ols.read();
|
||||
this.request = ols;
|
||||
} else {
|
||||
// Use standard XHR
|
||||
this.request = OpenLayers.Request.GET({
|
||||
url: this.url,
|
||||
callback: function(response) {
|
||||
this.isLoading = false;
|
||||
this.events.triggerEvent("loadend");
|
||||
if (response.status === 200) {
|
||||
this.parseData(response.responseText);
|
||||
}
|
||||
},
|
||||
scope: this
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.unload();
|
||||
}
|
||||
return drawn;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: abortLoading
|
||||
* Cancel a pending request.
|
||||
*/
|
||||
abortLoading: function() {
|
||||
if (this.request) {
|
||||
this.request.abort();
|
||||
delete this.request;
|
||||
}
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getFeatureInfo
|
||||
* Get feature information associated with a pixel offset. If the pixel
|
||||
* offset corresponds to a feature, the returned object will have id
|
||||
* and data properties. Otherwise, null will be returned.
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
* i - {Number} X-axis pixel offset (from top left of tile)
|
||||
* j - {Number} Y-axis pixel offset (from top left of tile)
|
||||
*
|
||||
* Returns:
|
||||
* {Object} Object with feature id and data properties corresponding to the
|
||||
* given pixel offset.
|
||||
*/
|
||||
getFeatureInfo: function(i, j) {
|
||||
var info = null;
|
||||
if (this.json) {
|
||||
var id = this.getFeatureId(i, j);
|
||||
if (id !== null) {
|
||||
info = {id: id, data: this.json.data[id]};
|
||||
}
|
||||
}
|
||||
return info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getFeatureId
|
||||
* Get the identifier for the feature associated with a pixel offset.
|
||||
*
|
||||
* Parameters:
|
||||
* i - {Number} X-axis pixel offset (from top left of tile)
|
||||
* j - {Number} Y-axis pixel offset (from top left of tile)
|
||||
*
|
||||
* Returns:
|
||||
* {Object} The feature identifier corresponding to the given pixel offset.
|
||||
* Returns null if pixel doesn't correspond to a feature.
|
||||
*/
|
||||
getFeatureId: function(i, j) {
|
||||
var id = null;
|
||||
if (this.json) {
|
||||
var resolution = this.utfgridResolution;
|
||||
var row = Math.floor(j / resolution);
|
||||
var col = Math.floor(i / resolution);
|
||||
var charCode = this.json.grid[row].charCodeAt(col);
|
||||
var index = this.indexFromCharCode(charCode);
|
||||
var keys = this.json.keys;
|
||||
if (!isNaN(index) && (index in keys)) {
|
||||
id = keys[index];
|
||||
}
|
||||
}
|
||||
return id;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: indexFromCharCode
|
||||
* Given a character code for one of the UTFGrid "grid" characters,
|
||||
* resolve the integer index for the feature id in the UTFGrid "keys"
|
||||
* array.
|
||||
*
|
||||
* Parameters:
|
||||
* charCode - {Integer}
|
||||
*
|
||||
* Returns:
|
||||
* {Integer} Index for the feature id from the keys array.
|
||||
*/
|
||||
indexFromCharCode: function(charCode) {
|
||||
if (charCode >= 93) {
|
||||
charCode--;
|
||||
}
|
||||
if (charCode >= 35) {
|
||||
charCode --;
|
||||
}
|
||||
return charCode - 32;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: parseData
|
||||
* Parse the JSON from a request
|
||||
*
|
||||
* Parameters:
|
||||
* str - {String} UTFGrid as a JSON string.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} parsed javascript data
|
||||
*/
|
||||
parseData: function(str) {
|
||||
if (!this.format) {
|
||||
this.format = new OpenLayers.Format.JSON();
|
||||
}
|
||||
this.json = this.format.read(str);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: clear
|
||||
* Delete data stored with this tile.
|
||||
*/
|
||||
clear: function() {
|
||||
this.json = null;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Tile.UTFGrid"
|
||||
|
||||
});
|
||||
@@ -559,14 +559,6 @@ OpenLayers.Util.urlAppend = function(url, paramStr) {
|
||||
return newUrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* APIProperty: ImgPath
|
||||
* {String} Set this to the path where control images are stored.
|
||||
* If set to '' OpenLayers will use script location + "img/"
|
||||
* Default is ''.
|
||||
*/
|
||||
OpenLayers.ImgPath = '';
|
||||
|
||||
/**
|
||||
* Function: getImagesLocation
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user