Previously examples would either use the now deprecated `window.$` or the non-API-method `OpenLayers.Util.getElement`. This was well caught by @probins and @elemoine.
239 lines
9.3 KiB
HTML
239 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<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 Cluster Strategy Example</title>
|
|
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
|
<link rel="stylesheet" href="style.css" type="text/css">
|
|
<style type="text/css">
|
|
#photos {
|
|
height: 100px;
|
|
width: 512px;
|
|
position: relative;
|
|
white-space: nowrap;
|
|
}
|
|
.shift {
|
|
height: 25px;
|
|
line-height: 25px;
|
|
background-color: #fefefe;
|
|
text-align: center;
|
|
position: absolute;
|
|
bottom: 10px;
|
|
font-size: 8px;
|
|
font-weight: bold;
|
|
color: #696969;
|
|
width: 25px;
|
|
}
|
|
#scroll-start {
|
|
left: 0px;
|
|
}
|
|
#scroll-end {
|
|
right: 0px;
|
|
}
|
|
#scroll {
|
|
left: 30px;
|
|
width: 452px;
|
|
height: 100px;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
bottom: 0px;
|
|
}
|
|
#photos ul {
|
|
position: absolute;
|
|
bottom: 0px;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
#photos ul.start {
|
|
left: 0px;
|
|
}
|
|
#photos ul.end {
|
|
right: 80px;
|
|
}
|
|
#photos ul li {
|
|
padding: 10px;
|
|
margin: 0;
|
|
list-style: none;
|
|
display: inline;
|
|
}
|
|
img.thumb {
|
|
height: 30px;
|
|
}
|
|
img.big {
|
|
height: 90px;
|
|
}
|
|
</style>
|
|
<script src="../lib/OpenLayers.js"></script>
|
|
<script src="Jugl.js"></script>
|
|
<script src="animator.js"></script>
|
|
<script type="text/javascript">
|
|
|
|
var map, template;
|
|
|
|
/**
|
|
* A specific format for parsing Flickr API JSON responses.
|
|
*/
|
|
OpenLayers.Format.Flickr = OpenLayers.Class(OpenLayers.Format, {
|
|
read: function(obj) {
|
|
if(obj.stat === 'fail') {
|
|
throw new Error(
|
|
['Flickr failure response (',
|
|
obj.code,
|
|
'): ',
|
|
obj.message].join(''));
|
|
}
|
|
if(!obj || !obj.photos ||
|
|
!OpenLayers.Util.isArray(obj.photos.photo)) {
|
|
throw new Error(
|
|
'Unexpected Flickr response');
|
|
}
|
|
var photos = obj.photos.photo, photo,
|
|
x, y, point,
|
|
feature, features = [];
|
|
for(var i=0,l=photos.length; i<l; i++) {
|
|
photo = photos[i];
|
|
x = photo.longitude;
|
|
y = photo.latitude;
|
|
point = new OpenLayers.Geometry.Point(x, y);
|
|
feature = new OpenLayers.Feature.Vector(point, {
|
|
title: photo.title,
|
|
img_url: photo.url_s
|
|
});
|
|
features.push(feature);
|
|
}
|
|
return features;
|
|
}
|
|
});
|
|
|
|
function init() {
|
|
map = new OpenLayers.Map('map');
|
|
var base = new OpenLayers.Layer.OSM();
|
|
|
|
var style = new OpenLayers.Style({
|
|
pointRadius: "${radius}",
|
|
fillColor: "#ffcc66",
|
|
fillOpacity: 0.8,
|
|
strokeColor: "#cc6633",
|
|
strokeWidth: 2,
|
|
strokeOpacity: 0.8
|
|
}, {
|
|
context: {
|
|
radius: function(feature) {
|
|
return Math.min(feature.attributes.count, 7) + 3;
|
|
}
|
|
}
|
|
});
|
|
|
|
var photos = new OpenLayers.Layer.Vector("Photos", {
|
|
projection: "EPSG:4326",
|
|
strategies: [
|
|
new OpenLayers.Strategy.Fixed(),
|
|
new OpenLayers.Strategy.Cluster()
|
|
],
|
|
protocol: new OpenLayers.Protocol.Script({
|
|
url: "http://api.flickr.com/services/rest",
|
|
params: {
|
|
api_key: 'b5e8c0e287e678671c3d8b2c0f3ced85',
|
|
format: 'json',
|
|
method: 'flickr.photos.search',
|
|
extras: 'geo,url_s',
|
|
per_page: 150,
|
|
page: 1,
|
|
bbox: [-180, -90, 180, 90]
|
|
},
|
|
callbackKey: 'jsoncallback',
|
|
format: new OpenLayers.Format.Flickr()
|
|
}),
|
|
styleMap: new OpenLayers.StyleMap({
|
|
"default": style,
|
|
"select": {
|
|
fillColor: "#8aeeef",
|
|
strokeColor: "#32a8a9"
|
|
}
|
|
})
|
|
});
|
|
|
|
var select = new OpenLayers.Control.SelectFeature(
|
|
photos, {hover: true}
|
|
);
|
|
map.addControl(select);
|
|
select.activate();
|
|
photos.events.on({"featureselected": display});
|
|
|
|
map.addLayers([base, photos]);
|
|
map.setCenter(new OpenLayers.LonLat(0, 0), 1);
|
|
|
|
// template setup
|
|
template = new jugl.Template("template");
|
|
|
|
}
|
|
|
|
function display(event) {
|
|
// clear previous photo list and create new one
|
|
document.getElementById("photos").innerHTML = "";
|
|
var node = template.process({
|
|
context: {features: event.feature.cluster},
|
|
clone: true,
|
|
parent: document.getElementById("photos")
|
|
});
|
|
// set up forward/rewind
|
|
var forward = Animator.apply(document.getElementById("list"), ["start", "end"], {duration: 1500});
|
|
document.getElementById("scroll-end").onmouseover = function() {forward.seekTo(1)};
|
|
document.getElementById("scroll-end").onmouseout = function() {forward.seekTo(forward.state)};
|
|
document.getElementById("scroll-start").onmouseover = function() {forward.seekTo(0)};
|
|
document.getElementById("scroll-start").onmouseout = function() {forward.seekTo(forward.state)};
|
|
// set up photo zoom
|
|
for(var i=0; i<event.feature.cluster.length; ++i) {
|
|
listen(document.getElementById("link-" + i), Animator.apply(document.getElementById("photo-" + i), ["thumb", "big"]));
|
|
}
|
|
}
|
|
|
|
function listen(el, anim) {
|
|
el.onmouseover = function() {anim.seekTo(1)};
|
|
el.onmouseout = function() {anim.seekTo(0)};
|
|
}
|
|
|
|
</script>
|
|
</head>
|
|
<body onload="init()">
|
|
<h1 id="title">Cluster Strategy Example</h1>
|
|
<div id="tags">
|
|
vector, feature, stylemap, cluster, strategy, flickr, script
|
|
</div>
|
|
<p id="shortdesc">
|
|
Uses a cluster strategy to render points representing clusters of features.
|
|
</p>
|
|
<div id="map" class="smallmap"></div>
|
|
<div id="docs">
|
|
<p>The Cluster strategy lets you display points representing clusters
|
|
of features within some pixel distance.</p>
|
|
<p>This particular example uses the <a
|
|
href="http://www.flickr.com/services/api/">Flickr API.</a></p>
|
|
</div>
|
|
<div id="photos"></div>
|
|
<p>Hover over a cluster on the map to see the photos it includes.</p>
|
|
<div style="display: none;">
|
|
<div id="template">
|
|
<div class="shift" id="scroll-start"><<</div>
|
|
<div id="scroll">
|
|
<ul id="list" class="start">
|
|
<li jugl:repeat="feature features">
|
|
<a jugl:attributes="href feature.attributes.img_url;
|
|
id 'link-' + repeat.feature.index"
|
|
target="_blank">
|
|
<img jugl:attributes="src feature.attributes.img_url;
|
|
title feature.attributes.title;
|
|
id 'photo-' + repeat.feature.index"
|
|
class="thumb" />
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="shift" id="scroll-end">>></div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|