Merge remote-tracking branch 'tschaub/utfgrid' into utfgrid
This commit is contained in:
@@ -1,23 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> OpenLayers UTFGrid Demo </title>
|
||||
<script src='./OpenLayers.js' type='text/javascript'></script>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers UTFGrid Demo</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<style>
|
||||
#themap { width:512px; height:380px; border:1px black solid; }
|
||||
#attrsdiv { width: 300px; height: 100px; float:right; border: 1px grey dashed;}
|
||||
#attrsdiv {
|
||||
float: right;
|
||||
}
|
||||
#controlToggle li { list-style: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1> OpenLayers UTFGrid Demo </h1>
|
||||
<h1 id="title">OpenLayers UTFGrid Demo</h1>
|
||||
|
||||
<div id="top">
|
||||
<div>
|
||||
<p>
|
||||
This page demostrates the use of the OpenLayers <a href="http://mapbox.com/mbtiles-spec/utfgrid/">UTFGrid</a> Controls. When the selected event is triggered, the underlying feature attributes are shown on the right.
|
||||
</p>
|
||||
<div>
|
||||
<div id="shortdesc">
|
||||
This page demonstrates the use of the OpenLayers UTFGrid Controls.
|
||||
</div>
|
||||
<div id="selector">
|
||||
<div id="attrsdiv"></div>
|
||||
<div id="themap" class="smallmap"></div>
|
||||
<p>
|
||||
When the selected event is triggered, the underlying feature attributes are shown below.
|
||||
</p>
|
||||
<ul id="controlToggle">
|
||||
<li>
|
||||
<input type="radio" name="type" value="move" id="moveHandler"
|
||||
@@ -40,12 +48,8 @@
|
||||
<label for="clickHandlerCustom">Click with custom callback</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="attrsdiv"></div>
|
||||
<div id="themap">
|
||||
</div>
|
||||
<div>
|
||||
<div id="docs">
|
||||
<p><a href="http://mapbox.com/mbtiles-spec/utfgrid/">UTFGrids</a> can be used to
|
||||
output highly optimized feature "hit grids". The UTFGrid encoding scheme encodes
|
||||
interactivity data for a tile in a space efficient manner. It is designed to be
|
||||
@@ -63,48 +67,43 @@
|
||||
/*
|
||||
* Map
|
||||
*/
|
||||
var map = new OpenLayers.Map('themap', {
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
units: "m",
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
|
||||
var map = new OpenLayers.Map({
|
||||
div: "themap",
|
||||
projection: "EPSG:900913",
|
||||
controls: [] // No default controls; no pan zoom for demo
|
||||
});
|
||||
|
||||
/*
|
||||
* Controls
|
||||
*/
|
||||
var callback = function(attributes) {
|
||||
if (attributes) {
|
||||
var msg = "<strong>In 2005, " + attributes.NAME
|
||||
msg += " had a population of " + attributes.POP2005 + " people.</strong>";
|
||||
var element = OpenLayers.Util.getElement('attrsdiv');
|
||||
element.innerHTML = msg;
|
||||
return true;
|
||||
} else {
|
||||
this.element.innerHTML = '';
|
||||
return false;
|
||||
var callback = function(dataLookup) {
|
||||
var msg = "";
|
||||
if (dataLookup) {
|
||||
var data;
|
||||
for (var idx in dataLookup) {
|
||||
// idx can be used to retrieve layer from map.layers[idx]
|
||||
data = dataLookup[idx];
|
||||
msg += "<strong>In 2005, " + data.NAME + " had a population of " +
|
||||
data.POP2005 + " people.</strong> ";
|
||||
}
|
||||
}
|
||||
}
|
||||
document.getElementById("attrsdiv").innerHTML = msg;
|
||||
};
|
||||
|
||||
controls = {
|
||||
'move': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'handlerMode': 'move'
|
||||
var controls = {
|
||||
move: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
handlerMode: 'move'
|
||||
}),
|
||||
'hover': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'handlerMode': 'hover'
|
||||
hover: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
handlerMode: 'hover'
|
||||
}),
|
||||
'click': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'handlerMode': 'click'
|
||||
}),
|
||||
'click_callback': new OpenLayers.Control.UTFGrid({
|
||||
'handlerMode': 'click',
|
||||
'callback': callback
|
||||
}),
|
||||
}
|
||||
click: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
handlerMode: 'click'
|
||||
})
|
||||
};
|
||||
var control;
|
||||
for(var key in controls) {
|
||||
control = controls[key];
|
||||
@@ -126,11 +125,8 @@
|
||||
* Layers
|
||||
*/
|
||||
|
||||
var ol_wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||
"http://vmap0.tiles.osgeo.org/wms/vmap0",
|
||||
{layers: 'basic'}
|
||||
);
|
||||
map.addLayer(ol_wms);
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
map.addLayer(osm);
|
||||
|
||||
var grid_layer = new OpenLayers.Layer.UTFGrid(
|
||||
'Invisible UTFGrid Layer',
|
||||
|
||||
@@ -1,85 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> OpenLayers Multiple UTFGrid Demo </title>
|
||||
<script src='./OpenLayers.js' type='text/javascript'></script>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>OpenLayers Multiple UTFGrid Demo</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<style>
|
||||
#themap { width:512px; height:380px; border:1px black solid; }
|
||||
#attrsdiv { width: 300px; height: 100px; float:right; border: 1px grey dashed;}
|
||||
#controlToggle li { list-style: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1> OpenLayers Multiple UTFGrid Demo </h1>
|
||||
<h1 id="title">OpenLayers Multiple UTFGrid Demo</h1>
|
||||
|
||||
<div id="top">
|
||||
<div>
|
||||
<p>
|
||||
This page demostrates the use of the OpenLayers <a href="http://mapbox.com/mbtiles-spec/utfgrid/">UTFGrid</a> Controls with <em>more than one UTFGrid Layer</em>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="selector">
|
||||
<ul id="controlToggle">
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_pop" id="moveHandler"
|
||||
onclick="toggleControl(this);" checked="checked" />
|
||||
<label for="moveHandler">Move (population)</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_bio" id="hoverHandler"
|
||||
onclick="toggleControl(this);" />
|
||||
<label for="hoverHandler">Move (bioregion)</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_both" id="clickHandler"
|
||||
onclick="toggleControl(this);" />
|
||||
<label for="clickHandler">Move (both)</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="shortdesc">
|
||||
This page demonstrates the use of the OpenLayers UTFGrid Controls with more than one UTFGrid Layer.
|
||||
</div>
|
||||
<div id="themap" class="smallmap"></div>
|
||||
<ul id="controlToggle">
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_pop" id="moveHandler"
|
||||
onclick="toggleControl(this);" checked="checked" />
|
||||
<label for="moveHandler">Move (population)</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_bio" id="hoverHandler"
|
||||
onclick="toggleControl(this);" />
|
||||
<label for="hoverHandler">Move (bioregion)</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="type" value="move_both" id="clickHandler"
|
||||
onclick="toggleControl(this);" />
|
||||
<label for="clickHandler">Move (both)</label>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="attrsdiv"></div>
|
||||
<div id="themap"> </div>
|
||||
<script>
|
||||
/*
|
||||
* Map
|
||||
*/
|
||||
var map = new OpenLayers.Map('themap', {
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
units: "m",
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
|
||||
var map = new OpenLayers.Map({
|
||||
div: "themap",
|
||||
projection: "EPSG:900913",
|
||||
controls: []
|
||||
});
|
||||
|
||||
var world_utfgrid = new OpenLayers.Layer.UTFGrid(
|
||||
'Invisible UTFGrid Layer',
|
||||
//"http://tiles/world_utfgrid/${z}/${x}/${y}.json"
|
||||
"World Population",
|
||||
"./utfgrid/world_utfgrid/${z}/${x}/${y}.json"
|
||||
);
|
||||
var bio_utfgrid = new OpenLayers.Layer.UTFGrid(
|
||||
'Invisible UTFGrid Layer of World Bioregions',
|
||||
//"http://tiles/bailey_utfgrid/${z}/${x}/${y}.json"
|
||||
"World Bioregions",
|
||||
"./utfgrid/bio_utfgrid/${z}/${x}/${y}.json"
|
||||
);
|
||||
map.addLayers([bio_utfgrid,world_utfgrid]);
|
||||
|
||||
controls = {
|
||||
'move_pop': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'layers': [world_utfgrid],
|
||||
'handlerMode': 'move'
|
||||
var callback = function(dataLookup) {
|
||||
var msg = "";
|
||||
if (dataLookup) {
|
||||
var layer, data;
|
||||
for (var idx in dataLookup) {
|
||||
layer = map.layers[idx];
|
||||
data = dataLookup[idx];
|
||||
if (data) {
|
||||
msg += "<strong>" + layer.name + "</strong><br>";
|
||||
for (var key in data) {
|
||||
msg += key + ": " + data[key] + "<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
document.getElementById("attrsdiv").innerHTML = msg;
|
||||
};
|
||||
var controls = {
|
||||
move_pop: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
layers: [world_utfgrid],
|
||||
handlerMode: 'move'
|
||||
}),
|
||||
'move_bio': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'layers': [bio_utfgrid],
|
||||
'handlerMode': 'move'
|
||||
move_bio: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
layers: [bio_utfgrid],
|
||||
handlerMode: 'move'
|
||||
}),
|
||||
'move_both': new OpenLayers.Control.UTFGrid({
|
||||
'div': 'attrsdiv',
|
||||
'layers': null, // same as [bio_utfgrid,world_utfgrid]
|
||||
'handlerMode': 'move'
|
||||
move_both: new OpenLayers.Control.UTFGrid({
|
||||
callback: callback,
|
||||
layers: null, // same as [bio_utfgrid,world_utfgrid]
|
||||
handlerMode: 'move'
|
||||
})
|
||||
}
|
||||
};
|
||||
var control;
|
||||
for(var key in controls) {
|
||||
control = controls[key];
|
||||
@@ -98,11 +108,8 @@
|
||||
}
|
||||
|
||||
// Visible Layers
|
||||
var ol_wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||
"http://vmap0.tiles.osgeo.org/wms/vmap0",
|
||||
{layers: 'basic'}
|
||||
);
|
||||
map.addLayer(ol_wms);
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
map.addLayer(osm);
|
||||
map.zoomTo(1);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -124,6 +124,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 +147,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 +205,7 @@
|
||||
"OpenLayers/Control/WMTSGetFeatureInfo.js",
|
||||
"OpenLayers/Control/Graticule.js",
|
||||
"OpenLayers/Control/TransformFeature.js",
|
||||
"OpenLayers/Control/UTFGrid.js",
|
||||
"OpenLayers/Control/SLDSelect.js",
|
||||
"OpenLayers/Geometry.js",
|
||||
"OpenLayers/Geometry/Collection.js",
|
||||
|
||||
@@ -31,9 +31,12 @@
|
||||
* map.addLayer(world_utfgrid);
|
||||
*
|
||||
* var control = new OpenLayers.Control.UTFGrid({
|
||||
* 'div': 'attrsdiv',
|
||||
* 'layers': [world_utfgrid],
|
||||
* 'handlerMode': 'move'
|
||||
* layers: [world_utfgrid],
|
||||
* handlerMode: 'move',
|
||||
* callback: function(dataLookup) {
|
||||
* // do something with returned data
|
||||
*
|
||||
* }
|
||||
* })
|
||||
* (end code)
|
||||
*
|
||||
@@ -58,18 +61,6 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
layers: null,
|
||||
|
||||
/**
|
||||
* Property: element
|
||||
* {DOMElement}
|
||||
*/
|
||||
element: null,
|
||||
|
||||
/**
|
||||
* Property: debugElement
|
||||
* {DOMElement}
|
||||
*/
|
||||
debugElement: null,
|
||||
|
||||
/* Property: defaultHandlerOptions
|
||||
* The default opts passed to the handler constructors
|
||||
*/
|
||||
@@ -153,9 +144,6 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
|
||||
options = options || {};
|
||||
options.handlerOptions = options.handlerOptions || this.defaultHandlerOptions;
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
if (options.div) {
|
||||
this.element = OpenLayers.Util.getElement(options.div);
|
||||
}
|
||||
this.resetHandler();
|
||||
},
|
||||
|
||||
@@ -186,110 +174,39 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
|
||||
var layers = this.findLayers();
|
||||
var globalAttrs = {};
|
||||
if (layers.length > 0) {
|
||||
var layer;
|
||||
var dataLookup = {};
|
||||
var layer, idx;
|
||||
for (var i=0, len=layers.length; i<len; i++) {
|
||||
layer = layers[i];
|
||||
var info = layer.getTileInfo( lonLat );
|
||||
this.writeDebugInfo(info);
|
||||
var tile = info.tile;
|
||||
var localAttrs = null;
|
||||
var resolution = layer.utfgridResolution || 4;
|
||||
if (tile !== null && typeof(tile) !== 'undefined') {
|
||||
var data = tile.json
|
||||
if (data !== null) {
|
||||
var code = this.resolveCode(data.grid[
|
||||
Math.floor((info.j) / resolution)
|
||||
].charCodeAt(
|
||||
Math.floor((info.i) / resolution)
|
||||
));
|
||||
localAttrs = data.data[data.keys[code]];
|
||||
for (var property in localAttrs) {
|
||||
// If attribute names collide, last one takes it
|
||||
globalAttrs[property] = localAttrs[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
idx = this.map.layers.indexOf(layer);
|
||||
dataLookup[idx] = layer.getData(lonLat);
|
||||
}
|
||||
this.callback(globalAttrs); // perhaps pass tile, lonLat?
|
||||
this.callback(dataLookup); // perhaps pass tile, lonLat?
|
||||
}
|
||||
},
|
||||
|
||||
/** Method: writeDebugInfo
|
||||
* Writes out debug info on event
|
||||
* Only fired off if this.debugElement is set
|
||||
*
|
||||
*/
|
||||
writeDebugInfo: function(info) {
|
||||
var debug = "<ul>";
|
||||
debug += "<li>i :" + info.i + "</li>";
|
||||
debug += "<li>j :" + info.j + "</li>";
|
||||
debug += "<li>globalrow :" + info.globalRow + "</li>";
|
||||
debug += "<li>globalcol :" + info.globalCol + "</li>";
|
||||
debug += "<li>gridrow :" + info.gridRow + "</li>";
|
||||
debug += "<li>gridcol :" + info.gridCol + "</li>";
|
||||
debug += "</ul>";
|
||||
if (this.debugElement) {
|
||||
this.debugElement.innerHTML = debug;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: callback
|
||||
* Takes the attrs and does somethings with them
|
||||
* The default behavior is to make a simple table
|
||||
* and write to a div (defined by this.element)
|
||||
* Function to be called when a mouse event corresponds with a location that
|
||||
* includes data in one of the configured UTFGrid layers.
|
||||
*
|
||||
* Parameters:
|
||||
* attrs - {Object}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} - was the element updated?
|
||||
* dataLookup - {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(attrs) {
|
||||
if (attrs !== null && typeof(attrs) !== 'undefined') {
|
||||
val = "<table>";
|
||||
for(var index in attrs) {
|
||||
val += "<tr><th>" + index + "</th><td>" + attrs[index] + "</td></tr>";
|
||||
}
|
||||
val += "</table>";
|
||||
this.element.innerHTML = val;
|
||||
return true;
|
||||
} else {
|
||||
this.element.innerHTML = '';
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: resolveCode
|
||||
* Resolve the UTF-8 encoding stored in grids to simple
|
||||
* number values.
|
||||
* See the [utfgrid section of the mbtiles spec](https://github.com/mapbox/mbtiles-spec/blob/master/1.1/utfgrid.md)
|
||||
* 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;
|
||||
callback: function(dataLookup) {
|
||||
// to be provided in the constructor
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: reset
|
||||
* Resets the element
|
||||
* Calls the callback with null.
|
||||
*/
|
||||
reset: function(evt) {
|
||||
this.callback(null);
|
||||
if (this.element)
|
||||
this.element.innerHTML = '';
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -180,7 +180,7 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
utfgridResolution: 4,
|
||||
|
||||
/**
|
||||
* APIMethod: getTileInfo
|
||||
* Method: getTileInfo
|
||||
* Get tile information for a given location at the current map resolution.
|
||||
*
|
||||
* Parameters:
|
||||
@@ -246,6 +246,53 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
j: Math.floor((fy - globalRow) * this.tileSize.h)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* APIProperty: getData
|
||||
* Get tile data associated with a map location.
|
||||
*
|
||||
* Parameters:
|
||||
* location - {<OpenLayers.LonLat>} map location
|
||||
*
|
||||
* Returns:
|
||||
* {Object} The UTFGrid data corresponding to the given map location.
|
||||
*/
|
||||
getData: function(location) {
|
||||
var info = this.getTileInfo(location);
|
||||
var tile = info.tile;
|
||||
var data;
|
||||
if (tile) {
|
||||
var resolution = this.utfgridResolution;
|
||||
var json = tile.json
|
||||
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;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIProperty: tileClass
|
||||
|
||||
Reference in New Issue
Block a user