Layer and tile API update.

The tile now has responsibility for resolving feature ids and fetching feature data given x, y pixel offsets with getFeatureId and getFeatureData methods.  The layer has corresponding getFeatureId and getFeatureData methods that take a map location, lookup the appropriate tile, and delegate to the tile for the rest of the work.
This commit is contained in:
Tim Schaub
2012-02-26 21:05:12 -07:00
parent fc03f57591
commit 551c582ab1
4 changed files with 134 additions and 31 deletions

View File

@@ -180,7 +180,7 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
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.getData(lonLat); dataLookup[idx] = layer.getFeatureData(lonLat);
} }
this.callback(dataLookup); // perhaps pass tile, lonLat? this.callback(dataLookup); // perhaps pass tile, lonLat?
} }

View File

@@ -107,6 +107,9 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
*/ */
initialize: function(name, url, options) { initialize: function(name, url, options) {
OpenLayers.Layer.Grid.prototype.initialize.apply(this, [name, url, {}, options]); OpenLayers.Layer.Grid.prototype.initialize.apply(this, [name, url, {}, options]);
this.tileOptions = OpenLayers.Util.extend({
utfgridResolution: this.utfgridResolution
}, this.tileOptions);
}, },
/** /**
@@ -158,10 +161,12 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
/** /**
* APIProperty: utfgridResolution * APIProperty: utfgridResolution
* {Number} Number of pixels per grid "cell" * {Number}
* Defaults to 4 * Ratio of the pixel width to the width of a UTFGrid data point. If an
* entry in the grid represents a 2x2 block of pixels, the
* utfgridResolution would be 2. Default is 4 (specified in
* <OpenLayers.Tile.UTFGrid>).
*/ */
utfgridResolution: 4,
/** /**
* Method: getTileInfo * Method: getTileInfo
@@ -232,8 +237,8 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
}, },
/** /**
* APIProperty: getData * APIProperty: getFeatureData
* Get tile data associated with a map location. * Get feature data from UTFGrid associated with a map location.
* *
* Parameters: * Parameters:
* location - {<OpenLayers.LonLat>} map location * location - {<OpenLayers.LonLat>} map location
@@ -241,41 +246,32 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
* Returns: * Returns:
* {Object} The UTFGrid data corresponding to the given map location. * {Object} The UTFGrid data corresponding to the given map location.
*/ */
getData: function(location) { getFeatureData: function(location) {
var info = this.getTileInfo(location);
var tile = info.tile;
var data; var data;
if (tile) { var info = this.getTileInfo(location);
var resolution = this.utfgridResolution; if (info.tile) {
var json = tile.json data = info.tile.getFeatureData(info.i, info.j);
if (json) {
var code = this.resolveCode(json.grid[
Math.floor((info.j) / resolution)
].charCodeAt(
Math.floor((info.i) / resolution)
));
data = json.data[json.keys[code]];
}
} }
return data; return data;
}, },
/** /**
* Method: resolveCode * APIMethod: getFeatureId
* Resolve the UTF-8 encoding stored in grids to simple number values. * Get the identifier for the feature associated with a map location.
* See the UTFGrid spec for details.
* *
* Parameters: * Parameters:
* key - {Integer} * location - {<OpenLayers.LonLat>} map location
* *
* Returns: * Returns:
* {Integer} Adjusted key for non-escaped chars * {Object} The feature identifier corresponding to the given map location.
*/ */
resolveCode: function(key) { getFeatureId: function(location) {
if (key >= 93) key--; var id;
if (key >= 35) key--; var info = this.getTileInfo(location);
key -= 32; if (info.tile) {
return key; id = info.tile.getFeatureId(info.i, info.j);
}
return id;
}, },
/** /**

View File

@@ -32,6 +32,15 @@ OpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {
*/ */
url: null, 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 2x2 block of pixels, the
* utfgridResolution would be 2. Default is 4.
*/
utfgridResolution: 4,
/** /**
* Property: json * Property: json
* {Object} * {Object}
@@ -135,6 +144,68 @@ OpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {
} }
this.isLoading = false; this.isLoading = false;
}, },
/**
* Method: getFeatureData
* Get feature data 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 UTFGrid data corresponding to the given pixel offset.
*/
getFeatureData: function(i, j) {
var data;
if (this.json) {
data = this.json.data[this.getFeatureId(i, j)];
}
return data;
},
/**
* 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.
*/
getFeatureId: function(i, j) {
var id;
if (this.json) {
var resolution = this.utfgridResolution;
var code = this.resolveCode(this.json.grid[
Math.floor((j) / resolution)
].charCodeAt(
Math.floor((i) / resolution)
));
id = this.json.keys[code];
}
return id;
},
/**
* Method: resolveCode
* Resolve the UTF-8 encoding stored in grids to simple number values.
* See the UTFGrid spec for details.
*
* Parameters:
* key - {Integer}
*
* Returns:
* {Integer} Adjusted key for non-escaped chars
*/
resolveCode: function(key) {
if (key >= 93) key--;
if (key >= 35) key--;
key -= 32;
return key;
},
/** /**
* Method: parseData * Method: parseData

View File

@@ -15,7 +15,7 @@
projection: "EPSG:900913", projection: "EPSG:900913",
layers: [layer], layers: [layer],
center: [0, 0], center: [0, 0],
zoom: 0 zoom: 1
}); });
} }
@@ -158,6 +158,42 @@
}); });
} }
function test_getFeatureId(t) {
t.plan(3);
setUp();
var tile = layer.grid[1][1];
t.delay_call(0.5, function() {
var id = tile.getFeatureId(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(300, 10), undefined, "undefined id outside tile");
tearDown();
});
}
function test_getFeatureData(t) {
t.plan(3);
setUp();
var tile = layer.grid[1][1];
t.delay_call(0.5, function() {
var data = tile.getFeatureData(16, 60);
var exp = {
NAME: "Svalbard",
POP2005: 0
};
t.eq(data, exp, "feature data at 16, 60");
t.eq(tile.getFeatureData(17, 62), exp, "same feature at 17, 62");
t.eq(tile.getFeatureData(300, 10), undefined, "undefined data outside tile");
tearDown();
});
}
</script> </script>
</head> </head>