Method for getting both feature id and data.

Having to call two methods to get complete feature information (id and data) is cumbersome.  The `getFeatureInfo` method returns an object with both feature id and data.
This commit is contained in:
Tim Schaub
2012-02-28 05:37:28 -07:00
parent 19a11561e8
commit 4d31a3ed3a
6 changed files with 75 additions and 54 deletions
+13 -12
View File
@@ -8,8 +8,8 @@
<link rel="stylesheet" href="style.css" type="text/css"> <link rel="stylesheet" href="style.css" type="text/css">
<script src="../lib/OpenLayers.js"></script> <script src="../lib/OpenLayers.js"></script>
<style> <style>
#attrsdiv { #attrs {
float: right; height: 1.5em;
} }
#controlToggle li { list-style: none; } #controlToggle li { list-style: none; }
</style> </style>
@@ -21,11 +21,11 @@
<div id="shortdesc"> <div id="shortdesc">
This page demonstrates the use of the OpenLayers UTFGrid Controls. This page demonstrates the use of the OpenLayers UTFGrid Controls.
</div> </div>
<div id="attrsdiv"></div>
<div id="themap" class="smallmap"></div> <div id="themap" class="smallmap"></div>
<p> <p>
When the selected event is triggered, the underlying feature attributes are shown below. When the selected event is triggered, the underlying feature attributes are shown below.
</p> </p>
<div id="attrs">&nbsp;</div>
<ul id="controlToggle"> <ul id="controlToggle">
<li> <li>
<input type="radio" name="type" value="move" id="moveHandler" <input type="radio" name="type" value="move" id="moveHandler"
@@ -71,20 +71,21 @@
/* /*
* Controls * Controls
*/ */
var callback = function(dataLookup) { var callback = function(infoLookup) {
var msg = ""; var msg = "";
if (dataLookup) { if (infoLookup) {
var data; var info;
for (var idx in dataLookup) { for (var idx in infoLookup) {
// idx can be used to retrieve layer from map.layers[idx] // idx can be used to retrieve layer from map.layers[idx]
data = dataLookup[idx]; info = infoLookup[idx];
if (data) { if (info && info.data) {
msg += "<strong>In 2005, " + data.NAME + " had a population of " + msg += "[" + info.id + "] <strong>In 2005, " +
data.POP2005 + " people.</strong> "; info.data.NAME + " had a population of " +
info.data.POP2005 + " people.</strong> ";
} }
} }
} }
document.getElementById("attrsdiv").innerHTML = msg; document.getElementById("attrs").innerHTML = msg;
}; };
var controls = { var controls = {
+9 -8
View File
@@ -58,17 +58,18 @@
); );
map.addLayers([bio_utfgrid,world_utfgrid]); map.addLayers([bio_utfgrid,world_utfgrid]);
var callback = function(dataLookup) { var callback = function(infoLookup) {
var msg = ""; var msg = "";
if (dataLookup) { if (infoLookup) {
var layer, data; var layer, info;
for (var idx in dataLookup) { for (var idx in infoLookup) {
layer = map.layers[idx]; layer = map.layers[idx];
data = dataLookup[idx]; info = infoLookup[idx];
if (data) { if (info && info.data) {
msg += "<strong>" + layer.name + "</strong><br>"; msg += "<strong>" + layer.name + "</strong><br>";
for (var key in data) { msg += "feature id: " + info.id + "<br>";
msg += key + ": " + data[key] + "<br>"; for (var key in info.data) {
msg += key + ": " + info.data[key] + "<br>";
} }
} }
} }
+6 -6
View File
@@ -33,7 +33,7 @@
* var control = new OpenLayers.Control.UTFGrid({ * var control = new OpenLayers.Control.UTFGrid({
* layers: [world_utfgrid], * layers: [world_utfgrid],
* handlerMode: 'move', * handlerMode: 'move',
* callback: function(dataLookup) { * callback: function(infoLookup) {
* // do something with returned data * // do something with returned data
* *
* } * }
@@ -175,14 +175,14 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
var layers = this.findLayers(); var layers = this.findLayers();
if (layers.length > 0) { if (layers.length > 0) {
var dataLookup = {}; var infoLookup = {};
var layer, idx; var layer, idx;
for (var i=0, len=layers.length; i<len; i++) { for (var i=0, len=layers.length; i<len; i++) {
layer = layers[i]; layer = layers[i];
idx = this.map.layers.indexOf(layer); idx = this.map.layers.indexOf(layer);
dataLookup[idx] = layer.getFeatureData(lonLat); infoLookup[idx] = layer.getFeatureInfo(lonLat);
} }
this.callback(dataLookup); // perhaps pass tile, lonLat? this.callback(infoLookup); // perhaps pass tile, lonLat?
} }
}, },
@@ -192,12 +192,12 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
* includes data in one of the configured UTFGrid layers. * includes data in one of the configured UTFGrid layers.
* *
* Parameters: * Parameters:
* dataLookup - {Object} Keys of this object are layer indexes and can be * 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 * used to resolve a layer in the map.layers array. The structure of
* the property values depend on the data included in the underlying * the property values depend on the data included in the underlying
* UTFGrid and may be any valid JSON type. * UTFGrid and may be any valid JSON type.
*/ */
callback: function(dataLookup) { callback: function(infoLookup) {
// to be provided in the constructor // to be provided in the constructor
}, },
+16 -11
View File
@@ -237,22 +237,26 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
}, },
/** /**
* APIProperty: getFeatureData * APIProperty: getFeatureInfo
* Get feature data from UTFGrid associated with a map location. * 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: * Parameters:
* location - {<OpenLayers.LonLat>} map location * location - {<OpenLayers.LonLat>} map location
* *
* Returns: * Returns:
* {Object} The UTFGrid data corresponding to the given map location. * {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.
*/ */
getFeatureData: function(location) { getFeatureInfo: function(location) {
var data; var info = null;
var info = this.getTileInfo(location); var tileInfo = this.getTileInfo(location);
if (info.tile) { if (tileInfo.tile) {
data = info.tile.getFeatureData(info.i, info.j); info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);
} }
return data; return info;
}, },
/** /**
@@ -263,10 +267,11 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
* location - {<OpenLayers.LonLat>} map location * location - {<OpenLayers.LonLat>} map location
* *
* Returns: * Returns:
* {Object} The feature identifier corresponding to the given map location. * {String} The feature identifier corresponding to the given map location.
* Returns null if the location doesn't hit a feature.
*/ */
getFeatureId: function(location) { getFeatureId: function(location) {
var id; var id = null;
var info = this.getTileInfo(location); var info = this.getTileInfo(location);
if (info.tile) { if (info.tile) {
id = info.tile.getFeatureId(info.i, info.j); id = info.tile.getFeatureId(info.i, info.j);
+20 -9
View File
@@ -146,22 +146,29 @@ OpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {
}, },
/** /**
* Method: getFeatureData * Method: getFeatureInfo
* Get feature data associated with a pixel offset. * 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: * Parameters:
* i - {Number} X-axis pixel offset (from top left of tile) * i - {Number} X-axis pixel offset (from top left of tile)
* j - {Number} Y-axis pixel offset (from top left of tile) * j - {Number} Y-axis pixel offset (from top left of tile)
* *
* Returns: * Returns:
* {Object} The UTFGrid data corresponding to the given pixel offset. * {Object} Object with feature id and data properties corresponding to the
* given pixel offset.
*/ */
getFeatureData: function(i, j) { getFeatureInfo: function(i, j) {
var data; var info = null;
if (this.json) { if (this.json) {
data = this.json.data[this.getFeatureId(i, j)]; var id = this.getFeatureId(i, j);
if (id !== null) {
info = {id: id, data: this.json.data[id]};
}
} }
return data; return info;
}, },
/** /**
@@ -174,16 +181,20 @@ OpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {
* *
* Returns: * Returns:
* {Object} The feature identifier corresponding to the given pixel offset. * {Object} The feature identifier corresponding to the given pixel offset.
* Returns null if pixel doesn't correspond to a feature.
*/ */
getFeatureId: function(i, j) { getFeatureId: function(i, j) {
var id; var id = null;
if (this.json) { if (this.json) {
var resolution = this.utfgridResolution; var resolution = this.utfgridResolution;
var row = Math.floor(j / resolution); var row = Math.floor(j / resolution);
var col = Math.floor(i / resolution); var col = Math.floor(i / resolution);
var charCode = this.json.grid[row].charCodeAt(col); var charCode = this.json.grid[row].charCodeAt(col);
var index = this.indexFromCharCode(charCode); var index = this.indexFromCharCode(charCode);
id = this.json.keys[index]; var keys = this.json.keys;
if (!isNaN(index) && (index in keys)) {
id = keys[index];
}
} }
return id; return id;
}, },
+11 -8
View File
@@ -171,27 +171,30 @@
t.eq(id, "238", "feature 238 at 16, 60"); t.eq(id, "238", "feature 238 at 16, 60");
t.eq(tile.getFeatureId(18, 63), id, "same feature at 18, 63"); t.eq(tile.getFeatureId(18, 63), id, "same feature at 18, 63");
t.eq(tile.getFeatureId(300, 10), undefined, "undefined id outside tile"); t.eq(tile.getFeatureId(300, 10), null, "null id outside tile");
tearDown(); tearDown();
}); });
} }
function test_getFeatureData(t) { function test_getFeatureInfo(t) {
t.plan(3); t.plan(3);
setUp(); setUp();
var tile = layer.grid[1][1]; var tile = layer.grid[1][1];
t.delay_call(0.5, function() { t.delay_call(0.5, function() {
var data = tile.getFeatureData(16, 60); var info = tile.getFeatureInfo(16, 60);
var exp = { var exp = {
NAME: "Svalbard", id: "238",
POP2005: 0 data: {
NAME: "Svalbard",
POP2005: 0
}
}; };
t.eq(data, exp, "feature data at 16, 60"); t.eq(info, exp, "feature info at 16, 60");
t.eq(tile.getFeatureData(17, 62), exp, "same feature at 17, 62"); t.eq(tile.getFeatureInfo(17, 62), exp, "same feature at 17, 62");
t.eq(tile.getFeatureData(300, 10), undefined, "undefined data outside tile"); t.eq(tile.getFeatureInfo(300, 10), null, "undefined outside tile");
tearDown(); tearDown();
}); });