Compare commits
200 Commits
release-2.
...
release-2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6a717ccf5 | ||
|
|
48145f62be | ||
|
|
54fd1f561c | ||
|
|
acae8a8013 | ||
|
|
e32372e4b2 | ||
|
|
8b0d660b00 | ||
|
|
a167860818 | ||
|
|
257cc5576b | ||
|
|
fce15acc01 | ||
|
|
b7f0f27dcd | ||
|
|
cdb4b78136 | ||
|
|
5f59b8d72d | ||
|
|
7295ffc9d4 | ||
|
|
6e28a7cafd | ||
|
|
6f73f7059f | ||
|
|
ce0ba0b570 | ||
|
|
a6319b2974 | ||
|
|
19af3bb8e7 | ||
|
|
7832d8dda1 | ||
|
|
cb3fc7842b | ||
|
|
29dece02a5 | ||
|
|
6b9ee6bb5e | ||
|
|
ed2e943e52 | ||
|
|
c5f233ab8c | ||
|
|
bf778b21c1 | ||
|
|
69032c0534 | ||
|
|
3520c32140 | ||
|
|
da14451dbd | ||
|
|
a785dc1b1f | ||
|
|
23137091fc | ||
|
|
f37c9f8aef | ||
|
|
ee7065c9fa | ||
|
|
3f172c501d | ||
|
|
25fac24436 | ||
|
|
28558c171c | ||
|
|
2c7eade60c | ||
|
|
59953b8eb6 | ||
|
|
5750b5f6e0 | ||
|
|
050eda6670 | ||
|
|
7eaa37856c | ||
|
|
814810f6ed | ||
|
|
9450124359 | ||
|
|
9d4e91e717 | ||
|
|
0d6658f52d | ||
|
|
7993fc177b | ||
|
|
94c29f1d4d | ||
|
|
42fedc4d69 | ||
|
|
415fcbf9f9 | ||
|
|
fc9e67318e | ||
|
|
9ae54040db | ||
|
|
5a8775cd16 | ||
|
|
602cf46c10 | ||
|
|
68d82edc01 | ||
|
|
c68e234b71 | ||
|
|
a52cb98622 | ||
|
|
33410b0e76 | ||
|
|
e0c3db1227 | ||
|
|
c15a1a0779 | ||
|
|
d965d4a1a0 | ||
|
|
c77688a0be | ||
|
|
f0736370f3 | ||
|
|
ea1290f8d8 | ||
|
|
9d3c4ecb1c | ||
|
|
31afaf1fca | ||
|
|
f89fb1f226 | ||
|
|
0892e61bcb | ||
|
|
6c0952934f | ||
|
|
9fd7463680 | ||
|
|
f2247ae079 | ||
|
|
e5f0cfe906 | ||
|
|
a5f2ddcfa1 | ||
|
|
ca27481c66 | ||
|
|
7398216346 | ||
|
|
b2f810361d | ||
|
|
6adffe5be2 | ||
|
|
2a30747bd9 | ||
|
|
67b0c7180f | ||
|
|
ee00417729 | ||
|
|
d880d2d2b7 | ||
|
|
afa7b9c2bb | ||
|
|
3d0c264198 | ||
|
|
a5ca639c5b | ||
|
|
1d8773eab6 | ||
|
|
309d198e04 | ||
|
|
64842fd711 | ||
|
|
4d3a1eebf7 | ||
|
|
74a6f7e895 | ||
|
|
e32d63d7b2 | ||
|
|
b81b05a9b5 | ||
|
|
1c4afaaded | ||
|
|
8c2caf91d1 | ||
|
|
c4eaee5b5c | ||
|
|
b428e58090 | ||
|
|
28a7776d04 | ||
|
|
42b003669c | ||
|
|
509042078e | ||
|
|
d47944e4b7 | ||
|
|
de462bbe33 | ||
|
|
22aa4281fa | ||
|
|
ef9afd22cb | ||
|
|
ea183210fe | ||
|
|
72e2280c87 | ||
|
|
955ee1b1a9 | ||
|
|
a9a9b6387e | ||
|
|
1f601390dd | ||
|
|
40539ff6d3 | ||
|
|
c8cad59575 | ||
|
|
20a4025af0 | ||
|
|
e643531a0a | ||
|
|
0bc3e3c8b3 | ||
|
|
08f506176b | ||
|
|
2939bad8d0 | ||
|
|
0db8f59ae3 | ||
|
|
d895af91a5 | ||
|
|
98941c9952 | ||
|
|
0b9e0f50ab | ||
|
|
60e869e295 | ||
|
|
ae472b69a2 | ||
|
|
a8af8bceb5 | ||
|
|
5f6a2209ba | ||
|
|
fa1b7d2481 | ||
|
|
9a2363d06b | ||
|
|
e6b0ec0ee3 | ||
|
|
4bb7ccaf0a | ||
|
|
c4fbe1c0b3 | ||
|
|
cd94a7f17d | ||
|
|
cca1395fc6 | ||
|
|
eb4d5a2447 | ||
|
|
98c7687033 | ||
|
|
e6de46b9d3 | ||
|
|
f42bbd1dfc | ||
|
|
07ee9991be | ||
|
|
fba8a99b9b | ||
|
|
d1e24bdcc0 | ||
|
|
f7113df376 | ||
|
|
35b8350aec | ||
|
|
7177144816 | ||
|
|
71482163cf | ||
|
|
d0a2edbebd | ||
|
|
448373eb75 | ||
|
|
1b5add6efe | ||
|
|
2b8e293d83 | ||
|
|
fd6c16bb6c | ||
|
|
a69a0d2164 | ||
|
|
ae5d20b39f | ||
|
|
744ee039bd | ||
|
|
9bd7f02dbb | ||
|
|
88f2922f54 | ||
|
|
8b0712bb24 | ||
|
|
925b6fa206 | ||
|
|
f9391dd158 | ||
|
|
d57b603d07 | ||
|
|
5f96b1f914 | ||
|
|
e4085bbdc6 | ||
|
|
91bceb273b | ||
|
|
53b4356219 | ||
|
|
f52cd8972a | ||
|
|
ef87d15cfe | ||
|
|
0f648dedf4 | ||
|
|
1c9ba551a7 | ||
|
|
69b4a84381 | ||
|
|
c4e779b992 | ||
|
|
f95532ab6f | ||
|
|
194c6adc4d | ||
|
|
489d3c47b6 | ||
|
|
a6cd2d51d5 | ||
|
|
fd32f2e9dd | ||
|
|
a1f90c7ac8 | ||
|
|
449bc859c4 | ||
|
|
e67c9411b4 | ||
|
|
c19a190905 | ||
|
|
baa4e7469b | ||
|
|
2d8981aed5 | ||
|
|
7c40667ad7 | ||
|
|
3b0cd09aad | ||
|
|
57d3f26efc | ||
|
|
f38d5e0790 | ||
|
|
b0e726b988 | ||
|
|
f66607a6e8 | ||
|
|
c7e840876c | ||
|
|
4658d32b31 | ||
|
|
a5093a27fa | ||
|
|
701896e0c3 | ||
|
|
cbfcf40e6a | ||
|
|
dc4d5036e4 | ||
|
|
0bb5ab8191 | ||
|
|
69cb8fbb5e | ||
|
|
5a05b6c142 | ||
|
|
6341e8e2b9 | ||
|
|
aa246a1122 | ||
|
|
4f809a9714 | ||
|
|
ca3ecfc5b1 | ||
|
|
35aadaf0c8 | ||
|
|
674a414971 | ||
|
|
be986a0243 | ||
|
|
295363fe58 | ||
|
|
d5daa28fed | ||
|
|
69d8ac892f | ||
|
|
7b7c174cc7 | ||
|
|
da2dffce1a |
@@ -4,47 +4,51 @@ import sys
|
||||
sys.path.append("../tools")
|
||||
import mergejs
|
||||
|
||||
have_compressor = None
|
||||
try:
|
||||
import jsmin
|
||||
have_compressor = "jsmin"
|
||||
except ImportError:
|
||||
def build():
|
||||
have_compressor = None
|
||||
try:
|
||||
import minimize
|
||||
have_compressor = "minimize"
|
||||
except Exception, E:
|
||||
print E
|
||||
pass
|
||||
import jsmin
|
||||
have_compressor = "jsmin"
|
||||
except ImportError:
|
||||
try:
|
||||
import minimize
|
||||
have_compressor = "minimize"
|
||||
except Exception, E:
|
||||
print E
|
||||
pass
|
||||
|
||||
sourceDirectory = "../lib"
|
||||
configFilename = "full.cfg"
|
||||
outputFilename = "OpenLayers.js"
|
||||
sourceDirectory = "../lib"
|
||||
configFilename = "full.cfg"
|
||||
outputFilename = "OpenLayers.js"
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
configFilename = sys.argv[1]
|
||||
extension = configFilename[-4:]
|
||||
if len(sys.argv) > 1:
|
||||
configFilename = sys.argv[1]
|
||||
extension = configFilename[-4:]
|
||||
|
||||
if extension != ".cfg":
|
||||
configFilename = sys.argv[1] + ".cfg"
|
||||
if extension != ".cfg":
|
||||
configFilename = sys.argv[1] + ".cfg"
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
outputFilename = sys.argv[2]
|
||||
if len(sys.argv) > 2:
|
||||
outputFilename = sys.argv[2]
|
||||
|
||||
print "Merging libraries."
|
||||
merged = mergejs.run(sourceDirectory, None, configFilename)
|
||||
if have_compressor == "jsmin":
|
||||
print "Compressing using jsmin."
|
||||
minimized = jsmin.jsmin(merged)
|
||||
elif have_compressor == "minimize":
|
||||
print "Compressing using minimize."
|
||||
minimized = minimize.minimize(merged)
|
||||
else: # fallback
|
||||
print "Not compressing."
|
||||
minimized = merged
|
||||
print "Adding license file."
|
||||
minimized = file("license.txt").read() + minimized
|
||||
print "Merging libraries."
|
||||
merged = mergejs.run(sourceDirectory, None, configFilename)
|
||||
if have_compressor == "jsmin":
|
||||
print "Compressing using jsmin."
|
||||
minimized = jsmin.jsmin(merged)
|
||||
elif have_compressor == "minimize":
|
||||
print "Compressing using minimize."
|
||||
minimized = minimize.minimize(merged)
|
||||
else: # fallback
|
||||
print "Not compressing."
|
||||
minimized = merged
|
||||
print "Adding license file."
|
||||
minimized = file("license.txt").read() + minimized
|
||||
|
||||
print "Writing to %s." % outputFilename
|
||||
file(outputFilename, "w").write(minimized)
|
||||
print "Writing to %s." % outputFilename
|
||||
file(outputFilename, "w").write(minimized)
|
||||
|
||||
print "Done."
|
||||
print "Done."
|
||||
|
||||
if __name__ == '__main__':
|
||||
build()
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
OpenLayers.js -- OpenLayers Map Viewer Library
|
||||
|
||||
Copyright 2005-2008 MetaCarta, Inc., released under the Clear BSD license.
|
||||
Copyright 2005-2010 MetaCarta, Inc., released under the Clear BSD license.
|
||||
Please see http://svn.openlayers.org/trunk/openlayers/license.txt
|
||||
for the full text of the license.
|
||||
|
||||
|
||||
196
examples/SLDSelect.html
Normal file
@@ -0,0 +1,196 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>OpenLayers SLD based selection control</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">
|
||||
.olControlSLDSelectBoxActive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.olControlSLDSelectPolygonActive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.olControlSLDSelectLineActive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.olControlSLDSelectPointActive {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
var map, controls, layers;
|
||||
|
||||
function init(){
|
||||
OpenLayers.ProxyHost= "proxy.cgi?url=";
|
||||
map = new OpenLayers.Map('map', {allOverlays: true, controls: []});
|
||||
var url = "http://demo.opengeo.org/geoserver/wms";
|
||||
layers = {
|
||||
states: new OpenLayers.Layer.WMS("State boundary", url,
|
||||
{layers: 'topp:tasmania_state_boundaries', format: 'image/gif', transparent: 'TRUE'},
|
||||
{singleTile: true}),
|
||||
roads: new OpenLayers.Layer.WMS("Roads", url,
|
||||
{layers: 'topp:tasmania_roads', format: 'image/gif', transparent: 'TRUE'},
|
||||
{singleTile: true}),
|
||||
waterbodies: new OpenLayers.Layer.WMS("Water bodies", url,
|
||||
{layers: 'topp:tasmania_water_bodies', format: 'image/gif', transparent: 'TRUE'},
|
||||
{singleTile: true}),
|
||||
cities: new OpenLayers.Layer.WMS("Cities", url,
|
||||
{layers: 'topp:tasmania_cities', format: 'image/gif', transparent: 'TRUE'},
|
||||
{singleTile: true})
|
||||
};
|
||||
|
||||
for (var key in layers) {
|
||||
map.addLayer(layers[key]);
|
||||
}
|
||||
|
||||
map.setCenter(new OpenLayers.LonLat(146.65748632815,-42.230763671875), 7);
|
||||
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
controls = {
|
||||
navigation: new OpenLayers.Control.Navigation(),
|
||||
box: new OpenLayers.Control.SLDSelect(
|
||||
OpenLayers.Handler.RegularPolygon,
|
||||
{
|
||||
displayClass: 'olControlSLDSelectBox',
|
||||
layers: [layers['waterbodies']],
|
||||
handlerOptions: {irregular: true}
|
||||
}
|
||||
),
|
||||
polygon: new OpenLayers.Control.SLDSelect(
|
||||
OpenLayers.Handler.Polygon,
|
||||
{
|
||||
displayClass: 'olControlSLDSelectPolygon',
|
||||
layers: [layers['waterbodies']]
|
||||
}
|
||||
),
|
||||
line: new OpenLayers.Control.SLDSelect(
|
||||
OpenLayers.Handler.Path,
|
||||
{
|
||||
displayClass: 'olControlSLDSelectLine',
|
||||
layers: [layers['waterbodies']]
|
||||
}
|
||||
),
|
||||
point: new OpenLayers.Control.SLDSelect(
|
||||
OpenLayers.Handler.Click,
|
||||
{
|
||||
displayClass: 'olControlSLDSelectPoint',
|
||||
layers: [layers['waterbodies']]
|
||||
}
|
||||
),
|
||||
circle: new OpenLayers.Control.SLDSelect(
|
||||
OpenLayers.Handler.RegularPolygon,
|
||||
{
|
||||
displayClass: 'olControlSLDSelectBox',
|
||||
layers: [layers['waterbodies']],
|
||||
handlerOptions: {sides: 30}
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
for(var key in controls) {
|
||||
map.addControl(controls[key]);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleControl(element) {
|
||||
for(var key in controls) {
|
||||
var control = controls[key];
|
||||
if(element.value == key && element.checked) {
|
||||
control.activate();
|
||||
} else {
|
||||
control.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSelectionLayer(element) {
|
||||
var selectLayers = [];
|
||||
var elements = element.value.split("_");
|
||||
for (var key in layers) {
|
||||
var layer = layers[key];
|
||||
for (var i=0, len=elements.length; i<len; i++) {
|
||||
var value = elements[i];
|
||||
if (value == key && element.checked) {
|
||||
selectLayers.push(layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i=0, len=this.map.controls.length; i<len; i++) {
|
||||
var control = this.map.controls[i];
|
||||
if (control instanceof OpenLayers.Control.SLDSelect) {
|
||||
control.setLayers(selectLayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">SLD based selection on WMS layers</h1>
|
||||
|
||||
<div id="tags"></div>
|
||||
|
||||
<div id="shortdesc">Using Styled Layer Descriptors to make a selection on WMS layers</div>
|
||||
|
||||
<div id="map" style="width: 512; height: 256; border: 1px solid red;"></div>
|
||||
|
||||
<div id="docs">
|
||||
This example uses the OpenLayers.Control.SLDSelect to select features in a WMS
|
||||
layer. The features are highlighted using Styled Layer Descriptors (SLD). The
|
||||
control supports point, box, line and polygon selection modes by configuring the
|
||||
appriopriate handler.
|
||||
</div>
|
||||
|
||||
<div id="controls">
|
||||
<ul id="controlToggle"><b>Map Controls</b>
|
||||
<li>
|
||||
<input type="radio" name="control" value="navigation" id="noneToggle" onclick="toggleControl(this);" CHECKED>
|
||||
<label for="noneToggle">navigate</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="control" value="box" id="boxToggle" onclick="toggleControl(this);">
|
||||
<label for="boxToggle">SLD select with box</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="control" value="polygon" id="polygonToggle" onclick="toggleControl(this);">
|
||||
<label for="polygonToggle">SLD select with polygon</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="control" value="line" id="lineToggle" onclick="toggleControl(this);">
|
||||
<label for="lineToggle">SLD select with line</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="control" value="point" id="pointToggle" onclick="toggleControl(this);">
|
||||
<label for="pointToggle">SLD select with point</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="control" value="circle" id="circleToggle" onclick="toggleControl(this);">
|
||||
<label for="circleToggle">SLD select with circle</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="layers">
|
||||
<ul id="layerToggle"><b>Selection layer</b>
|
||||
<li>
|
||||
<input type="radio" name="layer" value="waterbodies" id="waterbodiesToggle" onclick="toggleSelectionLayer(this);" CHECKED>
|
||||
<label for="noneToggle">Water bodies</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="layer" value="cities" id="citiesToggle" onclick="toggleSelectionLayer(this);">
|
||||
<label for="citiesToggle">Cities</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="layer" value="roads" id="roadsToggle" onclick="toggleSelectionLayer(this);">
|
||||
<label for="roadsToggle">Roads</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="radio" name="layer" value="roads_cities" id="roadsCitiesToggle" onclick="toggleSelectionLayer(this);">
|
||||
<label for="roadsCitiesToggle">Roads and cities</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
29
examples/all-overlays-google.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers All Overlays with Google and OSM</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="all-overlays-google.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">All Overlays with Google and OSM</h1>
|
||||
<p id="shortdesc">
|
||||
Using the Google and OSM layers as overlays.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
Using the allOverlays property on the map, the first layer added
|
||||
must initially be visible. This example demonstrates the use of
|
||||
a Google layer and an OSM layer treated as overlays.
|
||||
</p><p>
|
||||
See the <a href="all-overlays-google.js" target="_blank">
|
||||
all-overlays-google.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
19
examples/all-overlays-google.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
allOverlays: true
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
var gmap = new OpenLayers.Layer.Google("Google Streets", {visibility: false});
|
||||
|
||||
// note that first layer must be visible
|
||||
map.addLayers([osm, gmap]);
|
||||
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.zoomToMaxExtent();
|
||||
|
||||
}
|
||||
@@ -53,8 +53,8 @@
|
||||
}
|
||||
|
||||
function add() {
|
||||
var url = 'http://boston.openguides.org/markers/AQUA.png';
|
||||
var sz = new OpenLayers.Size(10, 17);
|
||||
var url = 'http://www.openlayers.org/dev/img/marker.png';
|
||||
var sz = new OpenLayers.Size(21, 25);
|
||||
var calculateOffset = function(size) {
|
||||
return new OpenLayers.Pixel(-(size.w/2), -size.h);
|
||||
};
|
||||
|
||||
48
examples/filter-strategy.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers Filter Strategy Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script>OpenLayers.ImgPath = "../img/";</script>
|
||||
<script src="filter-strategy.js"></script>
|
||||
<style>
|
||||
.olControlAttribution {
|
||||
font-size: 9px;
|
||||
bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">Filter Strategy</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrates the filter strategy for limiting features passed to the layer.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<label for="span">time span (seconds)</label>
|
||||
<select id="span" name="span">
|
||||
<option value="15">15</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60" selected>60</option>
|
||||
<option value="120">120</option>
|
||||
<option value="240">240</option>
|
||||
</select>
|
||||
<input type="button" id="start" value="start">
|
||||
<input type="button" id="stop" value="stop"><br><br>
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example uses a filter strategy to limit the features that are passed
|
||||
to a layer. Features bound for this layer have a <code>when</code> attribute
|
||||
with date values. A filter strategy is constructed with a between filter
|
||||
that limits the span of dates shown. A simple animation cycles through
|
||||
the domain of the <code>when</code> values, calling <code>setFilter</code>
|
||||
on the strategy with an updated filter.
|
||||
</p><p>
|
||||
View the <a href="filter-strategy.js" target="_blank">filter-strategy.js</a>
|
||||
source to see how this is done
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
89
examples/filter-strategy.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var map, filter, filterStrategy;
|
||||
|
||||
var startDate = new Date(1272736800000); // lower bound of when values
|
||||
var endDate = new Date(1272737100000); // upper value of when values
|
||||
var step = 8; // sencods to advance each interval
|
||||
var interval = 0.125; // seconds between each step in the animation
|
||||
|
||||
function init() {
|
||||
|
||||
// add behavior to elements
|
||||
document.getElementById("start").onclick = startAnimation;
|
||||
document.getElementById("stop").onclick = stopAnimation;
|
||||
var spanEl = document.getElementById("span");
|
||||
|
||||
var mercator = new OpenLayers.Projection("EPSG:900913");
|
||||
var geographic = new OpenLayers.Projection("EPSG:4326");
|
||||
map = new OpenLayers.Map("map");
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
|
||||
filter = new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "when",
|
||||
lowerBoundary: startDate,
|
||||
upperBoundary: new Date(startDate.getTime() + (parseInt(spanEl.value, 10) * 1000))
|
||||
});
|
||||
|
||||
filterStrategy = new OpenLayers.Strategy.Filter({filter: filter});
|
||||
|
||||
var flights = new OpenLayers.Layer.Vector("Aircraft Locations", {
|
||||
projection: geographic,
|
||||
strategies: [new OpenLayers.Strategy.Fixed(), filterStrategy],
|
||||
protocol: new OpenLayers.Protocol.HTTP({
|
||||
url: "kml-track.kml",
|
||||
format: new OpenLayers.Format.KML({
|
||||
extractTracks: true
|
||||
//,extractStyles: true // use style from KML instead of styleMap below
|
||||
})
|
||||
}),
|
||||
styleMap: new OpenLayers.StyleMap({
|
||||
"default": new OpenLayers.Style({
|
||||
graphicName: "circle",
|
||||
pointRadius: 3,
|
||||
fillOpacity: 0.25,
|
||||
fillColor: "#ffcc66",
|
||||
strokeColor: "#ff9933",
|
||||
strokeWidth: 1
|
||||
})
|
||||
}),
|
||||
renderers: ["Canvas", "SVG", "VML"]
|
||||
});
|
||||
|
||||
map.addLayers([osm, flights]);
|
||||
map.setCenter(new OpenLayers.LonLat(-93.2735, 44.8349).transform(geographic, mercator), 8);
|
||||
|
||||
};
|
||||
|
||||
var animationTimer;
|
||||
var currentDate;
|
||||
function startAnimation() {
|
||||
if (animationTimer) {
|
||||
stopAnimation(true);
|
||||
}
|
||||
if (!currentDate) {
|
||||
currentDate = startDate;
|
||||
}
|
||||
var spanEl = document.getElementById("span");
|
||||
var next = function() {
|
||||
var span = parseInt(spanEl.value, 10);
|
||||
if (currentDate < endDate) {
|
||||
filter.lowerBoundary = currentDate;
|
||||
filter.upperBoundary = new Date(currentDate.getTime() + (span * 1000));
|
||||
filterStrategy.setFilter(filter);
|
||||
currentDate = new Date(currentDate.getTime() + (step * 1000))
|
||||
} else {
|
||||
stopAnimation(true);
|
||||
}
|
||||
}
|
||||
animationTimer = window.setInterval(next, interval * 1000);
|
||||
}
|
||||
|
||||
function stopAnimation(reset) {
|
||||
window.clearInterval(animationTimer);
|
||||
animationTimer = null;
|
||||
if (reset === true) {
|
||||
currentDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
text-align:left;
|
||||
font-size:100%;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
padding:.2em .2em;
|
||||
}
|
||||
|
||||
|
||||
28
examples/google-v3-alloverlays.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers Google (v3) Layer Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="google-v3-alloverlays.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">Google (v3) allOverlays Layer Example</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrate use the Google Maps v3 API with allOverlays set to true on the map.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
You can also use Google layers as overlays, e.g. in a map with
|
||||
allOverlays set to true. Note some of the layers disappear as
|
||||
you zoom in to levels that are not supported by all layers. See the
|
||||
<a href="google-v3-alloverlays.js" target="_blank">google-v3-alloverlays.js source</a>
|
||||
to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
35
examples/google-v3-alloverlays.js
Normal file
@@ -0,0 +1,35 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map('map', {allOverlays: true});
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
// the SATELLITE layer has all 22 zoom level, so we add it first to
|
||||
// become the internal base layer that determines the zoom levels of the
|
||||
// map.
|
||||
var gsat = new OpenLayers.Layer.Google(
|
||||
"Google Satellite",
|
||||
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
|
||||
);
|
||||
var gphy = new OpenLayers.Layer.Google(
|
||||
"Google Physical",
|
||||
{type: google.maps.MapTypeId.TERRAIN, visibility: false}
|
||||
);
|
||||
var gmap = new OpenLayers.Layer.Google(
|
||||
"Google Streets", // the default
|
||||
{numZoomLevels: 20, visibility: false}
|
||||
);
|
||||
var ghyb = new OpenLayers.Layer.Google(
|
||||
"Google Hybrid",
|
||||
{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 22, visibility: false}
|
||||
);
|
||||
|
||||
map.addLayers([gsat, gphy, gmap, ghyb]);
|
||||
|
||||
// Google.v3 uses EPSG:900913 as projection, so we have to
|
||||
// transform our coordinates
|
||||
map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
|
||||
new OpenLayers.Projection("EPSG:4326"),
|
||||
map.getProjectionObject()
|
||||
), 5);
|
||||
}
|
||||
32
examples/google-v3.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers Google (v3) Layer Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="google-v3.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">Google (v3) Layer Example</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrate use the Google Maps v3 API.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
If you use the Google Maps v3 API with a Google layer, you don't
|
||||
need to include an API key. This layer only works in the
|
||||
spherical mercator projection. See the
|
||||
<a href="google-v3.js" target="_blank">google-v3.js source</a>
|
||||
to see how this is done.
|
||||
<p>
|
||||
In order to position the Google attribution div in the default
|
||||
location, you must include the extra theme/default/google.css
|
||||
stylesheet.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
32
examples/google-v3.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map('map');
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
var gphy = new OpenLayers.Layer.Google(
|
||||
"Google Physical",
|
||||
{type: google.maps.MapTypeId.TERRAIN}
|
||||
);
|
||||
var gmap = new OpenLayers.Layer.Google(
|
||||
"Google Streets", // the default
|
||||
{numZoomLevels: 20}
|
||||
);
|
||||
var ghyb = new OpenLayers.Layer.Google(
|
||||
"Google Hybrid",
|
||||
{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
|
||||
);
|
||||
var gsat = new OpenLayers.Layer.Google(
|
||||
"Google Satellite",
|
||||
{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
|
||||
);
|
||||
|
||||
map.addLayers([gphy, gmap, ghyb, gsat]);
|
||||
|
||||
// Google.v3 uses EPSG:900913 as projection, so we have to
|
||||
// transform our coordinates
|
||||
map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
|
||||
new OpenLayers.Projection("EPSG:4326"),
|
||||
map.getProjectionObject()
|
||||
), 5);
|
||||
}
|
||||
@@ -23,19 +23,20 @@
|
||||
<script type="text/javascript">
|
||||
Proj4js.defs["EPSG:42304"]="+title=Atlas of Canada, LCC +proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs";
|
||||
|
||||
var graticuleCtl1, graticuleCtl2;
|
||||
var map1, map2;
|
||||
function init(){
|
||||
initLonLat();
|
||||
initProjected();
|
||||
}
|
||||
function initLonLat(){
|
||||
graticuleCtl1 = new OpenLayers.Control.Graticule({
|
||||
numPoints: 2,
|
||||
labelled: true
|
||||
});
|
||||
map1 = new OpenLayers.Map('map', {
|
||||
controls: [
|
||||
new OpenLayers.Control.Graticule({
|
||||
numPoints: 2,
|
||||
labelled: true,
|
||||
visible: true
|
||||
}),
|
||||
graticuleCtl1,
|
||||
new OpenLayers.Control.LayerSwitcher(),
|
||||
new OpenLayers.Control.PanZoomBar(),
|
||||
new OpenLayers.Control.Navigation()
|
||||
@@ -52,12 +53,13 @@
|
||||
|
||||
function initProjected(){
|
||||
var extent = new OpenLayers.Bounds(-2200000,-712631,3072800,3840000);
|
||||
graticuleCtl2 = new OpenLayers.Control.Graticule({
|
||||
labelled: true,
|
||||
targetSize: 200
|
||||
});
|
||||
var mapOptions = {
|
||||
controls: [
|
||||
new OpenLayers.Control.Graticule({
|
||||
labelled: true,
|
||||
targetSize: 200
|
||||
}),
|
||||
graticuleCtl2,
|
||||
new OpenLayers.Control.LayerSwitcher(),
|
||||
new OpenLayers.Control.PanZoomBar(),
|
||||
new OpenLayers.Control.Navigation()
|
||||
@@ -98,5 +100,12 @@
|
||||
<div id="map2" class="smallmap"></div>
|
||||
|
||||
<div id="docs"></div>
|
||||
<br style="clear:both" />
|
||||
<ul>
|
||||
<li><a href="#"
|
||||
onclick="graticuleCtl1.activate(); graticuleCtl2.activate(); return false;">Activate graticule controls</a></li>
|
||||
<li><a href="#"
|
||||
onclick="graticuleCtl1.deactivate(); graticuleCtl2.deactivate(); return false;">Deactivate graticule controls</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
36
examples/kml-track.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers KLM Track Parsing Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<style>
|
||||
.olControlAttribution {
|
||||
bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="kml-track.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">Parsing gx:Track in KML</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrates parsing of gx:Track elements from KML.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
If a KML document contains <code><gx:Track></code>
|
||||
elements and the extractTracks property is set true on the
|
||||
parer, features will be created that represent track points.
|
||||
Each feature will have a when attribute that contains the
|
||||
value of the relevant <code><when></code> element from
|
||||
the track.
|
||||
</p>
|
||||
<p>
|
||||
View the <a href="kml-track.js" target="_blank">kml-track.js</a>
|
||||
source to see how this is done.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
40
examples/kml-track.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
|
||||
var mercator = new OpenLayers.Projection("EPSG:900913");
|
||||
var geographic = new OpenLayers.Projection("EPSG:4326");
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: mercator,
|
||||
layers: [
|
||||
new OpenLayers.Layer.OSM(),
|
||||
new OpenLayers.Layer.Vector("Aircraft Locations", {
|
||||
projection: geographic,
|
||||
strategies: [new OpenLayers.Strategy.Fixed()],
|
||||
protocol: new OpenLayers.Protocol.HTTP({
|
||||
url: "kml-track.kml",
|
||||
format: new OpenLayers.Format.KML({
|
||||
extractTracks: true,
|
||||
trackAttributes: ["speed"]
|
||||
})
|
||||
}),
|
||||
styleMap: new OpenLayers.StyleMap({
|
||||
"default": new OpenLayers.Style({
|
||||
graphicName: "circle",
|
||||
pointRadius: 2,
|
||||
fillOpacity: 0.5,
|
||||
fillColor: "#ffcc66",
|
||||
strokeColor: "#666633",
|
||||
strokeWidth: 1,
|
||||
})
|
||||
})
|
||||
})
|
||||
],
|
||||
center: new OpenLayers.LonLat(-93.2735, 44.8349).transform(geographic, mercator),
|
||||
zoom: 8
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
3359
examples/kml-track.kml
Normal file
@@ -17,11 +17,11 @@
|
||||
var markers = new OpenLayers.Layer.Markers( "Markers" );
|
||||
map.addLayer(markers);
|
||||
|
||||
size = new OpenLayers.Size(50,50);
|
||||
size = new OpenLayers.Size(21, 25);
|
||||
calculateOffset = function(size) {
|
||||
return new OpenLayers.Pixel(-(size.w/2), -size.h); };
|
||||
icon = new OpenLayers.Icon(
|
||||
'http://boston.openguides.org/markers/AQUA.png',
|
||||
'http://www.openlayers.org/dev/img/marker.png',
|
||||
size, null, calculateOffset);
|
||||
markers.addMarker(
|
||||
new OpenLayers.Marker(new OpenLayers.LonLat(-71,40), icon));
|
||||
|
||||
0
examples/marker_shadow.png
Executable file → Normal file
|
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 374 B |
@@ -22,9 +22,9 @@
|
||||
var markers = new OpenLayers.Layer.Markers( "Markers" );
|
||||
map.addLayer(markers);
|
||||
|
||||
var size = new OpenLayers.Size(10,17);
|
||||
var size = new OpenLayers.Size(21,25);
|
||||
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
|
||||
var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png',size,offset);
|
||||
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png',size,offset);
|
||||
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon));
|
||||
|
||||
var halfIcon = icon.clone();
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
</style>
|
||||
|
||||
|
||||
<script type="text/javascript" src="http://clients.multimap.com/API/maps/1.1/metacarta_04"></script>
|
||||
<!-- multimap api key for http://(www.)openlayers.org -->
|
||||
<script type="text/javascript" src="http://developer.multimap.com/API/maps/1.2/OA10072915821139765"></script>
|
||||
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
@@ -34,11 +35,9 @@
|
||||
{'sphericalMercator': true}
|
||||
);
|
||||
merc = new OpenLayers.Layer.WMS("World Map",
|
||||
"http://world.freemap.in/tiles/",
|
||||
{'layers': 'factbook-overlay',
|
||||
'format':'png'},
|
||||
{'reproject': false,
|
||||
'opacity': 0.4,
|
||||
"http://maps.opengeo.org/geowebcache/service/wms",
|
||||
{'layers': 'bluemarble'},
|
||||
{'opacity': 0.4,
|
||||
'isBaseLayer': false,
|
||||
'wrapDateLine': true});
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
function runMVS() {
|
||||
OpenLayers.ProxyHost = '/proxy/?url=';
|
||||
if (document.location.protocol != "file:") {
|
||||
theArgs = OpenLayers.Util.getArgs();
|
||||
theArgs = OpenLayers.Util.getParameters();
|
||||
} else {
|
||||
theArgs = {};
|
||||
theArgs.center = "0,0";
|
||||
|
||||
27
examples/osm-google.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers OSM and Google Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="osm-google.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">OSM and Google Together</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrate use of an OSM layer and a Google layer as base layers.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
The Google(v3) layer and the OSM are both in the same projection
|
||||
- spherical mercator - and can be used on a map together.
|
||||
See the <a href="osm-google.js" target="_blank">
|
||||
osm-google.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
28
examples/osm-google.js
Normal file
@@ -0,0 +1,28 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
units: "m",
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-20037508, -20037508, 20037508, 20037508.34
|
||||
)
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
var gmap = new OpenLayers.Layer.Google("Google Streets");
|
||||
|
||||
map.addLayers([osm, gmap]);
|
||||
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
map.setCenter(
|
||||
new OpenLayers.LonLat(10.2, 48.9).transform(
|
||||
new OpenLayers.Projection("EPSG:4326"),
|
||||
map.getProjectionObject()
|
||||
),
|
||||
5
|
||||
);
|
||||
}
|
||||
@@ -10,7 +10,12 @@
|
||||
map = new OpenLayers.Map( 'map');
|
||||
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
|
||||
map.addLayer(layer);
|
||||
map.zoomToMaxExtent();
|
||||
map.setCenter(
|
||||
new OpenLayers.LonLat(-71.147, 42.472).transform(
|
||||
new OpenLayers.Projection("EPSG:4326"),
|
||||
map.getProjectionObject()
|
||||
), 12
|
||||
);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -75,15 +75,13 @@
|
||||
map1.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
// create an overview map control with the default options
|
||||
var overview1 = new OpenLayers.Control.OverviewMap();
|
||||
var overview1 = new OpenLayers.Control.OverviewMap({
|
||||
maximized: true
|
||||
});
|
||||
map1.addControl(overview1);
|
||||
|
||||
map1.setCenter(new OpenLayers.LonLat(0, 0), 2);
|
||||
|
||||
// expand the overview map control
|
||||
overview1.maximizeControl();
|
||||
|
||||
|
||||
// create the bottom map (with advanced overview map control)
|
||||
var mapOptions = {
|
||||
maxExtent: new OpenLayers.Bounds(-8242894.927728, 4965204.031195,
|
||||
@@ -99,6 +97,7 @@
|
||||
|
||||
// create an overview map control with non-default options
|
||||
var controlOptions = {
|
||||
maximized: true,
|
||||
mapOptions: OpenLayers.Util.extend(mapOptions, {
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34,
|
||||
@@ -111,9 +110,6 @@
|
||||
|
||||
map2.setCenter(new OpenLayers.LonLat(-8233165.3575055, 4980298.21113769), 3);
|
||||
|
||||
// expand the overview map control
|
||||
overview2.maximizeControl();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: 5px;
|
||||
background-color:red;
|
||||
background-color:white;
|
||||
}
|
||||
|
||||
.olControlPanel .olControlMouseDefaultsItemActive {
|
||||
@@ -78,6 +78,12 @@
|
||||
{title:'Draw a feature'}),
|
||||
new OpenLayers.Control.ZoomToMaxExtent({title:"Zoom to the max extent"})
|
||||
]);
|
||||
|
||||
nav = new OpenLayers.Control.NavigationHistory();
|
||||
// parent control must be added to the map
|
||||
map.addControl(nav);
|
||||
panel.addControls([nav.next, nav.previous]);
|
||||
|
||||
map.addControl(panel);
|
||||
|
||||
map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
|
||||
|
||||
0
examples/popupMatrix.jpg
Executable file → Normal file
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
65
examples/sld-parser.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers SLD Parser</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<style>
|
||||
#input {
|
||||
width: 90%;
|
||||
height: 300px;
|
||||
}
|
||||
#output {
|
||||
width: 90%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="title">SLD Parser</h1>
|
||||
|
||||
<div id="shortdesc">Parsing Styled Layer Descriptor (SLD) documents with the SLD format.</div>
|
||||
|
||||
<textarea id="input">paste SLD here</textarea><br>
|
||||
<input type="checkbox" id="symbolizers" checked="checked"><label for="symbolizers">Maintain multiple symbolizers and FeatureTypeStyle elements</label><br>
|
||||
<input type="checkbox" id="array"><label for="array">Compile an array of named styles instead of an object.</label><br>
|
||||
<input type="button" id="button" value="Parse SLD">
|
||||
|
||||
<div id="docs">
|
||||
This example uses the SLD format to parse SLD documents pasted into the textarea above.
|
||||
A rough representation of the parsed style is shown in the textarea below.
|
||||
</div>
|
||||
|
||||
<textarea id="output"></textarea>
|
||||
|
||||
<script>
|
||||
|
||||
var button = document.getElementById("button");
|
||||
var input = document.getElementById("input");
|
||||
var output = document.getElementById("output");
|
||||
var symbolizers = document.getElementById("symbolizers");
|
||||
var array = document.getElementById("array");
|
||||
|
||||
var json = new OpenLayers.Format.JSON();
|
||||
|
||||
var format, obj;
|
||||
|
||||
button.onclick = function() {
|
||||
var str = input.value;
|
||||
format = new OpenLayers.Format.SLD({
|
||||
multipleSymbolizers: !!symbolizers.checked,
|
||||
namedLayersAsArray: !!array.checked
|
||||
});
|
||||
obj = format.read(str);
|
||||
try {
|
||||
output.value = json.write(obj, true);
|
||||
} catch (err) {
|
||||
output.value = "Trouble: " + err;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
0
examples/small.jpg
Executable file → Normal file
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -69,7 +69,7 @@
|
||||
getTitleForObservedProperty: function(property) {
|
||||
for (var name in this.SOSCapabilities.contents.offeringList) {
|
||||
var offering = this.SOSCapabilities.contents.offeringList[name];
|
||||
if (offering.observedProperty === property) {
|
||||
if (offering.observedProperties[0] === property) {
|
||||
return offering.name;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@
|
||||
responseMode: 'inline',
|
||||
procedure: feature.attributes.id,
|
||||
offering: name,
|
||||
observedProperty: offering.observedProperty,
|
||||
observedProperty: offering.observedProperties[0],
|
||||
responseFormat: this.responseFormat
|
||||
});
|
||||
OpenLayers.Request.POST({
|
||||
|
||||
0
examples/thinlong.jpg
Executable file → Normal file
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
46
examples/web-mercator.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers: Web Mercator</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script>
|
||||
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="web-mercator.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">OpenLayers Spherical Mercator Example</h1>
|
||||
|
||||
<div id="tags">
|
||||
</div>
|
||||
<p id="shortdesc">
|
||||
Shows the use of layers in spherical or web mercator using different
|
||||
EPSG codes to indicate the same projection.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
A number of mapping services support the spherical or web
|
||||
mercator but use different EPSG codes to identify it. ArcGIS
|
||||
server version 9.3 uses EPSG:102113 to represent the same SRS
|
||||
that OpenLayers typically refers to by EPSG:900913.
|
||||
</p><p>
|
||||
To configure a map with a WMS layer overlaid on a Google layer
|
||||
where the WMS uses EPSG:102113 to refer to the web mercator
|
||||
projection, the Google layer must be constructed with this
|
||||
projection code in its options (it is not sufficient to
|
||||
construct the map with this projection).
|
||||
<p>
|
||||
If your application needs to transform coordinates to and from
|
||||
EPSG:102113, you must add custom transforms as well.
|
||||
</p><p>
|
||||
See the <a href="web-mercator.js" target="_blank">web-mercator.js</a>
|
||||
source for details.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
45
examples/web-mercator.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// make map available for easy debugging
|
||||
var map;
|
||||
|
||||
// if your application transforms coordinates to and from EPSG:102113 then
|
||||
// you must uncomment the lines below
|
||||
|
||||
// OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:102113",
|
||||
// OpenLayers.Layer.SphericalMercator.projectForward);
|
||||
// OpenLayers.Projection.addTransform("EPSG:102113", "EPSG:4326",
|
||||
// OpenLayers.Layer.SphericalMercator.projectInverse);
|
||||
|
||||
function init() {
|
||||
|
||||
var options = {
|
||||
projection: new OpenLayers.Projection("EPSG:102113"),
|
||||
units: "m",
|
||||
numZoomLevels: 18,
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
|
||||
20037508, 20037508.34)
|
||||
};
|
||||
map = new OpenLayers.Map('map', options);
|
||||
|
||||
// create Google layer with EPSG:102113 code
|
||||
var gsat = new OpenLayers.Layer.Google("Google Imagery", {
|
||||
type: G_SATELLITE_MAP,
|
||||
sphericalMercator: true,
|
||||
projection: "EPSG:102113"
|
||||
});
|
||||
|
||||
// create WMS layer
|
||||
var wms = new OpenLayers.Layer.WMS(
|
||||
"Highways",
|
||||
"http://sampleserver1.arcgisonline.com/arcgis/services/Specialty/ESRI_StateCityHighway_USA/MapServer/WMSServer",
|
||||
{layers: "2", format: "image/gif", transparent: "true"},
|
||||
{
|
||||
isBaseLayer: false,
|
||||
wrapDateLine: true
|
||||
}
|
||||
);
|
||||
|
||||
map.addLayers([gsat, wms]);
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.setCenter(new OpenLayers.LonLat(-10723197, 4500612), 3);
|
||||
}
|
||||
29
examples/wfs-filter.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers WFS Protocol with Filter</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="wfs-filter.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">WFS Protocol and Filter</h1>
|
||||
<p id="shortdesc">
|
||||
Demonstrates the use of a filter in making GetFeature requests using the WFS protocol.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<div id="docs">
|
||||
<p>
|
||||
If a vector layer has a filter and the protocol supports server-side filtering,
|
||||
the filter will be serialized in requests for features. The WFS protocol can be
|
||||
used with a vector layer to serialize a filter using OGC Filter Encoding. This
|
||||
example requests all features that are <code>TYPE</code> "highway" or "road".
|
||||
</p><p>
|
||||
See the <a href="wfs-filter.js" target="_blank">wfs-filter source</a>
|
||||
for details on how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
48
examples/wfs-filter.js
Normal file
@@ -0,0 +1,48 @@
|
||||
var map;
|
||||
|
||||
// use proxy if requesting features cross-domain
|
||||
OpenLayers.ProxyHost= "proxy.cgi?url=";
|
||||
|
||||
function init() {
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
layers: [
|
||||
new OpenLayers.Layer.WMS(
|
||||
"Natural Earth",
|
||||
"http://demo.opengeo.org/geoserver/wms",
|
||||
{layers: "topp:naturalearth"}
|
||||
),
|
||||
new OpenLayers.Layer.Vector("WFS", {
|
||||
strategies: [new OpenLayers.Strategy.BBOX()],
|
||||
protocol: new OpenLayers.Protocol.WFS({
|
||||
url: "http://demo.opengeo.org/geoserver/wfs",
|
||||
featureType: "tasmania_roads",
|
||||
featureNS: "http://www.openplans.org/topp"
|
||||
}),
|
||||
styleMap: new OpenLayers.StyleMap({
|
||||
strokeWidth: 3,
|
||||
strokeColor: "#333333"
|
||||
}),
|
||||
filter: new OpenLayers.Filter.Logical({
|
||||
type: OpenLayers.Filter.Logical.OR,
|
||||
filters: [
|
||||
new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.EQUAL_TO,
|
||||
property: "TYPE",
|
||||
value: "highway"
|
||||
}),
|
||||
new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.EQUAL_TO,
|
||||
property: "TYPE",
|
||||
value: "road"
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
],
|
||||
center: new OpenLayers.LonLat(146.7, -41.8),
|
||||
zoom: 6
|
||||
});
|
||||
|
||||
}
|
||||
0
examples/widelong.jpg
Executable file → Normal file
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 210 KiB |
0
examples/wideshort.jpg
Executable file → Normal file
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
38
examples/wmts-capabilities.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers WMTS Capabilities Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/Firebug/firebug.js"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="wmts-capabilities.js"></script>
|
||||
<style>
|
||||
.olControlAttribution {
|
||||
bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<h1 id="title">Web Map Tile Service (WMTS) Capabilities Parsing</h1>
|
||||
|
||||
<p id="shortdesc">
|
||||
The WMTS Capabilities format allows for parsing of capabilities
|
||||
documents from OGC Web Map Tile Service (WMTS) version 1.0.0
|
||||
implementations.
|
||||
</p>
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example creates an OpenLayers.Layer.WMTS layer to based
|
||||
on the results of parsing a capabilities doc with the
|
||||
OpenLayers.Format.WMTSCapabilities parser.
|
||||
</p><p>
|
||||
See the <a href="wmts-capabilities.js" target="_blank">
|
||||
wmts-capabilities.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
64
examples/wmts-capabilities.js
Normal file
@@ -0,0 +1,64 @@
|
||||
OpenLayers.ProxyHost = "/proxy/?url=";
|
||||
|
||||
var map, format;
|
||||
|
||||
function init() {
|
||||
|
||||
format = new OpenLayers.Format.WMTSCapabilities({
|
||||
/**
|
||||
* This particular service is not in compliance with the WMTS spec and
|
||||
* is providing coordinates in y, x order regardless of the CRS. To
|
||||
* work around this, we can provide the format a table of CRS URN that
|
||||
* should be considered y, x order. These will extend the defaults on
|
||||
* the format.
|
||||
*/
|
||||
yx: {
|
||||
"urn:ogc:def:crs:EPSG::900913": true
|
||||
}
|
||||
});
|
||||
|
||||
OpenLayers.Request.GET({
|
||||
url: "http://v2.suite.opengeo.org/geoserver/gwc/service/wmts",
|
||||
params: {
|
||||
SERVICE: "WMTS",
|
||||
VERSION: "1.0.0",
|
||||
REQUEST: "GetCapabilities"
|
||||
},
|
||||
success: function(request) {
|
||||
var doc = request.responseXML;
|
||||
if (!doc || !doc.documentElement) {
|
||||
doc = request.responseText;
|
||||
}
|
||||
var capabilities = format.read(doc);
|
||||
var layer = format.createLayer(capabilities, {
|
||||
layer: "medford:buildings",
|
||||
matrixSet: "EPSG:900913",
|
||||
format: "image/png",
|
||||
opacity: 0.7,
|
||||
isBaseLayer: false
|
||||
});
|
||||
map.addLayer(layer);
|
||||
},
|
||||
failure: function() {
|
||||
alert("Trouble getting capabilities doc");
|
||||
OpenLayers.Console.error.apply(OpenLayers.Console, arguments);
|
||||
}
|
||||
})
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: "EPSG:900913",
|
||||
units: "m",
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-20037508.34, -20037508.34, 20037508.34, 20037508.34
|
||||
),
|
||||
maxResolution: 156543.0339
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
|
||||
map.addLayer(osm);
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.setCenter(new OpenLayers.LonLat(-13677832, 5213272), 13);
|
||||
|
||||
}
|
||||
69
examples/wmts-getfeatureinfo.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers WMTS GetFeatureInfo Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/Firebug/firebug.js"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="wmts-getfeatureinfo.js"></script>
|
||||
<style>
|
||||
.olControlAttribution {
|
||||
bottom: 5px;
|
||||
}
|
||||
|
||||
table.featureInfo, table.featureInfo td, table.featureInfo th {
|
||||
border: 1px solid #ddd;
|
||||
border-collapse: collapse;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
padding: .1em .1em;
|
||||
}
|
||||
table.featureInfo th {
|
||||
padding: .2em .2em;
|
||||
font-weight: bold;
|
||||
background: #eee;
|
||||
}
|
||||
table.featureInfo td {
|
||||
background: #fff;
|
||||
}
|
||||
table.featureInfo tr.odd td {
|
||||
background: #eee;
|
||||
}
|
||||
table.featureInfo caption {
|
||||
text-align: left;
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
padding: .1em .2em;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<h1 id="title">WMTS GetFeatureInfo Control</h1>
|
||||
|
||||
<p id="shortdesc">
|
||||
The WMTSGetFeatureInfo control allows retrieval of information about
|
||||
features displayed in a WMTS layer.
|
||||
</p>
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
<input id="drill" type="checkbox" checked="checked">
|
||||
<label for="drill">drill down</label>
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example uses an OpenLayers.Control.WMTSGetFeatureInfo
|
||||
control layer to access information from WMTS layers. The
|
||||
control is activated and configured to request feature
|
||||
information when you click on the map. If the control's
|
||||
drillDown property is set to true, multiple layers can be
|
||||
queried.
|
||||
</p><p>
|
||||
See the <a href="wmts-getfeatureinfo.js" target="_blank">
|
||||
wmts-getfeatureinfo.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
99
examples/wmts-getfeatureinfo.js
Normal file
@@ -0,0 +1,99 @@
|
||||
OpenLayers.ProxyHost = "/proxy/?url=";
|
||||
var map, control, popups = {};
|
||||
|
||||
function init() {
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: "EPSG:900913",
|
||||
units: "m",
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-20037508.34, -20037508.34, 20037508.34, 20037508.34
|
||||
),
|
||||
maxResolution: 156543.0339
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
|
||||
// If tile matrix identifiers differ from zoom levels (0, 1, 2, ...)
|
||||
// then they must be explicitly provided.
|
||||
var matrixIds = new Array(26);
|
||||
for (var i=0; i<26; ++i) {
|
||||
matrixIds[i] = "EPSG:900913:" + i;
|
||||
}
|
||||
|
||||
var zoning = new OpenLayers.Layer.WMTS({
|
||||
name: "zoning",
|
||||
url: "http://v2.suite.opengeo.org/geoserver/gwc/service/wmts/",
|
||||
layer: "medford:zoning",
|
||||
matrixSet: "EPSG:900913",
|
||||
matrixIds: matrixIds,
|
||||
format: "image/png",
|
||||
style: "_null",
|
||||
opacity: 0.7,
|
||||
isBaseLayer: false
|
||||
});
|
||||
var buildings = new OpenLayers.Layer.WMTS({
|
||||
name: "building",
|
||||
url: "http://v2.suite.opengeo.org/geoserver/gwc/service/wmts/",
|
||||
layer: "medford:buildings",
|
||||
matrixSet: "EPSG:900913",
|
||||
matrixIds: matrixIds,
|
||||
format: "image/png",
|
||||
style: "_null",
|
||||
isBaseLayer: false
|
||||
});
|
||||
|
||||
map.addLayers([osm, zoning, buildings]);
|
||||
|
||||
// create WMTS GetFeatureInfo control
|
||||
control = new OpenLayers.Control.WMTSGetFeatureInfo({
|
||||
drillDown: true,
|
||||
queryVisible: true,
|
||||
eventListeners: {
|
||||
getfeatureinfo: function(evt) {
|
||||
var text;
|
||||
var match = evt.text.match(/<body[^>]*>([\s\S]*)<\/body>/);
|
||||
if (match && !match[1].match(/^\s*$/)) {
|
||||
text = match[1];
|
||||
} else {
|
||||
text = "No " + evt.layer.name + " features in that area.<br>";
|
||||
}
|
||||
var popupId = evt.xy.x + "," + evt.xy.y;
|
||||
var popup = popups[popupId];
|
||||
if (!popup || !popup.map) {
|
||||
popup = new OpenLayers.Popup.FramedCloud(
|
||||
popupId,
|
||||
map.getLonLatFromPixel(evt.xy),
|
||||
null,
|
||||
" ",
|
||||
null,
|
||||
true,
|
||||
function(evt) {
|
||||
delete popups[this.id];
|
||||
this.hide();
|
||||
OpenLayers.Event.stop(evt);
|
||||
}
|
||||
);
|
||||
popups[popupId] = popup;
|
||||
map.addPopup(popup, true);
|
||||
}
|
||||
popup.setContentHTML(popup.contentHTML + text);
|
||||
popup.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
map.addControl(control);
|
||||
control.activate();
|
||||
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.setCenter(new OpenLayers.LonLat(-13678519, 5212803), 15);
|
||||
|
||||
var drill = document.getElementById("drill");
|
||||
drill.checked = true;
|
||||
drill.onchange = function() {
|
||||
control.drillDown = drill.checked;
|
||||
};
|
||||
}
|
||||
|
||||
OpenLayers.Popup.FramedCloud.prototype.maxSize = new OpenLayers.Size(350, 200);
|
||||
36
examples/wmts.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers WMTS Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/Firebug/firebug.js"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="wmts.js"></script>
|
||||
<style>
|
||||
.olControlAttribution {
|
||||
bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<h1 id="title">Web Map Tile Service (WMTS) Layer</h1>
|
||||
|
||||
<p id="shortdesc">
|
||||
The WMTS layer allows viewing of tiles from a server implementing
|
||||
the OGC Web Map Tile Service (WMTS) standard version 1.0.0.
|
||||
</p>
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example uses an OpenLayers.Layer.WMTS layer to display
|
||||
cached tiles over an OSM layer in spherical mercator coordinates.
|
||||
</p><p>
|
||||
See the <a href="wmts.js" target="_blank">
|
||||
wmts.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
40
examples/wmts.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
projection: "EPSG:900913",
|
||||
units: "m",
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-20037508.34, -20037508.34, 20037508.34, 20037508.34
|
||||
),
|
||||
maxResolution: 156543.0339
|
||||
});
|
||||
|
||||
var osm = new OpenLayers.Layer.OSM();
|
||||
|
||||
// If tile matrix identifiers differ from zoom levels (0, 1, 2, ...)
|
||||
// then they must be explicitly provided.
|
||||
var matrixIds = new Array(26);
|
||||
for (var i=0; i<26; ++i) {
|
||||
matrixIds[i] = "EPSG:900913:" + i;
|
||||
}
|
||||
|
||||
var wmts = new OpenLayers.Layer.WMTS({
|
||||
name: "Medford Buildings",
|
||||
url: "http://v2.suite.opengeo.org/geoserver/gwc/service/wmts/",
|
||||
layer: "medford:buildings",
|
||||
matrixSet: "EPSG:900913",
|
||||
matrixIds: matrixIds,
|
||||
format: "image/png",
|
||||
style: "_null",
|
||||
opacity: 0.7,
|
||||
isBaseLayer: false
|
||||
});
|
||||
|
||||
map.addLayers([osm, wmts]);
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
map.setCenter(new OpenLayers.LonLat(-13677832, 5213272), 13);
|
||||
|
||||
}
|
||||
33
examples/xyz-offset.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLayers XYZ with Offset</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src="xyz-offset.js"></script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">XYZ Layer with Offset</h1>
|
||||
|
||||
<div id="shortdesc">Using a limited set of levels from an XYZ layer with zoomOffset.</div>
|
||||
|
||||
<div id="map" class="smallmap"></div>
|
||||
|
||||
<div id="docs">
|
||||
<p>
|
||||
The XYZ layer allows a zoomOffset to be set if you want to have
|
||||
a maximum resolution for the map that differs from the maxiumum
|
||||
resolution of the cached tiles. This example uses only 6 of the
|
||||
levels in the cache, starting with the ninth level (index of 8)
|
||||
in the cache. To do this, the layer is constructed with a
|
||||
zoomOffset of 8. When the map zoom level is zero, the level
|
||||
with index 8 will be requested from the cache.
|
||||
</p>
|
||||
<p>
|
||||
See the <a href="xyz-offset.js" target="_blank">
|
||||
xyz-offset.js source</a> to see how this is done.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
37
examples/xyz-offset.js
Normal file
@@ -0,0 +1,37 @@
|
||||
var map, layer;
|
||||
|
||||
// if tiles are not available, hide images
|
||||
//OpenLayers.Util.onImageLoadError = function() {
|
||||
// this.style.display = "none";
|
||||
//}
|
||||
|
||||
// called on body load
|
||||
function init() {
|
||||
|
||||
var extent = new OpenLayers.Bounds(
|
||||
-13758743.4295939, 5591455.28887228, -13531302.3472101 , 5757360.4178881
|
||||
);
|
||||
|
||||
map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-128 * 156543.0339, -128 * 156543.0339,
|
||||
128 * 156543.0339, 128 * 156543.0339
|
||||
),
|
||||
restrictedExtent: extent,
|
||||
maxResolution: 611.496226171875, // corresponds to level 8 in the cache
|
||||
numZoomLevels: 6,
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
units: "m",
|
||||
layers: [
|
||||
new OpenLayers.Layer.XYZ(
|
||||
"ESRI",
|
||||
"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer/tile/${z}/${y}/${x}",
|
||||
{zoomOffset: 8} // since our map maxResolution differs from cache max resolution
|
||||
)
|
||||
]
|
||||
});
|
||||
|
||||
map.zoomToExtent(extent);
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -107,6 +107,7 @@
|
||||
"OpenLayers/Layer/EventPane.js",
|
||||
"OpenLayers/Layer/FixedZoomLevels.js",
|
||||
"OpenLayers/Layer/Google.js",
|
||||
"OpenLayers/Layer/Google/v3.js",
|
||||
"OpenLayers/Layer/VirtualEarth.js",
|
||||
"OpenLayers/Layer/Yahoo.js",
|
||||
"OpenLayers/Layer/HTTPRequest.js",
|
||||
@@ -124,6 +125,7 @@
|
||||
"OpenLayers/Layer/WMS.js",
|
||||
"OpenLayers/Layer/WMS/Untiled.js",
|
||||
"OpenLayers/Layer/WMS/Post.js",
|
||||
"OpenLayers/Layer/WMTS.js",
|
||||
"OpenLayers/Layer/ArcIMS.js",
|
||||
"OpenLayers/Layer/GeoRSS.js",
|
||||
"OpenLayers/Layer/Boxes.js",
|
||||
@@ -178,8 +180,10 @@
|
||||
"OpenLayers/Control/NavigationHistory.js",
|
||||
"OpenLayers/Control/Measure.js",
|
||||
"OpenLayers/Control/WMSGetFeatureInfo.js",
|
||||
"OpenLayers/Control/WMTSGetFeatureInfo.js",
|
||||
"OpenLayers/Control/Graticule.js",
|
||||
"OpenLayers/Control/TransformFeature.js",
|
||||
"OpenLayers/Control/SLDSelect.js",
|
||||
"OpenLayers/Geometry.js",
|
||||
"OpenLayers/Geometry/Rectangle.js",
|
||||
"OpenLayers/Geometry/Collection.js",
|
||||
@@ -200,6 +204,7 @@
|
||||
"OpenLayers/Layer/Vector.js",
|
||||
"OpenLayers/Layer/Vector/RootContainer.js",
|
||||
"OpenLayers/Strategy.js",
|
||||
"OpenLayers/Strategy/Filter.js",
|
||||
"OpenLayers/Strategy/Fixed.js",
|
||||
"OpenLayers/Strategy/Cluster.js",
|
||||
"OpenLayers/Strategy/Paging.js",
|
||||
@@ -224,10 +229,12 @@
|
||||
"OpenLayers/Layer/PointTrack.js",
|
||||
"OpenLayers/Layer/GML.js",
|
||||
"OpenLayers/Style.js",
|
||||
"OpenLayers/Style2.js",
|
||||
"OpenLayers/StyleMap.js",
|
||||
"OpenLayers/Rule.js",
|
||||
"OpenLayers/Format.js",
|
||||
"OpenLayers/Format/XML.js",
|
||||
"OpenLayers/Format/Context.js",
|
||||
"OpenLayers/Format/ArcXML.js",
|
||||
"OpenLayers/Format/ArcXML/Features.js",
|
||||
"OpenLayers/Format/GML.js",
|
||||
@@ -255,6 +262,9 @@
|
||||
"OpenLayers/Format/SLD.js",
|
||||
"OpenLayers/Format/SLD/v1.js",
|
||||
"OpenLayers/Format/SLD/v1_0_0.js",
|
||||
"OpenLayers/Format/OWSCommon/v1.js",
|
||||
"OpenLayers/Format/OWSCommon/v1_0_0.js",
|
||||
"OpenLayers/Format/OWSCommon/v1_1_0.js",
|
||||
"OpenLayers/Format/CSWGetDomain.js",
|
||||
"OpenLayers/Format/CSWGetDomain/v2_0_2.js",
|
||||
"OpenLayers/Format/CSWGetRecords.js",
|
||||
@@ -278,11 +288,14 @@
|
||||
"OpenLayers/Format/WMSCapabilities/v1_3.js",
|
||||
"OpenLayers/Format/WMSCapabilities/v1_3_0.js",
|
||||
"OpenLayers/Format/WMSGetFeatureInfo.js",
|
||||
"OpenLayers/Format/OWSCommon/v1_1_0.js",
|
||||
"OpenLayers/Format/SOSCapabilities.js",
|
||||
"OpenLayers/Format/SOSCapabilities/v1_0_0.js",
|
||||
"OpenLayers/Format/SOSGetObservation.js",
|
||||
"OpenLayers/Format/SOSGetFeatureOfInterest.js",
|
||||
"OpenLayers/Format/OWSContext.js",
|
||||
"OpenLayers/Format/OWSContext/v0_3_1.js",
|
||||
"OpenLayers/Format/WMTSCapabilities.js",
|
||||
"OpenLayers/Format/WMTSCapabilities/v1_0_0.js",
|
||||
"OpenLayers/Layer/WFS.js",
|
||||
"OpenLayers/Control/GetFeature.js",
|
||||
"OpenLayers/Control/MouseToolbar.js",
|
||||
@@ -293,6 +306,12 @@
|
||||
"OpenLayers/Control/ZoomOut.js",
|
||||
"OpenLayers/Control/ZoomPanel.js",
|
||||
"OpenLayers/Control/EditingToolbar.js",
|
||||
"OpenLayers/Symbolizer.js",
|
||||
"OpenLayers/Symbolizer/Point.js",
|
||||
"OpenLayers/Symbolizer/Line.js",
|
||||
"OpenLayers/Symbolizer/Polygon.js",
|
||||
"OpenLayers/Symbolizer/Text.js",
|
||||
"OpenLayers/Symbolizer/Raster.js",
|
||||
"OpenLayers/Lang.js",
|
||||
"OpenLayers/Lang/en.js"
|
||||
); // etc.
|
||||
|
||||
@@ -519,7 +519,7 @@ OpenLayers.Array = {
|
||||
* Array.prototype.filter extension to the ECMA-262 standard. Where
|
||||
* available, Array.prototype.filter will be used.
|
||||
*
|
||||
* Based on well known example from http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter
|
||||
* Based on well known example from http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter
|
||||
*
|
||||
* Parameters:
|
||||
* array - {Array} The array to be filtered. This array is not mutated.
|
||||
@@ -559,3 +559,123 @@ OpenLayers.Array = {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Namespace: OpenLayers.Date
|
||||
* Contains implementations of Date.parse and date.toISOString that match the
|
||||
* ECMAScript 5 specification for parsing RFC 3339 dates.
|
||||
* http://tools.ietf.org/html/rfc3339
|
||||
*/
|
||||
OpenLayers.Date = {
|
||||
|
||||
/**
|
||||
* APIMethod: toISOString
|
||||
* Generates a string representing a date. The format of the string follows
|
||||
* the profile of ISO 8601 for date and time on the Internet (see
|
||||
* http://tools.ietf.org/html/rfc3339). If the toISOString method is
|
||||
* available on the Date prototype, that is used. The toISOString
|
||||
* method for Date instances is defined in ECMA-262.
|
||||
*
|
||||
* Parameters:
|
||||
* date - {Date} A date object.
|
||||
*
|
||||
* Returns:
|
||||
* {String} A string representing the date (e.g.
|
||||
* "2010-08-07T16:58:23.123Z"). If the date does not have a valid time
|
||||
* (i.e. isNaN(date.getTime())) this method returns the string "Invalid
|
||||
* Date". The ECMA standard says the toISOString method should throw
|
||||
* RangeError in this case, but Firefox returns a string instead. For
|
||||
* best results, use isNaN(date.getTime()) to determine date validity
|
||||
* before generating date strings.
|
||||
*/
|
||||
toISOString: (function() {
|
||||
if ("toISOString" in Date.prototype) {
|
||||
return function(date) {
|
||||
return date.toISOString();
|
||||
}
|
||||
} else {
|
||||
function pad(num, len) {
|
||||
var str = num + "";
|
||||
while (str.length < len) {
|
||||
str = "0" + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
return function(date) {
|
||||
var str;
|
||||
if (isNaN(date.getTime())) {
|
||||
// ECMA-262 says throw RangeError, Firefox returns
|
||||
// "Invalid Date"
|
||||
str = "Invalid Date";
|
||||
} else {
|
||||
str =
|
||||
date.getUTCFullYear() + "-" +
|
||||
pad(date.getUTCMonth() + 1, 2) + "-" +
|
||||
pad(date.getUTCDate(), 2) + "T" +
|
||||
pad(date.getUTCHours(), 2) + ":" +
|
||||
pad(date.getUTCMinutes(), 2) + ":" +
|
||||
pad(date.getUTCSeconds(), 2) + "." +
|
||||
pad(date.getUTCMilliseconds(), 3) + "Z";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
})(),
|
||||
|
||||
/**
|
||||
* APIMethod: parse
|
||||
* Generate a date object from a string. The format for the string follows
|
||||
* the profile of ISO 8601 for date and time on the Internet (see
|
||||
* http://tools.ietf.org/html/rfc3339). If the parse method on
|
||||
* the Date constructor returns a valid date for the given string,
|
||||
* that method is used.
|
||||
*
|
||||
* Parameters:
|
||||
* str - {String} A string representing the date (e.g.
|
||||
* "2010", "2010-08", "2010-08-07", "2010-08-07T16:58:23.123Z",
|
||||
* "2010-08-07T11:58:23.123-06").
|
||||
*
|
||||
* Returns:
|
||||
* {Date} A date object. If the string could not be parsed, an invalid
|
||||
* date is returned (i.e. isNaN(date.getTime())).
|
||||
*/
|
||||
parse: function(str) {
|
||||
var date;
|
||||
// first check if the native parse method can parse it
|
||||
var elapsed = Date.parse(str);
|
||||
if (!isNaN(elapsed)) {
|
||||
date = new Date(elapsed);
|
||||
} else {
|
||||
var match = str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);
|
||||
var date;
|
||||
if (match && (match[1] || match[7])) { // must have at least year or time
|
||||
var year = parseInt(match[1], 10) || 0;
|
||||
var month = (parseInt(match[2], 10) - 1) || 0;
|
||||
var day = parseInt(match[3], 10) || 1;
|
||||
date = new Date(Date.UTC(year, month, day));
|
||||
// optional time
|
||||
var type = match[7];
|
||||
if (type) {
|
||||
var hours = parseInt(match[4], 10);
|
||||
var minutes = parseInt(match[5], 10);
|
||||
var secFrac = parseFloat(match[6]);
|
||||
var seconds = secFrac | 0;
|
||||
var milliseconds = Math.round(1000 * (secFrac - seconds));
|
||||
date.setUTCHours(hours, minutes, seconds, milliseconds);
|
||||
// check offset
|
||||
if (type !== "Z") {
|
||||
var hoursOffset = parseInt(type, 10);
|
||||
var minutesOffset = parseInt(match[8]) || 0;
|
||||
var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);
|
||||
date = new Date(date.getTime() + offset);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
date = new Date("invalid");
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -477,7 +477,7 @@ OpenLayers.Bounds = OpenLayers.Class({
|
||||
*
|
||||
* bounds - {<OpenLayers.Bounds>} The target bounds.
|
||||
* partial - {Boolean} If any of the target corners is within this bounds
|
||||
* consider the bounds contained. Default is false. If true, the
|
||||
* consider the bounds contained. Default is false. If false, the
|
||||
* entire target bounds must be contained within this bounds.
|
||||
* inclusive - {Boolean} Treat shared edges as contained. Default is
|
||||
* true.
|
||||
|
||||
@@ -35,30 +35,31 @@ OpenLayers.Class = function() {
|
||||
}
|
||||
};
|
||||
var extended = {};
|
||||
var parent, initialize;
|
||||
var parent, initialize, Type;
|
||||
for(var i=0, len=arguments.length; i<len; ++i) {
|
||||
if(typeof arguments[i] == "function") {
|
||||
Type = arguments[i];
|
||||
if(typeof Type == "function") {
|
||||
// make the class passed as the first argument the superclass
|
||||
if(i == 0 && len > 1) {
|
||||
initialize = arguments[i].prototype.initialize;
|
||||
initialize = Type.prototype.initialize;
|
||||
// replace the initialize method with an empty function,
|
||||
// because we do not want to create a real instance here
|
||||
arguments[i].prototype.initialize = function() {};
|
||||
Type.prototype.initialize = function() {};
|
||||
// the line below makes sure that the new class has a
|
||||
// superclass
|
||||
extended = new arguments[i];
|
||||
extended = new Type();
|
||||
// restore the original initialize method
|
||||
if(initialize === undefined) {
|
||||
delete arguments[i].prototype.initialize;
|
||||
delete Type.prototype.initialize;
|
||||
} else {
|
||||
arguments[i].prototype.initialize = initialize;
|
||||
Type.prototype.initialize = initialize;
|
||||
}
|
||||
}
|
||||
// get the prototype of the superclass
|
||||
parent = arguments[i].prototype;
|
||||
parent = Type.prototype;
|
||||
} else {
|
||||
// in this case we're extending with the prototype
|
||||
parent = arguments[i];
|
||||
parent = Type;
|
||||
}
|
||||
OpenLayers.Util.extend(extended, parent);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ OpenLayers.Element = {
|
||||
hide: function() {
|
||||
for (var i=0, len=arguments.length; i<len; i++) {
|
||||
var element = OpenLayers.Util.getElement(arguments[i]);
|
||||
element.style.display = 'none';
|
||||
if (element) {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -61,7 +63,9 @@ OpenLayers.Element = {
|
||||
show: function() {
|
||||
for (var i=0, len=arguments.length; i<len; i++) {
|
||||
var element = OpenLayers.Util.getElement(arguments[i]);
|
||||
element.style.display = '';
|
||||
if (element) {
|
||||
element.style.display = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -92,7 +92,8 @@ OpenLayers.LonLat = OpenLayers.Class({
|
||||
OpenLayers.Console.error(msg);
|
||||
return null;
|
||||
}
|
||||
return new OpenLayers.LonLat(this.lon + lon, this.lat + lat);
|
||||
return new OpenLayers.LonLat(this.lon + OpenLayers.Util.toFloat(lon),
|
||||
this.lat + OpenLayers.Util.toFloat(lat));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -184,6 +185,5 @@ OpenLayers.LonLat = OpenLayers.Class({
|
||||
*/
|
||||
OpenLayers.LonLat.fromString = function(str) {
|
||||
var pair = str.split(",");
|
||||
return new OpenLayers.LonLat(parseFloat(pair[0]),
|
||||
parseFloat(pair[1]));
|
||||
return new OpenLayers.LonLat(pair[0], pair[1]);
|
||||
};
|
||||
|
||||
@@ -76,9 +76,9 @@ OpenLayers.Control = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* Property: type
|
||||
* {OpenLayers.Control.TYPES} Controls can have a 'type'. The type
|
||||
* determines the type of interactions which are possible with them when
|
||||
* they are placed into a toolbar.
|
||||
* {Number} Controls can have a 'type'. The type determines the type of
|
||||
* interactions which are possible with them when they are placed in an
|
||||
* <OpenLayers.Control.Panel>.
|
||||
*/
|
||||
type: null,
|
||||
|
||||
@@ -351,6 +351,17 @@ OpenLayers.Control = OpenLayers.Class({
|
||||
CLASS_NAME: "OpenLayers.Control"
|
||||
});
|
||||
|
||||
/**
|
||||
* Constant: OpenLayers.Control.TYPE_BUTTON
|
||||
*/
|
||||
OpenLayers.Control.TYPE_BUTTON = 1;
|
||||
|
||||
/**
|
||||
* Constant: OpenLayers.Control.TYPE_TOGGLE
|
||||
*/
|
||||
OpenLayers.Control.TYPE_TOGGLE = 2;
|
||||
|
||||
/**
|
||||
* Constant: OpenLayers.Control.TYPE_TOOL
|
||||
*/
|
||||
OpenLayers.Control.TYPE_TOOL = 3;
|
||||
|
||||
@@ -59,10 +59,22 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: click
|
||||
* {Boolean} Use a click handler for selecting/unselecting features.
|
||||
* Default is true.
|
||||
* {Boolean} Use a click handler for selecting/unselecting features. If
|
||||
* both <click> and <box> are set to true, the click handler takes
|
||||
* precedence over the box handler if a box with zero extent was
|
||||
* selected. Default is true.
|
||||
*/
|
||||
click: true,
|
||||
|
||||
/**
|
||||
* APIProperty: single
|
||||
* {Boolean} Tells whether select by click should select a single
|
||||
* feature. If set to false, all matching features are selected.
|
||||
* If set to true, only the best matching feature is selected.
|
||||
* This option has an effect only of the <click> option is set
|
||||
* to true. Default is true.
|
||||
*/
|
||||
single: true,
|
||||
|
||||
/**
|
||||
* APIProperty: clickout
|
||||
@@ -96,7 +108,11 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: box
|
||||
* {Boolean} Allow feature selection by drawing a box.
|
||||
* {Boolean} Allow feature selection by drawing a box. If set to
|
||||
* true set <click> to false to disable the click handler and
|
||||
* rely on the box handler only, even for "zero extent" boxes.
|
||||
* See the description of the <click> option for additional
|
||||
* information. Default is false.
|
||||
*/
|
||||
box: false,
|
||||
|
||||
@@ -209,7 +225,7 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
if(this.click) {
|
||||
this.handlers.click = new OpenLayers.Handler.Click(this,
|
||||
{click: this.selectSingle}, this.handlerOptions.click || {});
|
||||
{click: this.selectClick}, this.handlerOptions.click || {});
|
||||
}
|
||||
|
||||
if(this.box) {
|
||||
@@ -268,20 +284,17 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: selectSingle
|
||||
* Method: selectClick
|
||||
* Called on click
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*/
|
||||
selectSingle: function(evt) {
|
||||
// Set the cursor to "wait" to tell the user we're working on their click.
|
||||
OpenLayers.Element.addClass(this.map.viewPortDiv, "olCursorWait");
|
||||
|
||||
selectClick: function(evt) {
|
||||
var bounds = this.pixelToBounds(evt.xy);
|
||||
|
||||
this.setModifiers(evt);
|
||||
this.request(bounds, {single: true});
|
||||
this.request(bounds, {single: this.single});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -305,7 +318,11 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
);
|
||||
|
||||
} else {
|
||||
bounds = this.pixelToBounds(position);
|
||||
if(this.click) {
|
||||
// box without extent - let the click handler take care of it
|
||||
return;
|
||||
}
|
||||
bounds = this.pixelToBounds(position);
|
||||
}
|
||||
this.setModifiers(this.handlers.box.dragHandler.evt);
|
||||
this.request(bounds);
|
||||
@@ -331,6 +348,8 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
if (this.hoverResponse) {
|
||||
this.protocol.abort(this.hoverResponse);
|
||||
this.hoverResponse = null;
|
||||
|
||||
OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -355,6 +374,9 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
value: bounds
|
||||
});
|
||||
|
||||
// Set the cursor to "wait" to tell the user we're working.
|
||||
OpenLayers.Element.addClass(this.map.viewPortDiv, "olCursorWait");
|
||||
|
||||
var response = this.protocol.read({
|
||||
maxFeatures: options.single == true ? this.maxFeatures : undefined,
|
||||
filter: filter,
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
*/
|
||||
OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: autoActivate
|
||||
* {Boolean} Activate the control when it is added to a map. Default is
|
||||
* true.
|
||||
*/
|
||||
autoActivate: true,
|
||||
|
||||
/**
|
||||
* APIProperty: intervals
|
||||
* {Array(Float)} A list of possible graticule widths in degrees.
|
||||
@@ -27,8 +34,8 @@ OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: displayInLayerSwitcher
|
||||
* {Boolean} Allows the Graticule control to be switched on and off.
|
||||
* defaults to true.
|
||||
* {Boolean} Allows the Graticule control to be switched on and off by
|
||||
* LayerSwitcher control. Defaults is true.
|
||||
*/
|
||||
displayInLayerSwitcher: true,
|
||||
|
||||
@@ -53,9 +60,10 @@ OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: layerName
|
||||
* {String} the name to be displayed in the layer switcher
|
||||
* {String} The name to be displayed in the layer switcher, default is set
|
||||
* by {<OpenLayers.Lang>}.
|
||||
*/
|
||||
layerName: "Graticule",
|
||||
layerName: null,
|
||||
|
||||
/**
|
||||
* APIProperty: labelled
|
||||
@@ -102,6 +110,8 @@ OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
* to extend the control.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
options.layerName = options.layerName || OpenLayers.i18n("graticule");
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
|
||||
this.labelSymbolizer.stroke = false;
|
||||
@@ -112,6 +122,18 @@ OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
this.labelSymbolizer.labelYOffset = "${yOffset}";
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: destroy
|
||||
*/
|
||||
destroy: function() {
|
||||
this.deactivate();
|
||||
OpenLayers.Control.prototype.destroy.apply(this, arguments);
|
||||
if (this.gratLayer) {
|
||||
this.gratLayer.destroy();
|
||||
this.gratLayer = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: draw
|
||||
*
|
||||
@@ -134,13 +156,36 @@ OpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {
|
||||
visibility: this.visible,
|
||||
displayInLayerSwitcher: this.displayInLayerSwitcher
|
||||
});
|
||||
this.map.addLayer(this.gratLayer);
|
||||
}
|
||||
this.map.events.register('moveend', this, this.update);
|
||||
this.update();
|
||||
return this.div;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: activate
|
||||
*/
|
||||
activate: function() {
|
||||
if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
|
||||
this.map.addLayer(this.gratLayer);
|
||||
this.map.events.register('moveend', this, this.update);
|
||||
this.update();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: deactivate
|
||||
*/
|
||||
deactivate: function() {
|
||||
if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
|
||||
this.map.events.unregister('moveend', this, this.update);
|
||||
this.map.removeLayer(this.gratLayer);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Method: update
|
||||
*
|
||||
|
||||
@@ -179,12 +179,15 @@ OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
|
||||
* geometry - {<OpenLayers.Geometry>} The sketch geometry.
|
||||
*/
|
||||
measurePartial: function(point, geometry) {
|
||||
this.delayedTrigger = window.setTimeout(
|
||||
OpenLayers.Function.bind(function() {
|
||||
this.measure(geometry, "measurepartial");
|
||||
}, this),
|
||||
this.partialDelay
|
||||
);
|
||||
if (geometry.getLength() > 0) {
|
||||
geometry = geometry.clone();
|
||||
this.delayedTrigger = window.setTimeout(
|
||||
OpenLayers.Function.bind(function() {
|
||||
this.measure(geometry, "measurepartial");
|
||||
}, this),
|
||||
this.partialDelay
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,7 +118,7 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* APIProperty: mode
|
||||
* {Integer} Bitfields specifying the modification mode. Defaults to
|
||||
* OpenLayers.Control.ModifyFeature.RESHAPE. To set the mode to a
|
||||
* combination of options, use the | operator. or example, to allow
|
||||
* combination of options, use the | operator. For example, to allow
|
||||
* the control to both resize and rotate features, use the following
|
||||
* syntax
|
||||
* (code)
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
*/
|
||||
OpenLayers.Control.MousePosition = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: autoActivate
|
||||
* {Boolean} Activate the control when it is added to a map. Default is
|
||||
* true.
|
||||
*/
|
||||
autoActivate: true,
|
||||
|
||||
/**
|
||||
* Property: element
|
||||
* {DOMElement}
|
||||
@@ -87,12 +94,38 @@ OpenLayers.Control.MousePosition = OpenLayers.Class(OpenLayers.Control, {
|
||||
* Method: destroy
|
||||
*/
|
||||
destroy: function() {
|
||||
if (this.map) {
|
||||
this.map.events.unregister('mousemove', this, this.redraw);
|
||||
}
|
||||
this.deactivate();
|
||||
OpenLayers.Control.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: activate
|
||||
*/
|
||||
activate: function() {
|
||||
if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
|
||||
this.map.events.register('mousemove', this, this.redraw);
|
||||
this.map.events.register('mouseout', this, this.reset);
|
||||
this.redraw();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: deactivate
|
||||
*/
|
||||
deactivate: function() {
|
||||
if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
|
||||
this.map.events.unregister('mousemove', this, this.redraw);
|
||||
this.map.events.unregister('mouseout', this, this.reset);
|
||||
this.element.innerHTML = "";
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: draw
|
||||
* {DOMElement}
|
||||
@@ -106,7 +139,6 @@ OpenLayers.Control.MousePosition = OpenLayers.Class(OpenLayers.Control, {
|
||||
this.element = this.div;
|
||||
}
|
||||
|
||||
this.redraw();
|
||||
return this.div;
|
||||
},
|
||||
|
||||
@@ -174,16 +206,7 @@ OpenLayers.Control.MousePosition = OpenLayers.Class(OpenLayers.Control, {
|
||||
lonLat.lat.toFixed(digits) +
|
||||
this.suffix;
|
||||
return newHtml;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setMap
|
||||
*/
|
||||
setMap: function() {
|
||||
OpenLayers.Control.prototype.setMap.apply(this, arguments);
|
||||
this.map.events.register( 'mousemove', this, this.redraw);
|
||||
this.map.events.register( 'mouseout', this, this.reset);
|
||||
},
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.MousePosition"
|
||||
});
|
||||
|
||||
@@ -294,7 +294,10 @@ OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, {
|
||||
getState: function() {
|
||||
return {
|
||||
center: this.map.getCenter(),
|
||||
resolution: this.map.getResolution()
|
||||
resolution: this.map.getResolution(),
|
||||
projection: this.map.getProjectionObject(),
|
||||
units: this.map.getProjectionObject().getUnits() ||
|
||||
this.map.units || this.map.baseLayer.units
|
||||
};
|
||||
},
|
||||
|
||||
@@ -306,8 +309,21 @@ OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, {
|
||||
* state - {Object} An object representing the state to restore.
|
||||
*/
|
||||
restore: function(state) {
|
||||
var zoom = this.map.getZoomForResolution(state.resolution);
|
||||
this.map.setCenter(state.center, zoom);
|
||||
var center, zoom;
|
||||
if (this.map.getProjectionObject() == state.projection) {
|
||||
zoom = this.map.getZoomForResolution(state.resolution);
|
||||
center = state.center;
|
||||
} else {
|
||||
center = state.center.clone();
|
||||
center.transform(state.projection, this.map.getProjectionObject());
|
||||
var sourceUnits = state.units;
|
||||
var targetUnits = this.map.getProjectionObject().getUnits() ||
|
||||
this.map.units || this.map.baseLayer.units;
|
||||
var resolutionFactor = sourceUnits && targetUnits ?
|
||||
OpenLayers.INCHES_PER_UNIT[sourceUnits] / OpenLayers.INCHES_PER_UNIT[targetUnits] : 1;
|
||||
zoom = this.map.getZoomForResolution(resolutionFactor*state.resolution);
|
||||
}
|
||||
this.map.setCenter(center, zoom);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -120,6 +120,12 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
resolutionFactor: 1,
|
||||
|
||||
/**
|
||||
* APIProperty: maximized
|
||||
* {Boolean} Start as maximized (visible). Defaults to false.
|
||||
*/
|
||||
maximized: false,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Control.OverviewMap
|
||||
* Create a new overview map
|
||||
@@ -288,7 +294,10 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
|
||||
this.map.events.register('moveend', this, this.update);
|
||||
|
||||
|
||||
if (this.maximized) {
|
||||
this.maximizeControl();
|
||||
}
|
||||
return this.div;
|
||||
},
|
||||
|
||||
|
||||
@@ -32,13 +32,54 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
* APIProperty: defaultControl
|
||||
* {<OpenLayers.Control>} The control which is activated when the control is
|
||||
* activated (turned on), which also happens at instantiation.
|
||||
* If <saveState> is true, <defaultControl> will be nullified after the
|
||||
* first activation of the panel.
|
||||
*/
|
||||
defaultControl: null,
|
||||
defaultControl: null,
|
||||
|
||||
/**
|
||||
* APIProperty: saveState
|
||||
* {Boolean} If set to true, the active state of this panel's controls will
|
||||
* be stored on panel deactivation, and restored on reactivation. Default
|
||||
* is false.
|
||||
*/
|
||||
saveState: false,
|
||||
|
||||
/**
|
||||
* Property: activeState
|
||||
* {Object} stores the active state of this panel's controls.
|
||||
*/
|
||||
activeState: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Control.Panel
|
||||
* Create a new control panel.
|
||||
*
|
||||
*
|
||||
* Each control in the panel is represented by an icon. When clicking
|
||||
* on an icon, the <activateControl> method is called.
|
||||
*
|
||||
* Specific properties for controls on a panel:
|
||||
* type - {Number} One of <OpenLayers.Control.TYPE_TOOL>,
|
||||
* <OpenLayers.Control.TYPE_TOGGLE>, <OpenLayers.Control.TYPE_BUTTON>.
|
||||
* If not provided, <OpenLayers.Control.TYPE_TOOL> is assumed.
|
||||
* title - {string} Text displayed when mouse is over the icon that
|
||||
* represents the control.
|
||||
*
|
||||
* The <OpenLayers.Control.type> of a control determines the behavior when
|
||||
* clicking its icon:
|
||||
* <OpenLayers.Control.TYPE_TOOL> - The control is activated and other
|
||||
* controls of this type in the same panel are deactivated. This is
|
||||
* the default type.
|
||||
* <OpenLayers.Control.TYPE_TOGGLE> - The active state of the control is
|
||||
* toggled.
|
||||
* <OpenLayers.Control.TYPE_BUTTON> - The
|
||||
* <OpenLayers.Control.Button.trigger> method of the control is called,
|
||||
* but its active state is not changed.
|
||||
*
|
||||
* If a control is <OpenLayers.Control.active>, it will be drawn with the
|
||||
* olControl[Name]ItemActive class, otherwise with the
|
||||
* olControl[Name]ItemInactive class.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be used
|
||||
* to extend the control.
|
||||
@@ -46,6 +87,7 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
initialize: function(options) {
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
this.controls = [];
|
||||
this.activeState = {};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -63,7 +105,8 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);
|
||||
this.controls[i].panel_div = null;
|
||||
}
|
||||
}
|
||||
this.activeState = null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -71,11 +114,17 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
activate: function() {
|
||||
if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
|
||||
for(var i=0, len=this.controls.length; i<len; i++) {
|
||||
if (this.controls[i] == this.defaultControl) {
|
||||
this.controls[i].activate();
|
||||
var control;
|
||||
for (var i=0, len=this.controls.length; i<len; i++) {
|
||||
control = this.controls[i];
|
||||
if (control === this.defaultControl ||
|
||||
(this.saveState && this.activeState[control.id])) {
|
||||
control.activate();
|
||||
}
|
||||
}
|
||||
if (this.saveState === true) {
|
||||
this.defaultControl = null;
|
||||
}
|
||||
this.redraw();
|
||||
return true;
|
||||
} else {
|
||||
@@ -88,8 +137,10 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
deactivate: function() {
|
||||
if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
|
||||
for(var i=0, len=this.controls.length; i<len; i++) {
|
||||
this.controls[i].deactivate();
|
||||
var control;
|
||||
for (var i=0, len=this.controls.length; i<len; i++) {
|
||||
control = this.controls[i];
|
||||
this.activeState[control.id] = control.deactivate();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
@@ -105,15 +156,7 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
draw: function() {
|
||||
OpenLayers.Control.prototype.draw.apply(this, arguments);
|
||||
for (var i=0, len=this.controls.length; i<len; i++) {
|
||||
this.map.addControl(this.controls[i]);
|
||||
this.controls[i].deactivate();
|
||||
this.controls[i].events.on({
|
||||
"activate": this.redraw,
|
||||
"deactivate": this.redraw,
|
||||
scope: this
|
||||
});
|
||||
}
|
||||
this.addControlsToMap(this.controls);
|
||||
return this.div;
|
||||
},
|
||||
|
||||
@@ -121,6 +164,11 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
* Method: redraw
|
||||
*/
|
||||
redraw: function() {
|
||||
if (this.div.children.length>0) {
|
||||
for (var l=this.div.children.length, i=l-1 ; i>=0 ; i--) {
|
||||
this.div.removeChild(this.div.children[i]);
|
||||
}
|
||||
}
|
||||
this.div.innerHTML = "";
|
||||
if (this.active) {
|
||||
for (var i=0, len=this.controls.length; i<len; i++) {
|
||||
@@ -137,7 +185,9 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIMethod: activateControl
|
||||
*
|
||||
* This method is called when the user click on the icon representing a
|
||||
* control in the panel.
|
||||
*
|
||||
* Parameters:
|
||||
* control - {<OpenLayers.Control>}
|
||||
*/
|
||||
@@ -157,11 +207,12 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
this.redraw();
|
||||
return;
|
||||
}
|
||||
var c;
|
||||
for (var i=0, len=this.controls.length; i<len; i++) {
|
||||
if (this.controls[i] != control) {
|
||||
if (this.controls[i].type != OpenLayers.Control.TYPE_TOGGLE) {
|
||||
this.controls[i].deactivate();
|
||||
}
|
||||
c = this.controls[i];
|
||||
if (c != control &&
|
||||
(c.type === OpenLayers.Control.TYPE_TOOL || c.type == null)) {
|
||||
c.deactivate();
|
||||
}
|
||||
}
|
||||
control.activate();
|
||||
@@ -174,7 +225,7 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
* Control Panel.
|
||||
*
|
||||
* Parameters:
|
||||
* controls - {<OpenLayers.Control>}
|
||||
* controls - {<OpenLayers.Control>} Controls to add in the panel.
|
||||
*/
|
||||
addControls: function(controls) {
|
||||
if (!(controls instanceof Array)) {
|
||||
@@ -202,19 +253,38 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
|
||||
if (this.map) { // map.addControl() has already been called on the panel
|
||||
for (var i=0, len=controls.length; i<len; i++) {
|
||||
this.map.addControl(controls[i]);
|
||||
controls[i].deactivate();
|
||||
controls[i].events.on({
|
||||
"activate": this.redraw,
|
||||
"deactivate": this.redraw,
|
||||
scope: this
|
||||
});
|
||||
}
|
||||
this.addControlsToMap(controls);
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: addControlsToMap
|
||||
* Only for internal use in draw() and addControls() methods.
|
||||
*
|
||||
* Parameters:
|
||||
* controls - {Array(<OpenLayers.Control>)} Controls to add into map.
|
||||
*/
|
||||
addControlsToMap: function (controls) {
|
||||
var control;
|
||||
for (var i=0, len=controls.length; i<len; i++) {
|
||||
control = controls[i];
|
||||
if (control.autoActivate === true) {
|
||||
control.autoActivate = false;
|
||||
this.map.addControl(control);
|
||||
control.autoActivate = true;
|
||||
} else {
|
||||
this.map.addControl(control);
|
||||
control.deactivate();
|
||||
}
|
||||
control.events.on({
|
||||
"activate": this.redraw,
|
||||
"deactivate": this.redraw,
|
||||
scope: this
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: onClick
|
||||
*/
|
||||
|
||||
569
lib/OpenLayers/Control/SLDSelect.js
Normal file
@@ -0,0 +1,569 @@
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., 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/Layer/WMS/Post.js
|
||||
* @requires OpenLayers/Handler/RegularPolygon.js
|
||||
* @requires OpenLayers/Handler/Polygon.js
|
||||
* @requires OpenLayers/Handler/Path.js
|
||||
* @requires OpenLayers/Handler/Click.js
|
||||
* @requires OpenLayers/Filter/Spatial.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Control.SLDSelect
|
||||
* Perform selections on WMS layers using Styled Layer Descriptor (SLD)
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Control>
|
||||
*/
|
||||
OpenLayers.Control.SLDSelect = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* Constant: EVENT_TYPES
|
||||
* {Array(String)} Supported application event types. Register a listener
|
||||
* for a particular event with the following syntax:
|
||||
* (code)
|
||||
* control.events.register(type, obj, listener);
|
||||
* (end)
|
||||
*
|
||||
* Listeners will be called with a reference to an event object. The
|
||||
* properties of this event depends on exactly what happened.
|
||||
*
|
||||
* Supported control event types (in addition to those from
|
||||
* <OpenLayers.Control>):
|
||||
* selected - Triggered when a selection occurs. Listeners receive an
|
||||
* event with *filters* and *layer* properties. Filters will be an
|
||||
* array of OpenLayers.Filter objects created in order to perform
|
||||
* the particular selection.
|
||||
*/
|
||||
EVENT_TYPES: ["selected"],
|
||||
|
||||
/**
|
||||
* APIProperty: clearOnDeactivate
|
||||
* {Boolean} Should the selection be cleared when the control is
|
||||
* deactivated. Default value is false.
|
||||
*/
|
||||
clearOnDeactivate: false,
|
||||
|
||||
/**
|
||||
* APIProperty: layers
|
||||
* {Array(<OpenLayers.Layer.WMS>)} The WMS layers this control will work
|
||||
* on.
|
||||
*/
|
||||
layers: null,
|
||||
|
||||
/**
|
||||
* Property: callbacks
|
||||
* {Object} The functions that are sent to the handler for callback
|
||||
*/
|
||||
callbacks: null,
|
||||
|
||||
/**
|
||||
* APIProperty: selectionSymbolizer
|
||||
* {Object} Determines the styling of the selected objects. Default is
|
||||
* a selection in red.
|
||||
*/
|
||||
selectionSymbolizer: {
|
||||
'Polygon': {fillColor: '#FF0000', stroke: false},
|
||||
'Line': {strokeColor: '#FF0000', strokeWidth: 2},
|
||||
'Point': {graphicName: 'square', fillColor: '#FF0000', pointRadius: 5}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIProperty: layerOptions
|
||||
* {Object} The options to apply to the selection layer, by default the
|
||||
* selection layer will be kept out of the layer switcher.
|
||||
*/
|
||||
layerOptions: null,
|
||||
|
||||
/**
|
||||
* APIProperty: handlerOptions
|
||||
* {Object} Used to set non-default properties on the control's handler
|
||||
*/
|
||||
handlerOptions: null,
|
||||
|
||||
/**
|
||||
* APIProperty: sketchStyle
|
||||
* {<OpenLayers.Style>|Object} Style or symbolizer to use for the sketch
|
||||
* handler. The recommended way of styling the sketch layer, however, is
|
||||
* to configure an <OpenLayers.StyleMap> in the layerOptions of the
|
||||
* <handlerOptions>:
|
||||
*
|
||||
* (code)
|
||||
* new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Path, {
|
||||
* handlerOptions: {
|
||||
* layerOptions: {
|
||||
* styleMap: new OpenLayers.StyleMap({
|
||||
* "default": {strokeColor: "yellow"}
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* (end)
|
||||
*/
|
||||
sketchStyle: null,
|
||||
|
||||
/**
|
||||
* APIProperty: wfsCache
|
||||
* {Object} Cache to use for storing parsed results from
|
||||
* <OpenLayers.Format.WFSDescribeFeatureType.read>. If not provided,
|
||||
* these will be cached on the prototype.
|
||||
*/
|
||||
wfsCache: {},
|
||||
|
||||
/**
|
||||
* APIProperty: layerCache
|
||||
* {Object} Cache to use for storing references to the selection layers.
|
||||
* Normally each source layer will have exactly 1 selection layer of
|
||||
* type OpenLayers.Layer.WMS.Post. If not provided, layers will
|
||||
* be cached on the prototype. Note that if <clearOnDeactivate> is
|
||||
* true, the layer will no longer be cached after deactivating the
|
||||
* control.
|
||||
*/
|
||||
layerCache: {},
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Control.SLDSelect
|
||||
* Create a new control for selecting features in WMS layers using
|
||||
* Styled Layer Descriptor (SLD).
|
||||
*
|
||||
* Parameters:
|
||||
* handler - {<OpenLayers.Class>} A sketch handler class. This determines
|
||||
* the type of selection, e.g. box (<OpenLayers.Handler.Box>), point
|
||||
* (<OpenLayers.Handler.Point>), path (<OpenLayers.Handler.Path>) or
|
||||
* polygon (<OpenLayers.Handler.Polygon>) selection. To use circle
|
||||
* type selection, use <OpenLayers.Handler.RegularPolygon> and pass
|
||||
* the number of desired sides (e.g. 40) as "sides" property to the
|
||||
* <handlerOptions>.
|
||||
* options - {Object} An object containing all configuration properties for
|
||||
* the control.
|
||||
*
|
||||
* Valid options:
|
||||
* layers - Array({<OpenLayers.Layer.WMS>}) The layers to perform the
|
||||
* selection on.
|
||||
*/
|
||||
initialize: function(handler, options) {
|
||||
// concatenate events specific to this control with those from the base
|
||||
this.EVENT_TYPES =
|
||||
OpenLayers.Control.SLDSelect.prototype.EVENT_TYPES.concat(
|
||||
OpenLayers.Control.prototype.EVENT_TYPES
|
||||
);
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
|
||||
this.callbacks = OpenLayers.Util.extend({done: this.select,
|
||||
click: this.select}, this.callbacks);
|
||||
this.handlerOptions = this.handlerOptions || {};
|
||||
this.layerOptions = OpenLayers.Util.applyDefaults(this.layerOptions, {
|
||||
displayInLayerSwitcher: false
|
||||
});
|
||||
if (this.sketchStyle) {
|
||||
this.handlerOptions.layerOptions = OpenLayers.Util.applyDefaults(
|
||||
this.handlerOptions.layerOptions,
|
||||
{styleMap: new OpenLayers.StyleMap({"default": this.sketchStyle})}
|
||||
);
|
||||
}
|
||||
this.handler = new handler(this, this.callbacks, this.handlerOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: destroy
|
||||
* Take care of things that are not handled in superclass.
|
||||
*/
|
||||
destroy: function() {
|
||||
for (var key in this.layerCache) {
|
||||
delete this.layerCache[key];
|
||||
}
|
||||
for (var key in this.wfsCache) {
|
||||
delete this.wfsCache[key];
|
||||
}
|
||||
OpenLayers.Control.prototype.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: coupleLayerVisiblity
|
||||
* Couple the selection layer and the source layer with respect to
|
||||
* layer visibility. So if the source layer is turned off, the
|
||||
* selection layer is also turned off.
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Object}
|
||||
*/
|
||||
coupleLayerVisiblity: function(evt) {
|
||||
this.setVisibility(evt.object.getVisibility());
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: createSelectionLayer
|
||||
* Creates a "clone" from the source layer in which the selection can
|
||||
* be drawn. This ensures both the source layer and the selection are
|
||||
* visible and not only the selection.
|
||||
*
|
||||
* Parameters:
|
||||
* source - {<OpenLayers.Layer.WMS>} The source layer on which the selection
|
||||
* is performed.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.WMS.Post>} A WMS Post layer since SLD selections can
|
||||
* easily get quite long.
|
||||
*/
|
||||
createSelectionLayer: function(source) {
|
||||
// check if we already have a selection layer for the source layer
|
||||
var selectionLayer;
|
||||
if (!this.layerCache[source.id]) {
|
||||
selectionLayer = new OpenLayers.Layer.WMS.Post(source.name,
|
||||
source.url, source.params,
|
||||
OpenLayers.Util.applyDefaults(
|
||||
this.layerOptions,
|
||||
source.getOptions())
|
||||
);
|
||||
this.layerCache[source.id] = selectionLayer;
|
||||
// make sure the layers are coupled wrt visibility, but only
|
||||
// if they are not displayed in the layer switcher, because in
|
||||
// that case the user cannot control visibility.
|
||||
if (this.layerOptions.displayInLayerSwitcher === false) {
|
||||
source.events.on({
|
||||
"visibilitychanged": this.coupleLayerVisiblity,
|
||||
scope: selectionLayer});
|
||||
}
|
||||
this.map.addLayer(selectionLayer);
|
||||
} else {
|
||||
selectionLayer = this.layerCache[source.id];
|
||||
}
|
||||
return selectionLayer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: createSLD
|
||||
* Create the SLD document for the layer using the supplied filters.
|
||||
*
|
||||
* Parameters:
|
||||
* layer - {<OpenLayers.Layer.WMS>}
|
||||
* filters - Array({<OpenLayers.Filter>}) The filters to be applied.
|
||||
* geometryAttributes - Array({Object}) The geometry attributes of the
|
||||
* layer.
|
||||
*
|
||||
* Returns:
|
||||
* {String} The SLD document generated as a string.
|
||||
*/
|
||||
createSLD: function(layer, filters, geometryAttributes) {
|
||||
var sld = {version: "1.0.0", namedLayers: {}};
|
||||
var layerNames = [layer.params.LAYERS].join(",").split(",");
|
||||
for (var i=0, len=layerNames.length; i<len; i++) {
|
||||
var name = layerNames[i];
|
||||
sld.namedLayers[name] = {name: name, userStyles: []};
|
||||
var symbolizer = this.selectionSymbolizer;
|
||||
var geometryAttribute = geometryAttributes[i];
|
||||
if (geometryAttribute.type.indexOf('Polygon') >= 0) {
|
||||
symbolizer = {Polygon: this.selectionSymbolizer['Polygon']};
|
||||
} else if (geometryAttribute.type.indexOf('LineString') >= 0) {
|
||||
symbolizer = {Line: this.selectionSymbolizer['Line']};
|
||||
} else if (geometryAttribute.type.indexOf('Point') >= 0) {
|
||||
symbolizer = {Point: this.selectionSymbolizer['Point']};
|
||||
}
|
||||
var filter = filters[i];
|
||||
sld.namedLayers[name].userStyles.push({name: 'default', rules: [
|
||||
new OpenLayers.Rule({symbolizer: symbolizer,
|
||||
filter: filter,
|
||||
maxScaleDenominator: layer.options.minScale})
|
||||
]});
|
||||
}
|
||||
return new OpenLayers.Format.SLD().write(sld);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: parseDescribeLayer
|
||||
* Parse the SLD WMS DescribeLayer response and issue the corresponding
|
||||
* WFS DescribeFeatureType request
|
||||
*
|
||||
* request - {XMLHttpRequest} The request object.
|
||||
*/
|
||||
parseDescribeLayer: function(request) {
|
||||
var format = new OpenLayers.Format.WMSDescribeLayer();
|
||||
var doc = request.responseXML;
|
||||
if(!doc || !doc.documentElement) {
|
||||
doc = request.responseText;
|
||||
}
|
||||
var describeLayer = format.read(doc);
|
||||
var typeNames = [];
|
||||
var url = null;
|
||||
for (var i=0, len=describeLayer.length; i<len; i++) {
|
||||
// perform a WFS DescribeFeatureType request
|
||||
if (describeLayer[i].owsType == "WFS") {
|
||||
typeNames.push(describeLayer[i].typeName);
|
||||
url = describeLayer[i].owsURL;
|
||||
}
|
||||
}
|
||||
var options = {
|
||||
url: url,
|
||||
params: {
|
||||
SERVICE: "WFS",
|
||||
TYPENAME: typeNames.toString(),
|
||||
REQUEST: "DescribeFeatureType",
|
||||
VERSION: "1.0.0"
|
||||
},
|
||||
callback: function(request) {
|
||||
var format = new OpenLayers.Format.WFSDescribeFeatureType();
|
||||
var doc = request.responseXML;
|
||||
if(!doc || !doc.documentElement) {
|
||||
doc = request.responseText;
|
||||
}
|
||||
var describeFeatureType = format.read(doc);
|
||||
this.control.wfsCache[this.layer.id] = describeFeatureType;
|
||||
this.control._queue && this.control.applySelection();
|
||||
},
|
||||
scope: this
|
||||
};
|
||||
OpenLayers.Request.GET(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getGeometryAttributes
|
||||
* Look up the geometry attributes from the WFS DescribeFeatureType response
|
||||
*
|
||||
* Parameters:
|
||||
* layer - {<OpenLayers.Layer.WMS>} The layer for which to look up the
|
||||
* geometry attributes.
|
||||
*
|
||||
* Returns:
|
||||
* Array({Object}) Array of geometry attributes
|
||||
*/
|
||||
getGeometryAttributes: function(layer) {
|
||||
var result = [];
|
||||
var cache = this.wfsCache[layer.id];
|
||||
for (var i=0, len=cache.featureTypes.length; i<len; i++) {
|
||||
var typeName = cache.featureTypes[i];
|
||||
var properties = typeName.properties;
|
||||
for (var j=0, lenj=properties.length; j < lenj; j++) {
|
||||
var property = properties[j];
|
||||
var type = property.type;
|
||||
if ((type.indexOf('LineString') >= 0) ||
|
||||
(type.indexOf('GeometryAssociationType') >=0) ||
|
||||
(type.indexOf('GeometryPropertyType') >= 0) ||
|
||||
(type.indexOf('Point') >= 0) ||
|
||||
(type.indexOf('Polygon') >= 0) ) {
|
||||
result.push(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: activate
|
||||
* Activate the control. Activating the control will perform a SLD WMS
|
||||
* DescribeLayer request followed by a WFS DescribeFeatureType request
|
||||
* so that the proper symbolizers can be chosen based on the geometry
|
||||
* type.
|
||||
*/
|
||||
activate: function() {
|
||||
var activated = OpenLayers.Control.prototype.activate.call(this);
|
||||
if(activated) {
|
||||
for (var i=0, len=this.layers.length; i<len; i++) {
|
||||
var layer = this.layers[i];
|
||||
if (layer && !this.wfsCache[layer.id]) {
|
||||
var options = {
|
||||
url: layer.url,
|
||||
params: {
|
||||
SERVICE: "WMS",
|
||||
VERSION: layer.params.VERSION,
|
||||
LAYERS: layer.params.LAYERS,
|
||||
REQUEST: "DescribeLayer"
|
||||
},
|
||||
callback: this.parseDescribeLayer,
|
||||
scope: {layer: layer, control: this}
|
||||
};
|
||||
OpenLayers.Request.GET(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
return activated;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: deactivate
|
||||
* Deactivate the control. If clearOnDeactivate is true, remove the
|
||||
* selection layer(s).
|
||||
*/
|
||||
deactivate: function() {
|
||||
var deactivated = OpenLayers.Control.prototype.deactivate.call(this);
|
||||
if(deactivated) {
|
||||
for (var i=0, len=this.layers.length; i<len; i++) {
|
||||
var layer = this.layers[i];
|
||||
if (layer && this.clearOnDeactivate === true) {
|
||||
var layerCache = this.layerCache;
|
||||
var selectionLayer = layerCache[layer.id];
|
||||
if (selectionLayer) {
|
||||
layer.events.un({
|
||||
"visibilitychanged": this.coupleLayerVisiblity,
|
||||
scope: selectionLayer});
|
||||
selectionLayer.destroy();
|
||||
delete layerCache[layer.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return deactivated;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: setLayers
|
||||
* Set the layers on which the selection should be performed. Call the
|
||||
* setLayers method if the layer(s) to be used change and the same
|
||||
* control should be used on a new set of layers.
|
||||
* If the control is already active, it will be active after the new
|
||||
* set of layers is set.
|
||||
*
|
||||
* Parameters:
|
||||
* layers - {Array(<OpenLayers.Layer.WMS>)} The new set of layers on which
|
||||
* the selection should be performed.
|
||||
*/
|
||||
setLayers: function(layers) {
|
||||
if(this.active) {
|
||||
this.deactivate();
|
||||
this.layers = layers;
|
||||
this.activate();
|
||||
} else {
|
||||
this.layers = layers;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: createFilter
|
||||
* Create the filter to be used in the SLD.
|
||||
*
|
||||
* Parameters:
|
||||
* geometryAttribute - {Object} Used to get the name of the geometry
|
||||
* attribute which is needed for constructing the spatial filter.
|
||||
* geometry - {<OpenLayers.Geometry>} The geometry to use.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Filter.Spatial>} The spatial filter created.
|
||||
*/
|
||||
createFilter: function(geometryAttribute, geometry) {
|
||||
var filter = null;
|
||||
if (this.handler instanceof OpenLayers.Handler.RegularPolygon) {
|
||||
// box
|
||||
if (this.handler.irregular === true) {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.BBOX,
|
||||
property: geometryAttribute.name,
|
||||
value: geometry.getBounds()}
|
||||
);
|
||||
} else {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.INTERSECTS,
|
||||
property: geometryAttribute.name,
|
||||
value: geometry}
|
||||
);
|
||||
}
|
||||
} else if (this.handler instanceof OpenLayers.Handler.Polygon) {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.INTERSECTS,
|
||||
property: geometryAttribute.name,
|
||||
value: geometry}
|
||||
);
|
||||
} else if (this.handler instanceof OpenLayers.Handler.Path) {
|
||||
// if source layer is point based, use DWITHIN instead
|
||||
if (geometryAttribute.type.indexOf('Point') >= 0) {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.DWITHIN,
|
||||
property: geometryAttribute.name,
|
||||
distance: this.map.getExtent().getWidth()*0.01 ,
|
||||
distanceUnits: this.map.getUnits(),
|
||||
value: geometry}
|
||||
);
|
||||
} else {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.INTERSECTS,
|
||||
property: geometryAttribute.name,
|
||||
value: geometry}
|
||||
);
|
||||
}
|
||||
} else if (this.handler instanceof OpenLayers.Handler.Click) {
|
||||
if (geometryAttribute.type.indexOf('Polygon') >= 0) {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.INTERSECTS,
|
||||
property: geometryAttribute.name,
|
||||
value: geometry}
|
||||
);
|
||||
} else {
|
||||
filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.DWITHIN,
|
||||
property: geometryAttribute.name,
|
||||
distance: this.map.getExtent().getWidth()*0.01 ,
|
||||
distanceUnits: this.map.getUnits(),
|
||||
value: geometry}
|
||||
);
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: select
|
||||
* When the handler is done, use SLD_BODY on the selection layer to
|
||||
* display the selection in the map.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {Object} or {<OpenLayers.Geometry>}
|
||||
*/
|
||||
select: function(geometry) {
|
||||
this._queue = function() {
|
||||
for (var i=0, len=this.layers.length; i<len; i++) {
|
||||
var layer = this.layers[i];
|
||||
var geometryAttributes = this.getGeometryAttributes(layer);
|
||||
var filters = [];
|
||||
for (var j=0, lenj=geometryAttributes.length; j<lenj; j++) {
|
||||
var geometryAttribute = geometryAttributes[j];
|
||||
if (geometryAttribute !== null) {
|
||||
// from the click handler we will not get an actual
|
||||
// geometry so transform
|
||||
if (!(geometry instanceof OpenLayers.Geometry)) {
|
||||
var point = this.map.getLonLatFromPixel(
|
||||
geometry.xy);
|
||||
geometry = new OpenLayers.Geometry.Point(
|
||||
point.lon, point.lat);
|
||||
}
|
||||
var filter = this.createFilter(geometryAttribute,
|
||||
geometry);
|
||||
if (filter !== null) {
|
||||
filters.push(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectionLayer = this.createSelectionLayer(layer);
|
||||
var sld = this.createSLD(layer, filters, geometryAttributes);
|
||||
|
||||
this.events.triggerEvent("selected", {
|
||||
layer: layer,
|
||||
filters: filters
|
||||
});
|
||||
|
||||
selectionLayer.mergeNewParams({SLD_BODY: sld});
|
||||
delete this._queue;
|
||||
}
|
||||
};
|
||||
this.applySelection();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: applySelection
|
||||
* Checks if all required wfs data is cached, and applies the selection
|
||||
*/
|
||||
applySelection: function() {
|
||||
var canApply = true;
|
||||
for (var i=0, len=this.layers.length; i<len; i++) {
|
||||
if(!this.wfsCache[this.layers[i].id]) {
|
||||
canApply = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
canApply && this._queue.call(this);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.SLDSelect"
|
||||
});
|
||||
@@ -23,6 +23,15 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
element: null,
|
||||
|
||||
/**
|
||||
* APIProperty: geodesic
|
||||
* {Boolean} Use geodesic measurement. Default is false. The recommended
|
||||
* setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
|
||||
* true, the scale will be calculated based on the horizontal size of the
|
||||
* pixel in the center of the map viewport.
|
||||
*/
|
||||
geodesic: false,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Control.Scale
|
||||
*
|
||||
@@ -56,7 +65,19 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, {
|
||||
* Method: updateScale
|
||||
*/
|
||||
updateScale: function() {
|
||||
var scale = this.map.getScale();
|
||||
var scale;
|
||||
if(this.geodesic === true) {
|
||||
var units = this.map.getUnits();
|
||||
if(!units) {
|
||||
return;
|
||||
}
|
||||
var inches = OpenLayers.INCHES_PER_UNIT;
|
||||
scale = (this.map.getGeodesicPixelSize().w || 0.000001) *
|
||||
inches["km"] * OpenLayers.DOTS_PER_INCH;
|
||||
} else {
|
||||
scale = this.map.getScale();
|
||||
}
|
||||
|
||||
if (!scale) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,10 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: geodesic
|
||||
* {Boolean} Use geodesic measurement. Default is false.
|
||||
* {Boolean} Use geodesic measurement. Default is false. The recommended
|
||||
* setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
|
||||
* true, the scale will be calculated based on the horizontal size of the
|
||||
* pixel in the center of the map viewport.
|
||||
*/
|
||||
geodesic: false,
|
||||
|
||||
@@ -165,7 +168,8 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
||||
var maxSizeData = this.maxWidth * res * inches[curMapUnits];
|
||||
var geodesicRatio = 1;
|
||||
if(this.geodesic === true) {
|
||||
var maxSizeGeodesic = this.getGeodesicLength(this.maxWidth);
|
||||
var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||
|
||||
0.000001) * this.maxWidth;
|
||||
var maxSizeKilometers = maxSizeData / inches["km"];
|
||||
geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
|
||||
maxSizeData *= geodesicRatio;
|
||||
@@ -213,26 +217,6 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getGeodesicLength
|
||||
*
|
||||
* Parameters:
|
||||
* pixels - {Number} the pixels to get the geodesic length in meters for.
|
||||
*/
|
||||
getGeodesicLength: function(pixels) {
|
||||
var map = this.map;
|
||||
var centerPx = map.getPixelFromLonLat(map.getCenter());
|
||||
var bottom = map.getLonLatFromPixel(centerPx.add(0, -pixels / 2));
|
||||
var top = map.getLonLatFromPixel(centerPx.add(0, pixels / 2));
|
||||
var source = map.getProjectionObject();
|
||||
var dest = new OpenLayers.Projection("EPSG:4326");
|
||||
if(!source.equals(dest)) {
|
||||
bottom.transform(source, dest);
|
||||
top.transform(source, dest);
|
||||
}
|
||||
return OpenLayers.Util.distVincenty(bottom, top);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.ScaleLine"
|
||||
});
|
||||
|
||||
|
||||
@@ -586,7 +586,7 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setLayer
|
||||
* APIMethod: setLayer
|
||||
* Attach a new layer to the control, overriding any existing layers.
|
||||
*
|
||||
* Parameters:
|
||||
|
||||
@@ -346,12 +346,12 @@ OpenLayers.Control.Split = OpenLayers.Class(OpenLayers.Control, {
|
||||
* {Boolean} The supplied feature was split (and destroyed).
|
||||
*/
|
||||
considerSplit: function(feature) {
|
||||
sourceSplit = false;
|
||||
targetSplit = false;
|
||||
var sourceSplit = false;
|
||||
var targetSplit = false;
|
||||
if(!this.sourceFilter ||
|
||||
this.sourceFilter.evaluate(feature.attributes)) {
|
||||
var features = this.layer && this.layer.features || [];
|
||||
var target, results, result, proceed;
|
||||
var target, results, proceed;
|
||||
var additions = [], removals = [];
|
||||
var mutual = (this.layer === this.source) && this.mutual;
|
||||
var options = {
|
||||
|
||||
@@ -47,7 +47,7 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* <OpenLayers.Geometry.Point> object with the new center of the
|
||||
* transformed feature, the others are Floats with the scale, ratio
|
||||
* or rotation change of the feature since the last transformation.
|
||||
* - *transformcomplete" Triggered after dragging. Listeners receive
|
||||
* - *transformcomplete* Triggered after dragging. Listeners receive
|
||||
* an event object with the transformed *feature*.
|
||||
*/
|
||||
EVENT_TYPES: ["beforesetfeature", "setfeature", "beforetransform",
|
||||
@@ -479,7 +479,6 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
},
|
||||
// transform while dragging
|
||||
onDrag: function(feature, pixel) {
|
||||
var geom = feature.geometry;
|
||||
if(feature === control.box) {
|
||||
control.transformFeature({center: control.center});
|
||||
control.drawHandles();
|
||||
@@ -500,7 +499,7 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
},
|
||||
onComplete: function(feature, pixel) {
|
||||
control.events.triggerEvent("transformcomplete",
|
||||
{feature: feature});
|
||||
{feature: control.feature});
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -567,7 +566,7 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
geom._handle = null;
|
||||
geom._rotationHandle && geom._rotationHandle.destroy();
|
||||
geom._rotationHandle = null;
|
||||
};
|
||||
}
|
||||
this.box.destroy();
|
||||
this.box = null;
|
||||
this.layer = null;
|
||||
|
||||
@@ -149,6 +149,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
* beforegetfeatureinfo - Triggered before the request is sent.
|
||||
* The event object has an *xy* property with the position of the
|
||||
* mouse click or hover event that triggers the request.
|
||||
* nogetfeatureinfo - no queryable layers were found.
|
||||
* getfeatureinfo - Triggered when a GetFeatureInfo response is received.
|
||||
* The event object has a *text* property with the body of the
|
||||
* response (String), a *features* property with an array of the
|
||||
@@ -159,7 +160,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
* layers, *text* and *request* will only contain the response body
|
||||
* and request object of the last request.
|
||||
*/
|
||||
EVENT_TYPES: ["beforegetfeatureinfo", "getfeatureinfo"],
|
||||
EVENT_TYPES: ["beforegetfeatureinfo", "nogetfeatureinfo", "getfeatureinfo"],
|
||||
|
||||
/**
|
||||
* Constructor: <OpenLayers.Control.WMSGetFeatureInfo>
|
||||
@@ -424,6 +425,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
request: function(clickPosition, options) {
|
||||
var layers = this.findLayers();
|
||||
if(layers.length == 0) {
|
||||
this.events.triggerEvent("nogetfeatureinfo");
|
||||
// Reset the cursor.
|
||||
OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
|
||||
return;
|
||||
@@ -433,10 +435,10 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
if(this.drillDown === false) {
|
||||
var wmsOptions = this.buildWMSOptions(this.url, layers,
|
||||
clickPosition, layers[0].params.FORMAT);
|
||||
var response = OpenLayers.Request.GET(wmsOptions);
|
||||
var request = OpenLayers.Request.GET(wmsOptions);
|
||||
|
||||
if (options.hover === true) {
|
||||
this.hoverRequest = response.priv;
|
||||
this.hoverRequest = request;
|
||||
}
|
||||
} else {
|
||||
this._requestCount = 0;
|
||||
@@ -516,18 +518,6 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setMap
|
||||
* Set the map property for the control.
|
||||
*
|
||||
* Parameters:
|
||||
* map - {<OpenLayers.Map>}
|
||||
*/
|
||||
setMap: function(map) {
|
||||
this.handler.setMap(map);
|
||||
OpenLayers.Control.prototype.setMap.apply(this, arguments);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.WMSGetFeatureInfo"
|
||||
});
|
||||
|
||||
441
lib/OpenLayers/Control/WMTSGetFeatureInfo.js
Normal file
@@ -0,0 +1,441 @@
|
||||
/* Copyright (c) 2006-2008 MetaCarta, Inc., 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/Click.js
|
||||
* @requires OpenLayers/Handler/Hover.js
|
||||
* @requires OpenLayers/Request.js
|
||||
* @requires OpenLayers/Format/WMSGetFeatureInfo.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Control.WMTSGetFeatureInfo
|
||||
* The WMTSGetFeatureInfo control uses a WMTS query to get information about a
|
||||
* point on the map. The information may be in a display-friendly format
|
||||
* such as HTML, or a machine-friendly format such as GML, depending on the
|
||||
* server's capabilities and the client's configuration. This control
|
||||
* handles click or hover events, attempts to parse the results using an
|
||||
* OpenLayers.Format, and fires a 'getfeatureinfo' event for each layer
|
||||
* queried.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Control>
|
||||
*/
|
||||
OpenLayers.Control.WMTSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: hover
|
||||
* {Boolean} Send GetFeatureInfo requests when mouse stops moving.
|
||||
* Default is false.
|
||||
*/
|
||||
hover: false,
|
||||
|
||||
/**
|
||||
* Property: requestEncoding
|
||||
* {String} One of "KVP" or "REST". Only KVP encoding is supported at this
|
||||
* time.
|
||||
*/
|
||||
requestEncoding: "KVP",
|
||||
|
||||
/**
|
||||
* APIProperty: drillDown
|
||||
* {Boolean} Drill down over all WMTS layers in the map. When
|
||||
* using drillDown mode, hover is not possible. A getfeatureinfo event
|
||||
* will be fired for each layer queried.
|
||||
*/
|
||||
drillDown: false,
|
||||
|
||||
/**
|
||||
* APIProperty: maxFeatures
|
||||
* {Integer} Maximum number of features to return from a WMTS query. This
|
||||
* sets the feature_count parameter on WMTS GetFeatureInfo
|
||||
* requests.
|
||||
*/
|
||||
maxFeatures: 10,
|
||||
|
||||
/** APIProperty: clickCallback
|
||||
* {String} The click callback to register in the
|
||||
* {<OpenLayers.Handler.Click>} object created when the hover
|
||||
* option is set to false. Default is "click".
|
||||
*/
|
||||
clickCallback: "click",
|
||||
|
||||
/**
|
||||
* Property: layers
|
||||
* {Array(<OpenLayers.Layer.WMTS>)} The layers to query for feature info.
|
||||
* If omitted, all map WMTS layers will be considered.
|
||||
*/
|
||||
layers: null,
|
||||
|
||||
/**
|
||||
* APIProperty: queryVisible
|
||||
* {Boolean} Filter out hidden layers when searching the map for layers to
|
||||
* query. Default is true.
|
||||
*/
|
||||
queryVisible: true,
|
||||
|
||||
/**
|
||||
* Property: infoFormat
|
||||
* {String} The mimetype to request from the server
|
||||
*/
|
||||
infoFormat: 'text/html',
|
||||
|
||||
/**
|
||||
* Property: vendorParams
|
||||
* {Object} Additional parameters that will be added to the request, for
|
||||
* WMTS implementations that support them. This could e.g. look like
|
||||
* (start code)
|
||||
* {
|
||||
* radius: 5
|
||||
* }
|
||||
* (end)
|
||||
*/
|
||||
vendorParams: {},
|
||||
|
||||
/**
|
||||
* Property: format
|
||||
* {<OpenLayers.Format>} A format for parsing GetFeatureInfo responses.
|
||||
* Default is <OpenLayers.Format.WMSGetFeatureInfo>.
|
||||
*/
|
||||
format: null,
|
||||
|
||||
/**
|
||||
* Property: formatOptions
|
||||
* {Object} Optional properties to set on the format (if one is not provided
|
||||
* in the <format> property.
|
||||
*/
|
||||
formatOptions: null,
|
||||
|
||||
/**
|
||||
* APIProperty: handlerOptions
|
||||
* {Object} Additional options for the handlers used by this control, e.g.
|
||||
* (start code)
|
||||
* {
|
||||
* "click": {delay: 100},
|
||||
* "hover": {delay: 300}
|
||||
* }
|
||||
* (end)
|
||||
*/
|
||||
handlerOptions: null,
|
||||
|
||||
/**
|
||||
* Property: handler
|
||||
* {Object} Reference to the <OpenLayers.Handler> for this control
|
||||
*/
|
||||
handler: null,
|
||||
|
||||
/**
|
||||
* Property: hoverRequest
|
||||
* {<OpenLayers.Request>} contains the currently running hover request
|
||||
* (if any).
|
||||
*/
|
||||
hoverRequest: null,
|
||||
|
||||
/**
|
||||
* Constant: EVENT_TYPES
|
||||
*
|
||||
* Supported event types (in addition to those from <OpenLayers.Control>):
|
||||
* beforegetfeatureinfo - Triggered before each request is sent.
|
||||
* The event object has an *xy* property with the position of the
|
||||
* mouse click or hover event that triggers the request and a *layer*
|
||||
* property referencing the layer about to be queried. If a listener
|
||||
* returns false, the request will not be issued.
|
||||
* getfeatureinfo - Triggered when a GetFeatureInfo response is received.
|
||||
* The event object has a *text* property with the body of the
|
||||
* response (String), a *features* property with an array of the
|
||||
* parsed features, an *xy* property with the position of the mouse
|
||||
* click or hover event that triggered the request, a *layer* property
|
||||
* referencing the layer queried and a *request* property with the
|
||||
* request itself. If drillDown is set to true, one event will be fired
|
||||
* for each layer queried.
|
||||
* exception - Triggered when a GetFeatureInfo request fails (with a
|
||||
* status other than 200) or whenparsing fails. Listeners will receive
|
||||
* an event with *request*, *xy*, and *layer* properties. In the case
|
||||
* of a parsing error, the event will also contain an *error* property.
|
||||
*/
|
||||
EVENT_TYPES: ["beforegetfeatureinfo", "getfeatureinfo", "exception"],
|
||||
|
||||
/**
|
||||
* Property: pending
|
||||
* {Number} The number of pending requests.
|
||||
*/
|
||||
pending: 0,
|
||||
|
||||
/**
|
||||
* Constructor: <OpenLayers.Control.WMTSGetFeatureInfo>
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object}
|
||||
*/
|
||||
initialize: function(options) {
|
||||
// concatenate events specific to vector with those from the base
|
||||
this.EVENT_TYPES =
|
||||
OpenLayers.Control.WMTSGetFeatureInfo.prototype.EVENT_TYPES.concat(
|
||||
OpenLayers.Control.prototype.EVENT_TYPES
|
||||
);
|
||||
|
||||
options = options || {};
|
||||
options.handlerOptions = options.handlerOptions || {};
|
||||
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
|
||||
if (!this.format) {
|
||||
this.format = new OpenLayers.Format.WMSGetFeatureInfo(
|
||||
options.formatOptions
|
||||
);
|
||||
}
|
||||
|
||||
if (this.drillDown === true) {
|
||||
this.hover = false;
|
||||
}
|
||||
|
||||
if (this.hover) {
|
||||
this.handler = new OpenLayers.Handler.Hover(
|
||||
this, {
|
||||
move: this.cancelHover,
|
||||
pause: this.getInfoForHover
|
||||
},
|
||||
OpenLayers.Util.extend(
|
||||
this.handlerOptions.hover || {}, {delay: 250}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
var callbacks = {};
|
||||
callbacks[this.clickCallback] = this.getInfoForClick;
|
||||
this.handler = new OpenLayers.Handler.Click(
|
||||
this, callbacks, this.handlerOptions.click || {}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: activate
|
||||
* Activates the control.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was effectively activated.
|
||||
*/
|
||||
activate: function () {
|
||||
if (!this.active) {
|
||||
this.handler.activate();
|
||||
}
|
||||
return OpenLayers.Control.prototype.activate.apply(
|
||||
this, arguments
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: deactivate
|
||||
* Deactivates the control.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was effectively deactivated.
|
||||
*/
|
||||
deactivate: function () {
|
||||
return OpenLayers.Control.prototype.deactivate.apply(
|
||||
this, arguments
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getInfoForClick
|
||||
* Called on click
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*/
|
||||
getInfoForClick: function(evt) {
|
||||
this.request(evt.xy, {});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getInfoForHover
|
||||
* Pause callback for the hover handler
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Object}
|
||||
*/
|
||||
getInfoForHover: function(evt) {
|
||||
this.request(evt.xy, {hover: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: cancelHover
|
||||
* Cancel callback for the hover handler
|
||||
*/
|
||||
cancelHover: function() {
|
||||
if (this.hoverRequest) {
|
||||
--this.pending;
|
||||
if (this.pending <= 0) {
|
||||
OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
|
||||
this.pending = 0;
|
||||
}
|
||||
this.hoverRequest.abort();
|
||||
this.hoverRequest = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: findLayers
|
||||
* Internal method to get the layers, independent of whether we are
|
||||
* inspecting the map or using a client-provided array
|
||||
*/
|
||||
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.WMTS &&
|
||||
layer.requestEncoding === this.requestEncoding &&
|
||||
(!this.queryVisible || layer.getVisibility())) {
|
||||
layers.push(layer);
|
||||
if (!this.drillDown || this.hover) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: buildRequestOptions
|
||||
* Build an object with the relevant options for the GetFeatureInfo request.
|
||||
*
|
||||
* Parameters:
|
||||
* layer - {<OpenLayers.Layer.WMTS>} A WMTS layer.
|
||||
* xy - {<OpenLayers.Pixel>} The position on the map where the
|
||||
* mouse event occurred.
|
||||
*/
|
||||
buildRequestOptions: function(layer, xy) {
|
||||
var loc = this.map.getLonLatFromPixel(xy);
|
||||
var getTileUrl = layer.getURL(
|
||||
new OpenLayers.Bounds(loc.lon, loc.lat, loc.lon, loc.lat)
|
||||
);
|
||||
var params = OpenLayers.Util.getParameters(getTileUrl);
|
||||
var tileInfo = layer.getTileInfo(loc);
|
||||
OpenLayers.Util.extend(params, {
|
||||
service: "WMTS",
|
||||
version: layer.version,
|
||||
request: "GetFeatureInfo",
|
||||
infoFormat: this.infoFormat,
|
||||
i: tileInfo.i,
|
||||
j: tileInfo.j
|
||||
});
|
||||
OpenLayers.Util.applyDefaults(params, this.vendorParams);
|
||||
return {
|
||||
url: layer.url instanceof Array ? layer.url[0] : layer.url,
|
||||
params: OpenLayers.Util.upperCaseObject(params),
|
||||
callback: function(request) {
|
||||
this.handleResponse(xy, request, layer);
|
||||
},
|
||||
scope: this
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: request
|
||||
* Sends a GetFeatureInfo request to the WMTS
|
||||
*
|
||||
* Parameters:
|
||||
* xy - {<OpenLayers.Pixel>} The position on the map where the mouse event
|
||||
* occurred.
|
||||
* options - {Object} additional options for this method.
|
||||
*
|
||||
* Valid options:
|
||||
* - *hover* {Boolean} true if we do the request for the hover handler
|
||||
*/
|
||||
request: function(xy, options) {
|
||||
options = options || {};
|
||||
var layers = this.findLayers();
|
||||
if (layers.length > 0) {
|
||||
var issue, layer;
|
||||
for (var i=0, len=layers.length; i<len; i++) {
|
||||
layer = layers[i];
|
||||
issue = this.events.triggerEvent("beforegetfeatureinfo", {
|
||||
xy: xy,
|
||||
layer: layer
|
||||
});
|
||||
if (issue !== false) {
|
||||
++this.pending;
|
||||
var requestOptions = this.buildRequestOptions(layer, xy);
|
||||
var request = OpenLayers.Request.GET(requestOptions);
|
||||
if (options.hover === true) {
|
||||
this.hoverRequest = request;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.pending > 0) {
|
||||
OpenLayers.Element.addClass(this.map.viewPortDiv, "olCursorWait");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: handleResponse
|
||||
* Handler for the GetFeatureInfo response.
|
||||
*
|
||||
* Parameters:
|
||||
* xy - {<OpenLayers.Pixel>} The position on the map where the mouse event
|
||||
* occurred.
|
||||
* request - {XMLHttpRequest} The request object.
|
||||
* layer - {<OpenLayers.Layer.WMTS>} The queried layer.
|
||||
*/
|
||||
handleResponse: function(xy, request, layer) {
|
||||
--this.pending;
|
||||
if (this.pending <= 0) {
|
||||
OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
|
||||
this.pending = 0;
|
||||
}
|
||||
if (request.status && (request.status < 200 || request.status >= 300)) {
|
||||
this.events.triggerEvent("exception", {
|
||||
xy: xy,
|
||||
request: request,
|
||||
layer: layer
|
||||
});
|
||||
} else {
|
||||
var doc = request.responseXML;
|
||||
if (!doc || !doc.documentElement) {
|
||||
doc = request.responseText;
|
||||
}
|
||||
var features, except;
|
||||
try {
|
||||
features = this.format.read(doc);
|
||||
} catch (error) {
|
||||
except = true;
|
||||
this.events.triggerEvent("exception", {
|
||||
xy: xy,
|
||||
request: request,
|
||||
error: error,
|
||||
layer: layer
|
||||
});
|
||||
}
|
||||
if (!except) {
|
||||
this.events.triggerEvent("getfeatureinfo", {
|
||||
text: request.responseText,
|
||||
features: features,
|
||||
request: request,
|
||||
xy: xy,
|
||||
layer: layer
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setMap
|
||||
* Set the map property for the control.
|
||||
*
|
||||
* Parameters:
|
||||
* map - {<OpenLayers.Map>}
|
||||
*/
|
||||
setMap: function(map) {
|
||||
this.handler.setMap(map);
|
||||
OpenLayers.Control.prototype.setMap.apply(this, arguments);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.WMTSGetFeatureInfo"
|
||||
});
|
||||
@@ -42,8 +42,8 @@ OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
|
||||
|
||||
/**
|
||||
* APIProperty: attributes
|
||||
* {Object} This object holds arbitrary properties that describe the
|
||||
* feature.
|
||||
* {Object} This object holds arbitrary, serializable properties that
|
||||
* describe the feature.
|
||||
*/
|
||||
attributes: null,
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ OpenLayers.Filter = OpenLayers.Class({
|
||||
* subclasses.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} Context to use in evaluating the filter.
|
||||
* context - {Object} Context to use in evaluating the filter. If a vector
|
||||
* feature is provided, the feature.attributes will be used as context.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The filter applies.
|
||||
|
||||
@@ -93,20 +93,23 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, {
|
||||
|
||||
/**
|
||||
* APIMethod: evaluate
|
||||
* Evaluates this filter in a specific context. Should be implemented by
|
||||
* subclasses.
|
||||
* Evaluates this filter in a specific context.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} Context to use in evaluating the filter.
|
||||
* context - {Object} Context to use in evaluating the filter. If a vector
|
||||
* feature is provided, the feature.attributes will be used as context.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The filter applies.
|
||||
*/
|
||||
evaluate: function(context) {
|
||||
if (context instanceof OpenLayers.Feature.Vector) {
|
||||
context = context.attributes;
|
||||
}
|
||||
var result = false;
|
||||
var got = context[this.property];
|
||||
switch(this.type) {
|
||||
case OpenLayers.Filter.Comparison.EQUAL_TO:
|
||||
var got = context[this.property];
|
||||
var exp = this.value;
|
||||
if(!this.matchCase &&
|
||||
typeof got == "string" && typeof exp == "string") {
|
||||
@@ -116,7 +119,6 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, {
|
||||
}
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:
|
||||
var got = context[this.property];
|
||||
var exp = this.value;
|
||||
if(!this.matchCase &&
|
||||
typeof got == "string" && typeof exp == "string") {
|
||||
@@ -126,24 +128,24 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, {
|
||||
}
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.LESS_THAN:
|
||||
result = context[this.property] < this.value;
|
||||
result = got < this.value;
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.GREATER_THAN:
|
||||
result = context[this.property] > this.value;
|
||||
result = got > this.value;
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:
|
||||
result = context[this.property] <= this.value;
|
||||
result = got <= this.value;
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:
|
||||
result = context[this.property] >= this.value;
|
||||
result = got >= this.value;
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.BETWEEN:
|
||||
result = (context[this.property] >= this.lowerBoundary) &&
|
||||
(context[this.property] <= this.upperBoundary);
|
||||
result = (got >= this.lowerBoundary) &&
|
||||
(got <= this.upperBoundary);
|
||||
break;
|
||||
case OpenLayers.Filter.Comparison.LIKE:
|
||||
var regexp = new RegExp(this.value, "gi");
|
||||
result = regexp.test(context[this.property]);
|
||||
result = regexp.test(got);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -58,11 +58,12 @@ OpenLayers.Filter.Logical = OpenLayers.Class(OpenLayers.Filter, {
|
||||
|
||||
/**
|
||||
* APIMethod: evaluate
|
||||
* Evaluates this filter in a specific context. Should be implemented by
|
||||
* subclasses.
|
||||
* Evaluates this filter in a specific context.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} Context to use in evaluating the filter.
|
||||
* context - {Object} Context to use in evaluating the filter. A vector
|
||||
* feature may also be provided to evaluate feature attributes in
|
||||
* comparison filters or geometries in spatial filters.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The filter applies.
|
||||
|
||||
@@ -221,7 +221,9 @@ OpenLayers.Format.ArcXML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
}
|
||||
}
|
||||
|
||||
if (!arcNode) {
|
||||
// in Safari, arcNode will be there but will have a child named
|
||||
// parsererror
|
||||
if (!arcNode || arcNode.firstChild.nodeName === 'parsererror') {
|
||||
var error, source;
|
||||
try {
|
||||
error = data.firstChild.nodeValue;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright to be assigned to OpenLayers project
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @requires OpenLayers/Format/CSWGetRecords.js
|
||||
* @requires OpenLayers/Format/Filter/v1_0_0.js
|
||||
* @requires OpenLayers/Format/Filter/v1_1_0.js
|
||||
* @requires OpenLayers/Format/OWSCommon/v1_0_0.js
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -118,6 +119,17 @@ OpenLayers.Format.CSWGetRecords.v2_0_2 = OpenLayers.Class(OpenLayers.Format.XML,
|
||||
*/
|
||||
Query: null,
|
||||
|
||||
/**
|
||||
* Property: regExes
|
||||
* Compiled regular expressions for manipulating strings.
|
||||
*/
|
||||
regExes: {
|
||||
trimSpace: (/^\s*|\s*$/g),
|
||||
removeSpace: (/\s*/g),
|
||||
splitSpace: (/\s+/),
|
||||
trimComma: (/\s*,\s*/g)
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.CSWGetRecords.v2_0_2
|
||||
* A class for parsing and generating CSWGetRecords v2.0.2 transactions.
|
||||
@@ -249,53 +261,24 @@ OpenLayers.Format.CSWGetRecords.v2_0_2 = OpenLayers.Class(OpenLayers.Format.XML,
|
||||
obj[name].push(this.getChildValue(node));
|
||||
}
|
||||
},
|
||||
"ows": {
|
||||
"WGS84BoundingBox": function(node, obj) {
|
||||
// LowerCorner = "min_x min_y"
|
||||
// UpperCorner = "max_x max_y"
|
||||
if (!(obj.BoundingBox instanceof Array)) {
|
||||
obj.BoundingBox = new Array();
|
||||
}
|
||||
//this.readChildNodes(node, bbox);
|
||||
var lc = this.getChildValue(
|
||||
this.getElementsByTagNameNS(
|
||||
node,
|
||||
this.namespaces["ows"],
|
||||
"LowerCorner"
|
||||
)[0]
|
||||
).split(' ', 2);
|
||||
var uc = this.getChildValue(
|
||||
this.getElementsByTagNameNS(
|
||||
node,
|
||||
this.namespaces["ows"],
|
||||
"UpperCorner"
|
||||
)[0]
|
||||
).split(' ', 2);
|
||||
|
||||
var boundingBox = {
|
||||
value: [
|
||||
parseFloat(lc[0]),
|
||||
parseFloat(lc[1]),
|
||||
parseFloat(uc[0]),
|
||||
parseFloat(uc[1])
|
||||
]
|
||||
};
|
||||
// store boundingBox attributes
|
||||
var attrs = node.attributes;
|
||||
for(var i=0, len=attrs.length; i<len; ++i) {
|
||||
boundingBox[attrs[i].name] = attrs[i].nodeValue;
|
||||
}
|
||||
obj.BoundingBox.push(boundingBox);
|
||||
},
|
||||
|
||||
"ows": OpenLayers.Util.applyDefaults({
|
||||
"BoundingBox": function(node, obj) {
|
||||
// FIXME: We consider that BoundingBox is the same as WGS84BoundingBox
|
||||
// LowerCorner = "min_x min_y"
|
||||
// UpperCorner = "max_x max_y"
|
||||
// It should normally depend on the projection
|
||||
this.readers['ows']['WGS84BoundingBox'].apply(this, [node, obj]);
|
||||
if (obj.bounds) {
|
||||
obj.BoundingBox = [{crs: obj.projection, value:
|
||||
[
|
||||
obj.bounds.left,
|
||||
obj.bounds.bottom,
|
||||
obj.bounds.right,
|
||||
obj.bounds.top
|
||||
]
|
||||
}];
|
||||
delete obj.projection;
|
||||
delete obj.bounds;
|
||||
}
|
||||
OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"]["BoundingBox"].apply(
|
||||
this, arguments);
|
||||
}
|
||||
}
|
||||
}, OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"])
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
333
lib/OpenLayers/Format/Context.js
Normal file
@@ -0,0 +1,333 @@
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.Context
|
||||
* Base class for both Format.WMC and Format.OWSContext
|
||||
*/
|
||||
OpenLayers.Format.Context = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: version
|
||||
* {String} Specify a version string if one is known.
|
||||
*/
|
||||
version: null,
|
||||
|
||||
/**
|
||||
* Property: layerOptions
|
||||
* {Object} Default options for layers created by the parser. These
|
||||
* options are overridden by the options which are read from the
|
||||
* capabilities document.
|
||||
*/
|
||||
layerOptions: null,
|
||||
|
||||
/**
|
||||
* Property: layerParams
|
||||
* {Object} Default parameters for layers created by the parser. This
|
||||
* can be used e.g. to override DEFAULT_PARAMS for
|
||||
* OpenLayers.Layer.WMS.
|
||||
*/
|
||||
layerParams: null,
|
||||
|
||||
/**
|
||||
* Property: parser
|
||||
* {Object} Instance of the versioned parser. Cached for multiple read and
|
||||
* write calls of the same version.
|
||||
*/
|
||||
parser: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.Context
|
||||
* Create a new parser for Context documents.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Util.extend(this, options);
|
||||
this.options = options;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Read Context data from a string, and return an object with map
|
||||
* properties and a list of layers.
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
* options - {Object} The options object must contain a map property. If
|
||||
* the map property is a string, it must be the id of a dom element
|
||||
* where the new map will be placed. If the map property is an
|
||||
* <OpenLayers.Map>, the layers from the context document will be added
|
||||
* to the map.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} A map based on the context.
|
||||
*/
|
||||
read: function(data, options) {
|
||||
if(typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
var root = data.documentElement;
|
||||
var version = this.version;
|
||||
if(!version) {
|
||||
version = root.getAttribute("version");
|
||||
}
|
||||
var parser = this.getParser(version);
|
||||
var context = parser.read(data, options);
|
||||
var map;
|
||||
if(options && options.map) {
|
||||
this.context = context;
|
||||
if(options.map instanceof OpenLayers.Map) {
|
||||
map = this.mergeContextToMap(context, options.map);
|
||||
} else {
|
||||
var mapOptions = options.map;
|
||||
if(OpenLayers.Util.isElement(mapOptions) ||
|
||||
typeof mapOptions == "string") {
|
||||
// we assume mapOptions references a div
|
||||
// element
|
||||
mapOptions = {div: mapOptions};
|
||||
}
|
||||
map = this.contextToMap(context, mapOptions);
|
||||
}
|
||||
} else {
|
||||
// not documented as part of the API, provided as a non-API option
|
||||
map = context;
|
||||
}
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getLayerFromContext
|
||||
* Create a WMS layer from a layerContext object.
|
||||
*
|
||||
* Parameters:
|
||||
* layerContext - {Object} An object representing a WMS layer.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.WMS>} A WMS layer.
|
||||
*/
|
||||
getLayerFromContext: function(layerContext) {
|
||||
var i, len;
|
||||
// fill initial options object from layerContext
|
||||
var options = {
|
||||
queryable: layerContext.queryable, //keep queryable for api compatibility
|
||||
visibility: layerContext.visibility,
|
||||
maxExtent: layerContext.maxExtent,
|
||||
metadata: OpenLayers.Util.applyDefaults(layerContext.metadata,
|
||||
{styles: layerContext.styles}),
|
||||
numZoomLevels: layerContext.numZoomLevels,
|
||||
units: layerContext.units,
|
||||
isBaseLayer: layerContext.isBaseLayer,
|
||||
opacity: layerContext.opacity,
|
||||
displayInLayerSwitcher: layerContext.displayInLayerSwitcher,
|
||||
singleTile: layerContext.singleTile,
|
||||
tileSize: (layerContext.tileSize) ?
|
||||
new OpenLayers.Size(
|
||||
layerContext.tileSize.width,
|
||||
layerContext.tileSize.height
|
||||
) : undefined,
|
||||
minScale: layerContext.minScale || layerContext.maxScaleDenominator,
|
||||
maxScale: layerContext.maxScale || layerContext.minScaleDenominator
|
||||
};
|
||||
if (this.layerOptions) {
|
||||
OpenLayers.Util.applyDefaults(options, this.layerOptions);
|
||||
}
|
||||
|
||||
var params = {
|
||||
layers: layerContext.name,
|
||||
transparent: layerContext.transparent,
|
||||
version: layerContext.version
|
||||
};
|
||||
if (layerContext.formats && layerContext.formats.length>0) {
|
||||
// set default value for params if current attribute is not positionned
|
||||
params.format = layerContext.formats[0].value;
|
||||
for (i=0, len=layerContext.formats.length; i<len; i++) {
|
||||
var format = layerContext.formats[i];
|
||||
if (format.current == true) {
|
||||
params.format = format.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layerContext.styles && layerContext.styles.length>0) {
|
||||
for (i=0, len=layerContext.styles.length; i<len; i++) {
|
||||
var style = layerContext.styles[i];
|
||||
if (style.current == true) {
|
||||
// three style types to consider
|
||||
// 1) linked SLD
|
||||
// 2) inline SLD
|
||||
// 3) named style
|
||||
if(style.href) {
|
||||
params.sld = style.href;
|
||||
} else if(style.body) {
|
||||
params.sld_body = style.body;
|
||||
} else {
|
||||
params.styles = style.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.layerParams) {
|
||||
OpenLayers.Util.applyDefaults(params, this.layerParams);
|
||||
}
|
||||
|
||||
var layer = null;
|
||||
var service = layerContext.service;
|
||||
if (service == OpenLayers.Format.Context.serviceTypes.WFS) {
|
||||
options.strategies = [new OpenLayers.Strategy.BBOX()];
|
||||
options.protocol = new OpenLayers.Protocol.WFS({
|
||||
url: layerContext.url,
|
||||
// since we do not know featureNS, let the protocol
|
||||
// determine it automagically using featurePrefix
|
||||
featurePrefix: layerContext.name.split(":")[0],
|
||||
featureType: layerContext.name.split(":").pop()
|
||||
});
|
||||
layer = new OpenLayers.Layer.Vector(
|
||||
layerContext.title || layerContext.name,
|
||||
options
|
||||
);
|
||||
} else if (service == OpenLayers.Format.Context.serviceTypes.KML) {
|
||||
// use a vector layer with an HTTP Protcol and a Fixed strategy
|
||||
options.strategies = [new OpenLayers.Strategy.Fixed()];
|
||||
options.protocol = new OpenLayers.Protocol.HTTP({
|
||||
url: layerContext.url,
|
||||
format: new OpenLayers.Format.KML()
|
||||
});
|
||||
layer = new OpenLayers.Layer.Vector(
|
||||
layerContext.title || layerContext.name,
|
||||
options
|
||||
);
|
||||
} else if (service == OpenLayers.Format.Context.serviceTypes.GML) {
|
||||
// use a vector layer with a HTTP Protocol and a Fixed strategy
|
||||
options.strategies = [new OpenLayers.Strategy.Fixed()];
|
||||
options.protocol = new OpenLayers.Protocol.HTTP({
|
||||
url: layerContext.url,
|
||||
format: new OpenLayers.Format.GML()
|
||||
});
|
||||
layer = new OpenLayers.Layer.Vector(
|
||||
layerContext.title || layerContext.name,
|
||||
options
|
||||
);
|
||||
} else if (layerContext.features) {
|
||||
// inline GML or KML features
|
||||
layer = new OpenLayers.Layer.Vector(
|
||||
layerContext.title || layerContext.name,
|
||||
options
|
||||
);
|
||||
layer.addFeatures(layerContext.features);
|
||||
} else if (layerContext.categoryLayer !== true) {
|
||||
layer = new OpenLayers.Layer.WMS(
|
||||
layerContext.title || layerContext.name,
|
||||
layerContext.url,
|
||||
params,
|
||||
options
|
||||
);
|
||||
}
|
||||
return layer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getLayersFromContext
|
||||
* Create an array of layers from an array of layerContext objects.
|
||||
*
|
||||
* Parameters:
|
||||
* layersContext - {Array(Object)} An array of objects representing layers.
|
||||
*
|
||||
* Returns:
|
||||
* {Array(<OpenLayers.Layer>)} An array of layers.
|
||||
*/
|
||||
getLayersFromContext: function(layersContext) {
|
||||
var layers = [];
|
||||
for (var i=0, len=layersContext.length; i<len; i++) {
|
||||
var layer = this.getLayerFromContext(layersContext[i]);
|
||||
if (layer !== null) {
|
||||
layers.push(layer);
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: contextToMap
|
||||
* Create a map given a context object.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} The context object.
|
||||
* options - {Object} Default map options.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} A map based on the context object.
|
||||
*/
|
||||
contextToMap: function(context, options) {
|
||||
options = OpenLayers.Util.applyDefaults({
|
||||
maxExtent: context.maxExtent,
|
||||
projection: context.projection
|
||||
}, options);
|
||||
var map = new OpenLayers.Map(options);
|
||||
map.addLayers(this.getLayersFromContext(context.layersContext));
|
||||
map.setCenter(
|
||||
context.bounds.getCenterLonLat(),
|
||||
map.getZoomForExtent(context.bounds, true)
|
||||
);
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: mergeContextToMap
|
||||
* Add layers from a context object to a map.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} The context object.
|
||||
* map - {<OpenLayers.Map>} The map.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} The same map with layers added.
|
||||
*/
|
||||
mergeContextToMap: function(context, map) {
|
||||
map.addLayers(this.getLayersFromContext(context.layersContext));
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: write
|
||||
* Write a context document given a map.
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {<OpenLayers.Map> | Object} A map or context object.
|
||||
* options - {Object} Optional configuration object.
|
||||
*
|
||||
* Returns:
|
||||
* {String} A context document string.
|
||||
*/
|
||||
write: function(obj, options) {
|
||||
obj = this.toContext(obj);
|
||||
var version = options && options.version;
|
||||
var parser = this.getParser(version);
|
||||
var context = parser.write(obj, options);
|
||||
return context;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.Context"
|
||||
});
|
||||
|
||||
/**
|
||||
* Constant: OpenLayers.Format.Context.serviceTypes
|
||||
* Enumeration for service types
|
||||
*/
|
||||
OpenLayers.Format.Context.serviceTypes = {
|
||||
"WMS": "urn:ogc:serviceType:WMS",
|
||||
"WFS": "urn:ogc:serviceType:WFS",
|
||||
"WCS": "urn:ogc:serviceType:WCS",
|
||||
"GML": "urn:ogc:serviceType:GML",
|
||||
"SLD": "urn:ogc:serviceType:SLD",
|
||||
"FES": "urn:ogc:serviceType:FES",
|
||||
"KML": "urn:ogc:serviceType:KML"
|
||||
};
|
||||
@@ -227,7 +227,7 @@ OpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
var obj = {};
|
||||
this.readChildNodes(node, obj);
|
||||
var value = obj.value;
|
||||
if(!value) {
|
||||
if(value === undefined) {
|
||||
value = this.getChildValue(node);
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -140,7 +140,9 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
// only accept one geometry per feature - look for highest "order"
|
||||
var order = ["MultiPolygon", "Polygon",
|
||||
"MultiLineString", "LineString",
|
||||
"MultiPoint", "Point", "Envelope", "Box"];
|
||||
"MultiPoint", "Point", "Envelope"];
|
||||
// FIXME: In case we parse a feature with no geometry, but boundedBy an Envelope,
|
||||
// this code creates a geometry derived from the Envelope. This is not correct.
|
||||
var type, nodeList, geometry, parser;
|
||||
for(var i=0; i<order.length; ++i) {
|
||||
type = order[i];
|
||||
@@ -162,6 +164,21 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var bounds;
|
||||
var boxNodes = this.getElementsByTagNameNS(node, this.gmlns, "Box");
|
||||
for(i=0; i<boxNodes.length; ++i) {
|
||||
var boxNode = boxNodes[i];
|
||||
var box = this.parseGeometry["box"].apply(this, [boxNode]);
|
||||
var parentNode = boxNode.parentNode;
|
||||
var parentName = parentNode.localName ||
|
||||
parentNode.nodeName.split(":").pop();
|
||||
if(parentName === "boundedBy") {
|
||||
bounds = box;
|
||||
} else {
|
||||
geometry = box.toGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
// construct feature (optionally with attributes)
|
||||
var attributes;
|
||||
@@ -169,6 +186,7 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
attributes = this.parseAttributes(node);
|
||||
}
|
||||
var feature = new OpenLayers.Feature.Vector(geometry, attributes);
|
||||
feature.bounds = bounds;
|
||||
|
||||
feature.gml = {
|
||||
featureType: node.firstChild.nodeName.split(":")[1],
|
||||
@@ -176,14 +194,6 @@ OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
featureNSPrefix: node.firstChild.prefix
|
||||
};
|
||||
|
||||
var boundedByNodes = this.getElementsByTagNameNS(node, this.gmlns, 'boundedBy');
|
||||
if (boundedByNodes.length === 1) {
|
||||
parser = this.parseGeometry['box'];
|
||||
if (parser) {
|
||||
feature.bounds = parser.apply(this, [boundedByNodes[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
// assign fid - this can come from a "fid" or "id" attribute
|
||||
var childNode = node.firstChild;
|
||||
var fid;
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
*/
|
||||
OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
/**
|
||||
* Property: namespaces
|
||||
* {Object} Mapping of namespace aliases to namespace URIs.
|
||||
*/
|
||||
namespaces: {
|
||||
kml: "http://www.opengis.net/kml/2.2",
|
||||
gx: "http://www.google.com/kml/ext/2.2"
|
||||
},
|
||||
|
||||
/**
|
||||
* APIProperty: kmlns
|
||||
* {String} KML Namespace to use. Defaults to 2.0 namespace.
|
||||
@@ -65,6 +74,26 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
*/
|
||||
extractStyles: false,
|
||||
|
||||
/**
|
||||
* APIProperty: extractTracks
|
||||
* {Boolean} Extract gx:Track elements from Placemark elements. Default
|
||||
* is false. If true, features will be generated for all points in
|
||||
* all gx:Track elements. Features will have a when (Date) attribute
|
||||
* based on when elements in the track. If tracks include angle
|
||||
* elements, features will have heading, tilt, and roll attributes.
|
||||
* If track point coordinates have three values, features will have
|
||||
* an altitude attribute with the third coordinate value.
|
||||
*/
|
||||
extractTracks: false,
|
||||
|
||||
/**
|
||||
* APIProperty: trackAttributes
|
||||
* {Array} If <extractTracks> is true, points within gx:Track elements will
|
||||
* be parsed as features with when, heading, tilt, and roll attributes.
|
||||
* Any additional attribute names can be provided in <trackAttributes>.
|
||||
*/
|
||||
trackAttributes: null,
|
||||
|
||||
/**
|
||||
* Property: internalns
|
||||
* {String} KML Namespace to use -- defaults to the namespace of the
|
||||
@@ -565,7 +594,7 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
*
|
||||
*/
|
||||
parseFeatures: function(nodes, options) {
|
||||
var features = new Array(nodes.length);
|
||||
var features = [];
|
||||
for(var i=0, len=nodes.length; i<len; i++) {
|
||||
var featureNode = nodes[i];
|
||||
var feature = this.parseFeature.apply(this,[featureNode]) ;
|
||||
@@ -593,8 +622,26 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
}
|
||||
}
|
||||
|
||||
// add feature to list of features
|
||||
features[i] = feature;
|
||||
// check if gx:Track elements should be parsed
|
||||
if (this.extractTracks) {
|
||||
var tracks = this.getElementsByTagNameNS(
|
||||
featureNode, this.namespaces.gx, "Track"
|
||||
);
|
||||
if (tracks && tracks.length > 0) {
|
||||
var track = tracks[0];
|
||||
var container = {
|
||||
features: [],
|
||||
feature: feature
|
||||
};
|
||||
this.readNode(track, container);
|
||||
if (container.features.length > 0) {
|
||||
features.push.apply(features, container.features);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add feature to list of features
|
||||
features.push(feature);
|
||||
}
|
||||
} else {
|
||||
throw "Bad Placemark: " + i;
|
||||
}
|
||||
@@ -603,7 +650,100 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
// add new features to existing feature list
|
||||
this.features = this.features.concat(features);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
* be applied when a namespaced node is found matching the function
|
||||
* name. The function will be applied in the scope of this parser
|
||||
* with two arguments: the node being read and a context object passed
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"kml": {
|
||||
"when": function(node, container) {
|
||||
container.whens.push(OpenLayers.Date.parse(
|
||||
this.getChildValue(node)
|
||||
));
|
||||
},
|
||||
"_trackPointAttribute": function(node, container) {
|
||||
var name = node.nodeName.split(":").pop();
|
||||
container.attributes[name].push(this.getChildValue(node));
|
||||
}
|
||||
},
|
||||
"gx": {
|
||||
"Track": function(node, container) {
|
||||
var obj = {
|
||||
whens: [],
|
||||
points: [],
|
||||
angles: []
|
||||
};
|
||||
if (this.trackAttributes) {
|
||||
var name;
|
||||
obj.attributes = {};
|
||||
for (var i=0, ii=this.trackAttributes.length; i<ii; ++i) {
|
||||
name = this.trackAttributes[i];
|
||||
obj.attributes[name] = [];
|
||||
if (!(name in this.readers.kml)) {
|
||||
this.readers.kml[name] = this.readers.kml._trackPointAttribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.readChildNodes(node, obj);
|
||||
if (obj.whens.length !== obj.points.length) {
|
||||
throw new Error("gx:Track with unequal number of when (" + obj.whens.length + ") and gx:coord (" + obj.points.length + ") elements.");
|
||||
}
|
||||
var hasAngles = obj.angles.length > 0;
|
||||
if (hasAngles && obj.whens.length !== obj.angles.length) {
|
||||
throw new Error("gx:Track with unequal number of when (" + obj.whens.length + ") and gx:angles (" + obj.angles.length + ") elements.");
|
||||
}
|
||||
var feature, point, angles;
|
||||
for (var i=0, ii=obj.whens.length; i<ii; ++i) {
|
||||
feature = container.feature.clone();
|
||||
feature.fid = container.feature.fid || container.feature.id;
|
||||
point = obj.points[i];
|
||||
feature.geometry = point;
|
||||
if ("z" in point) {
|
||||
feature.attributes.altitude = point.z;
|
||||
}
|
||||
if (this.internalProjection && this.externalProjection) {
|
||||
feature.geometry.transform(
|
||||
this.externalProjection, this.internalProjection
|
||||
);
|
||||
}
|
||||
if (this.trackAttributes) {
|
||||
for (var j=0, jj=this.trackAttributes.length; j<jj; ++j) {
|
||||
feature.attributes[name] = obj.attributes[this.trackAttributes[j]][i];
|
||||
}
|
||||
}
|
||||
feature.attributes.when = obj.whens[i];
|
||||
feature.attributes.trackId = container.feature.id;
|
||||
if (hasAngles) {
|
||||
angles = obj.angles[i];
|
||||
feature.attributes.heading = parseFloat(angles[0]);
|
||||
feature.attributes.tilt = parseFloat(angles[1]);
|
||||
feature.attributes.roll = parseFloat(angles[2]);
|
||||
}
|
||||
container.features.push(feature);
|
||||
}
|
||||
},
|
||||
"coord": function(node, container) {
|
||||
var str = this.getChildValue(node);
|
||||
var coords = str.replace(this.regExes.trimSpace, "").split(/\s+/);
|
||||
var point = new OpenLayers.Geometry.Point(coords[0], coords[1]);
|
||||
if (coords.length > 2) {
|
||||
point.z = parseFloat(coords[2]);
|
||||
}
|
||||
container.points.push(point);
|
||||
},
|
||||
"angles": function(node, container) {
|
||||
var str = this.getChildValue(node);
|
||||
var parts = str.replace(this.regExes.trimSpace, "").split(/\s+/);
|
||||
container.angles.push(parts);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: parseFeature
|
||||
* This function is the core of the KML parsing code in OpenLayers.
|
||||
@@ -885,7 +1025,7 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
child = children[i];
|
||||
if(child.nodeType == 1) {
|
||||
grandchildren = child.childNodes;
|
||||
if(grandchildren.length >= 1 || grandchildren.length <= 3) {
|
||||
if(grandchildren.length >= 1 && grandchildren.length <= 3) {
|
||||
var grandchild;
|
||||
switch (grandchildren.length) {
|
||||
case 1:
|
||||
@@ -894,7 +1034,7 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
case 2:
|
||||
var c1 = grandchildren[0];
|
||||
var c2 = grandchildren[1];
|
||||
grandchild = c1.nodeType == 3 || c1.nodeType == 4 ?
|
||||
grandchild = (c1.nodeType == 3 || c1.nodeType == 4) ?
|
||||
c1 : c2;
|
||||
break;
|
||||
case 3:
|
||||
|
||||
255
lib/OpenLayers/Format/OWSCommon/v1.js
Normal file
@@ -0,0 +1,255 @@
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
*/
|
||||
|
||||
if (!OpenLayers.Format.OWSCommon) {
|
||||
OpenLayers.Format.OWSCommon = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.OWSCommon.v1
|
||||
* Common readers and writers for OWSCommon v1.X formats
|
||||
*/
|
||||
OpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
/**
|
||||
* Property: regExes
|
||||
* Compiled regular expressions for manipulating strings.
|
||||
*/
|
||||
regExes: {
|
||||
trimSpace: (/^\s*|\s*$/g),
|
||||
removeSpace: (/\s*/g),
|
||||
splitSpace: (/\s+/),
|
||||
trimComma: (/\s*,\s*/g)
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
* be applied when a namespaced node is found matching the function
|
||||
* name. The function will be applied in the scope of this parser
|
||||
* with two arguments: the node being read and a context object passed
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"ows": {
|
||||
"ServiceIdentification": function(node, obj) {
|
||||
obj.serviceIdentification = {};
|
||||
this.readChildNodes(node, obj.serviceIdentification);
|
||||
},
|
||||
"Title": function(node, obj) {
|
||||
obj.title = this.getChildValue(node);
|
||||
},
|
||||
"Abstract": function(node, serviceIdentification) {
|
||||
serviceIdentification["abstract"] = this.getChildValue(node);
|
||||
},
|
||||
"Keywords": function(node, serviceIdentification) {
|
||||
serviceIdentification.keywords = {};
|
||||
this.readChildNodes(node, serviceIdentification.keywords);
|
||||
},
|
||||
"Keyword": function(node, keywords) {
|
||||
keywords[this.getChildValue(node)] = true;
|
||||
},
|
||||
"ServiceType": function(node, serviceIdentification) {
|
||||
serviceIdentification.serviceType = {
|
||||
codeSpace: node.getAttribute('codeSpace'),
|
||||
value: this.getChildValue(node)};
|
||||
},
|
||||
"ServiceTypeVersion": function(node, serviceIdentification) {
|
||||
serviceIdentification.serviceTypeVersion = this.getChildValue(node);
|
||||
},
|
||||
"Fees": function(node, serviceIdentification) {
|
||||
serviceIdentification.fees = this.getChildValue(node);
|
||||
},
|
||||
"AccessConstraints": function(node, serviceIdentification) {
|
||||
serviceIdentification.accessConstraints =
|
||||
this.getChildValue(node);
|
||||
},
|
||||
"ServiceProvider": function(node, obj) {
|
||||
obj.serviceProvider = {};
|
||||
this.readChildNodes(node, obj.serviceProvider);
|
||||
},
|
||||
"ProviderName": function(node, serviceProvider) {
|
||||
serviceProvider.providerName = this.getChildValue(node);
|
||||
},
|
||||
"ProviderSite": function(node, serviceProvider) {
|
||||
serviceProvider.providerSite = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"ServiceContact": function(node, serviceProvider) {
|
||||
serviceProvider.serviceContact = {};
|
||||
this.readChildNodes(node, serviceProvider.serviceContact);
|
||||
},
|
||||
"IndividualName": function(node, serviceContact) {
|
||||
serviceContact.individualName = this.getChildValue(node);
|
||||
},
|
||||
"PositionName": function(node, serviceContact) {
|
||||
serviceContact.positionName = this.getChildValue(node);
|
||||
},
|
||||
"ContactInfo": function(node, serviceContact) {
|
||||
serviceContact.contactInfo = {};
|
||||
this.readChildNodes(node, serviceContact.contactInfo);
|
||||
},
|
||||
"Phone": function(node, contactInfo) {
|
||||
contactInfo.phone = {};
|
||||
this.readChildNodes(node, contactInfo.phone);
|
||||
},
|
||||
"Voice": function(node, phone) {
|
||||
phone.voice = this.getChildValue(node);
|
||||
},
|
||||
"Address": function(node, contactInfo) {
|
||||
contactInfo.address = {};
|
||||
this.readChildNodes(node, contactInfo.address);
|
||||
},
|
||||
"DeliveryPoint": function(node, address) {
|
||||
address.deliveryPoint = this.getChildValue(node);
|
||||
},
|
||||
"City": function(node, address) {
|
||||
address.city = this.getChildValue(node);
|
||||
},
|
||||
"AdministrativeArea": function(node, address) {
|
||||
address.administrativeArea = this.getChildValue(node);
|
||||
},
|
||||
"PostalCode": function(node, address) {
|
||||
address.postalCode = this.getChildValue(node);
|
||||
},
|
||||
"Country": function(node, address) {
|
||||
address.country = this.getChildValue(node);
|
||||
},
|
||||
"ElectronicMailAddress": function(node, address) {
|
||||
address.electronicMailAddress = this.getChildValue(node);
|
||||
},
|
||||
"Role": function(node, serviceContact) {
|
||||
serviceContact.role = this.getChildValue(node);
|
||||
},
|
||||
"OperationsMetadata": function(node, obj) {
|
||||
obj.operationsMetadata = {};
|
||||
this.readChildNodes(node, obj.operationsMetadata);
|
||||
},
|
||||
"Operation": function(node, operationsMetadata) {
|
||||
var name = node.getAttribute("name");
|
||||
operationsMetadata[name] = {};
|
||||
this.readChildNodes(node, operationsMetadata[name]);
|
||||
},
|
||||
"DCP": function(node, operation) {
|
||||
operation.dcp = {};
|
||||
this.readChildNodes(node, operation.dcp);
|
||||
},
|
||||
"HTTP": function(node, dcp) {
|
||||
dcp.http = {};
|
||||
this.readChildNodes(node, dcp.http);
|
||||
},
|
||||
"Get": function(node, http) {
|
||||
http.get = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"Post": function(node, http) {
|
||||
http.post = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"Parameter": function(node, operation) {
|
||||
if (!operation.parameters) {
|
||||
operation.parameters = {};
|
||||
}
|
||||
var name = node.getAttribute("name");
|
||||
operation.parameters[name] = {};
|
||||
this.readChildNodes(node, operation.parameters[name]);
|
||||
},
|
||||
"Value": function(node, allowedValues) {
|
||||
allowedValues[this.getChildValue(node)] = true;
|
||||
},
|
||||
"OutputFormat": function(node, obj) {
|
||||
obj.formats.push({value: this.getChildValue(node)});
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"WGS84BoundingBox": function(node, obj) {
|
||||
var boundingBox = {};
|
||||
boundingBox.crs = node.getAttribute("crs");
|
||||
if (obj.BoundingBox) {
|
||||
obj.BoundingBox.push(boundingBox);
|
||||
} else {
|
||||
obj.projection = boundingBox.crs;
|
||||
boundingBox = obj;
|
||||
}
|
||||
this.readChildNodes(node, boundingBox);
|
||||
},
|
||||
"BoundingBox": function(node, obj) {
|
||||
// FIXME: We consider that BoundingBox is the same as WGS84BoundingBox
|
||||
// LowerCorner = "min_x min_y"
|
||||
// UpperCorner = "max_x max_y"
|
||||
// It should normally depend on the projection
|
||||
this.readers['ows']['WGS84BoundingBox'].apply(this, [node, obj]);
|
||||
},
|
||||
"LowerCorner": function(node, obj) {
|
||||
var str = this.getChildValue(node).replace(
|
||||
this.regExes.trimSpace, "");
|
||||
str = str.replace(this.regExes.trimComma, ",");
|
||||
var pointList = str.split(this.regExes.splitSpace);
|
||||
obj.left = pointList[0];
|
||||
obj.bottom = pointList[1];
|
||||
},
|
||||
"UpperCorner": function(node, obj) {
|
||||
var str = this.getChildValue(node).replace(
|
||||
this.regExes.trimSpace, "");
|
||||
str = str.replace(this.regExes.trimComma, ",");
|
||||
var pointList = str.split(this.regExes.splitSpace);
|
||||
obj.right = pointList[0];
|
||||
obj.top = pointList[1];
|
||||
obj.bounds = new OpenLayers.Bounds(obj.left, obj.bottom,
|
||||
obj.right, obj.top);
|
||||
delete obj.left;
|
||||
delete obj.bottom;
|
||||
delete obj.right;
|
||||
delete obj.top;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: writers
|
||||
* As a compliment to the readers property, this structure contains public
|
||||
* writing functions grouped by namespace alias and named like the
|
||||
* node names they produce.
|
||||
*/
|
||||
writers: {
|
||||
"ows": {
|
||||
"BoundingBox": function(options) {
|
||||
var node = this.createElementNSPlus("ows:BoundingBox", {
|
||||
attributes: {
|
||||
crs: options.projection
|
||||
}
|
||||
});
|
||||
this.writeNode("ows:LowerCorner", options, node);
|
||||
this.writeNode("ows:UpperCorner", options, node);
|
||||
return node;
|
||||
},
|
||||
"LowerCorner": function(options) {
|
||||
var node = this.createElementNSPlus("ows:LowerCorner", {
|
||||
value: options.bounds.left + " " + options.bounds.bottom });
|
||||
return node;
|
||||
},
|
||||
"UpperCorner": function(options) {
|
||||
var node = this.createElementNSPlus("ows:UpperCorner", {
|
||||
value: options.bounds.right + " " + options.bounds.top });
|
||||
return node;
|
||||
},
|
||||
"Title": function(title) {
|
||||
var node = this.createElementNSPlus("ows:Title", {
|
||||
value: title });
|
||||
return node;
|
||||
},
|
||||
"OutputFormat": function(format) {
|
||||
var node = this.createElementNSPlus("ows:OutputFormat", {
|
||||
value: format });
|
||||
return node;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.OWSCommon.v1"
|
||||
|
||||
});
|
||||
49
lib/OpenLayers/Format/OWSCommon/v1_0_0.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/* Copyright (c) 2006-2009 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/OWSCommon/v1.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.OWSCommon.v1_0_0
|
||||
* Parser for OWS Common version 1.0.0 which can be used by other parsers.
|
||||
* It is not intended to be used on its own.
|
||||
*/
|
||||
OpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, {
|
||||
|
||||
/**
|
||||
* Property: namespaces
|
||||
* {Object} Mapping of namespace aliases to namespace URIs.
|
||||
*/
|
||||
namespaces: {
|
||||
ows: "http://www.opengis.net/ows/1.0",
|
||||
xlink: "http://www.w3.org/1999/xlink"
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
* be applied when a namespaced node is found matching the function
|
||||
* name. The function will be applied in the scope of this parser
|
||||
* with two arguments: the node being read and a context object passed
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"ows": OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"]
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: writers
|
||||
* As a compliment to the readers property, this structure contains public
|
||||
* writing functions grouped by namespace alias and named like the
|
||||
* node names they produce.
|
||||
*/
|
||||
writers: {
|
||||
"ows": OpenLayers.Format.OWSCommon.v1.prototype.writers["ows"]
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.OWSCommon.v1_1_0"
|
||||
|
||||
});
|
||||
@@ -3,21 +3,16 @@
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
* @requires OpenLayers/Format/OWSCommon/v1.js
|
||||
*/
|
||||
|
||||
OpenLayers.Format.OWSCommon = {};
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.OWSCommon.v1_1_0
|
||||
* Parser for OWS Common version 1.1.0 which can be used by other parsers.
|
||||
* It is not intended to be used on its own.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, {
|
||||
|
||||
/**
|
||||
* Property: namespaces
|
||||
* {Object} Mapping of namespace aliases to namespace URIs.
|
||||
@@ -25,8 +20,8 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
namespaces: {
|
||||
ows: "http://www.opengis.net/ows/1.1",
|
||||
xlink: "http://www.w3.org/1999/xlink"
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
@@ -36,129 +31,7 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"ows": {
|
||||
"ServiceIdentification": function(node, obj) {
|
||||
obj.serviceIdentification = {};
|
||||
this.readChildNodes(node, obj.serviceIdentification);
|
||||
},
|
||||
"Title": function(node, serviceIdentification) {
|
||||
serviceIdentification.title = this.getChildValue(node);
|
||||
},
|
||||
"Abstract": function(node, serviceIdentification) {
|
||||
serviceIdentification.abstract = this.getChildValue(node);
|
||||
},
|
||||
"Keywords": function(node, serviceIdentification) {
|
||||
serviceIdentification.keywords = {};
|
||||
this.readChildNodes(node, serviceIdentification.keywords);
|
||||
},
|
||||
"Keyword": function(node, keywords) {
|
||||
keywords[this.getChildValue(node)] = true;
|
||||
},
|
||||
"ServiceType": function(node, serviceIdentification) {
|
||||
serviceIdentification.serviceType = {
|
||||
codeSpace: node.getAttribute('codeSpace'),
|
||||
value: this.getChildValue(node)};
|
||||
},
|
||||
"ServiceTypeVersion": function(node, serviceIdentification) {
|
||||
serviceIdentification.serviceTypeVersion = this.getChildValue(node);
|
||||
},
|
||||
"Fees": function(node, serviceIdentification) {
|
||||
serviceIdentification.fees = this.getChildValue(node);
|
||||
},
|
||||
"AccessConstraints": function(node, serviceIdentification) {
|
||||
serviceIdentification.accessConstraints =
|
||||
this.getChildValue(node);
|
||||
},
|
||||
"ServiceProvider": function(node, obj) {
|
||||
obj.serviceProvider = {};
|
||||
this.readChildNodes(node, obj.serviceProvider);
|
||||
},
|
||||
"ProviderName": function(node, serviceProvider) {
|
||||
serviceProvider.providerName = this.getChildValue(node);
|
||||
},
|
||||
"ProviderSite": function(node, serviceProvider) {
|
||||
serviceProvider.providerSite = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"ServiceContact": function(node, serviceProvider) {
|
||||
serviceProvider.serviceContact = {};
|
||||
this.readChildNodes(node, serviceProvider.serviceContact);
|
||||
},
|
||||
"IndividualName": function(node, serviceContact) {
|
||||
serviceContact.individualName = this.getChildValue(node);
|
||||
},
|
||||
"PositionName": function(node, serviceContact) {
|
||||
serviceContact.positionName = this.getChildValue(node);
|
||||
},
|
||||
"ContactInfo": function(node, serviceContact) {
|
||||
serviceContact.contactInfo = {};
|
||||
this.readChildNodes(node, serviceContact.contactInfo);
|
||||
},
|
||||
"Phone": function(node, contactInfo) {
|
||||
contactInfo.phone = {};
|
||||
this.readChildNodes(node, contactInfo.phone);
|
||||
},
|
||||
"Voice": function(node, phone) {
|
||||
phone.voice = this.getChildValue(node);
|
||||
},
|
||||
"Address": function(node, contactInfo) {
|
||||
contactInfo.address = {};
|
||||
this.readChildNodes(node, contactInfo.address);
|
||||
},
|
||||
"DeliveryPoint": function(node, address) {
|
||||
address.deliveryPoint = this.getChildValue(node);
|
||||
},
|
||||
"City": function(node, address) {
|
||||
address.city = this.getChildValue(node);
|
||||
},
|
||||
"AdministrativeArea": function(node, address) {
|
||||
address.administrativeArea = this.getChildValue(node);
|
||||
},
|
||||
"PostalCode": function(node, address) {
|
||||
address.postalCode = this.getChildValue(node);
|
||||
},
|
||||
"Country": function(node, address) {
|
||||
address.country = this.getChildValue(node);
|
||||
},
|
||||
"ElectronicMailAddress": function(node, address) {
|
||||
address.electronicMailAddress = this.getChildValue(node);
|
||||
},
|
||||
"Role": function(node, serviceContact) {
|
||||
serviceContact.role = this.getChildValue(node);
|
||||
},
|
||||
"OperationsMetadata": function(node, obj) {
|
||||
obj.operationsMetadata = {};
|
||||
this.readChildNodes(node, obj.operationsMetadata);
|
||||
},
|
||||
"Operation": function(node, operationsMetadata) {
|
||||
var name = node.getAttribute("name");
|
||||
operationsMetadata[name] = {};
|
||||
this.readChildNodes(node, operationsMetadata[name]);
|
||||
},
|
||||
"DCP": function(node, operation) {
|
||||
operation.dcp = {};
|
||||
this.readChildNodes(node, operation.dcp);
|
||||
},
|
||||
"HTTP": function(node, dcp) {
|
||||
dcp.http = {};
|
||||
this.readChildNodes(node, dcp.http);
|
||||
},
|
||||
"Get": function(node, http) {
|
||||
http.get = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"Post": function(node, http) {
|
||||
http.post = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
},
|
||||
"Parameter": function(node, operation) {
|
||||
if (!operation.parameters) {
|
||||
operation.parameters = {};
|
||||
}
|
||||
var name = node.getAttribute("name");
|
||||
operation.parameters[name] = {};
|
||||
this.readChildNodes(node, operation.parameters[name]);
|
||||
},
|
||||
"ows": OpenLayers.Util.applyDefaults({
|
||||
"AllowedValues": function(node, parameter) {
|
||||
parameter.allowedValues = {};
|
||||
this.readChildNodes(node, parameter.allowedValues);
|
||||
@@ -166,9 +39,6 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
"AnyValue": function(node, parameter) {
|
||||
parameter.anyValue = true;
|
||||
},
|
||||
"Value": function(node, allowedValues) {
|
||||
allowedValues[this.getChildValue(node)] = true;
|
||||
},
|
||||
"Range": function(node, allowedValues) {
|
||||
allowedValues.range = {};
|
||||
this.readChildNodes(node, allowedValues.range);
|
||||
@@ -178,8 +48,14 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
},
|
||||
"MaximumValue": function(node, range) {
|
||||
range.maxValue = this.getChildValue(node);
|
||||
},
|
||||
"Identifier": function(node, obj) {
|
||||
obj.identifier = this.getChildValue(node);
|
||||
},
|
||||
"SupportedCRS": function(node, obj) {
|
||||
obj.supportedCRS = this.getChildValue(node);
|
||||
}
|
||||
}
|
||||
}, OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"])
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.OWSCommon.v1_1_0"
|
||||
|
||||
80
lib/OpenLayers/Format/OWSContext.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/Context.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.OWSContext
|
||||
* Read and write OWS Context documents. OWS Context documents are a
|
||||
* preliminary OGC (Open Geospatial Consortium) standard for storing the
|
||||
* state of a web mapping application. In a way it is the successor to
|
||||
* Web Map Context (WMC), since it is more generic and more types of layers
|
||||
* can be stored. Also, nesting of layers is supported since version 0.3.1.
|
||||
* For more information see: http://www.ogcnetwork.net/context
|
||||
*/
|
||||
OpenLayers.Format.OWSContext = OpenLayers.Class(OpenLayers.Format.Context,{
|
||||
|
||||
/**
|
||||
* APIProperty: defaultVersion
|
||||
* {String} Version number to assume if none found. Default is "0.3.1".
|
||||
*/
|
||||
defaultVersion: "0.3.1",
|
||||
|
||||
/**
|
||||
* Method: getParser
|
||||
* Get the OWSContext parser given a version. Create a new parser if it does not
|
||||
* already exist.
|
||||
*
|
||||
* Parameters:
|
||||
* version - {String} The version of the parser.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Format.OWSContext>} An OWSContext parser.
|
||||
*/
|
||||
getParser: function(version) {
|
||||
var v = version || this.version || this.defaultVersion;
|
||||
// 0.3.1 is backwards compatible with 0.3.0
|
||||
if (v === "0.3.0") {
|
||||
v = this.defaultVersion;
|
||||
}
|
||||
if(!this.parser || this.parser.VERSION != v) {
|
||||
var format = OpenLayers.Format.OWSContext[
|
||||
"v" + v.replace(/\./g, "_")
|
||||
];
|
||||
if(!format) {
|
||||
throw "Can't find a OWSContext parser for version " + v;
|
||||
}
|
||||
this.parser = new format(this.options);
|
||||
}
|
||||
return this.parser;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: toContext
|
||||
* Create a context object free from layer given a map or a
|
||||
* context object.
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {<OpenLayers.Map> | Object} The map or context.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} A context object.
|
||||
*/
|
||||
toContext: function(obj) {
|
||||
var context = {};
|
||||
if(obj.CLASS_NAME == "OpenLayers.Map") {
|
||||
context.bounds = obj.getExtent();
|
||||
context.maxExtent = obj.maxExtent;
|
||||
context.projection = obj.projection;
|
||||
context.size = obj.getSize();
|
||||
context.layers = obj.layers;
|
||||
}
|
||||
return context;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.OWSContext"
|
||||
|
||||
});
|
||||
588
lib/OpenLayers/Format/OWSContext/v0_3_1.js
Normal file
@@ -0,0 +1,588 @@
|
||||
/* Copyright (c) 2006-2010 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
* @requires OpenLayers/Format/KML.js
|
||||
* @requires OpenLayers/Format/GML.js
|
||||
* @requires OpenLayers/Format/GML/v2.js
|
||||
* @requires OpenLayers/Format/SLD/v1_0_0.js
|
||||
* @requires OpenLayers/Format/OWSContext.js
|
||||
* @requires OpenLayers/Format/OWSCommon/v1_0_0.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.OWSContext.v0_3_1
|
||||
* Read and write OWSContext version 0.3.1.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.OWSContext.v0_3_1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
/**
|
||||
* Property: namespaces
|
||||
* {Object} Mapping of namespace aliases to namespace URIs.
|
||||
*/
|
||||
namespaces: {
|
||||
owc: "http://www.opengis.net/ows-context",
|
||||
gml: "http://www.opengis.net/gml",
|
||||
kml: "http://www.opengis.net/kml/2.2",
|
||||
ogc: "http://www.opengis.net/ogc",
|
||||
ows: "http://www.opengis.net/ows",
|
||||
sld: "http://www.opengis.net/sld",
|
||||
xlink: "http://www.w3.org/1999/xlink",
|
||||
xsi: "http://www.w3.org/2001/XMLSchema-instance"
|
||||
},
|
||||
|
||||
/**
|
||||
* Constant: VERSION
|
||||
* {String} 0.3.1
|
||||
*/
|
||||
VERSION: "0.3.1",
|
||||
|
||||
/**
|
||||
* Property: schemaLocation
|
||||
* {String} Schema location
|
||||
*/
|
||||
schemaLocation: "http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd",
|
||||
|
||||
/**
|
||||
* Property: defaultPrefix
|
||||
* {String} Default namespace prefix to use.
|
||||
*/
|
||||
defaultPrefix: "owc",
|
||||
|
||||
/**
|
||||
* APIProperty: extractAttributes
|
||||
* {Boolean} Extract attributes from GML. Default is true.
|
||||
*/
|
||||
extractAttributes: true,
|
||||
|
||||
/**
|
||||
* APIProperty: xy
|
||||
* {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
|
||||
* Changing is not recommended, a new Format should be instantiated.
|
||||
*/
|
||||
xy: true,
|
||||
|
||||
/**
|
||||
* Property: regExes
|
||||
* Compiled regular expressions for manipulating strings.
|
||||
*/
|
||||
regExes: {
|
||||
trimSpace: (/^\s*|\s*$/g),
|
||||
removeSpace: (/\s*/g),
|
||||
splitSpace: (/\s+/),
|
||||
trimComma: (/\s*,\s*/g)
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: featureNS
|
||||
* {String} The namespace uri to use for writing InlineGeometry
|
||||
*/
|
||||
featureNS: "http://mapserver.gis.umn.edu/mapserver",
|
||||
|
||||
/**
|
||||
* Property: featureType
|
||||
* {String} The name to use as the feature type when writing out
|
||||
* InlineGeometry
|
||||
*/
|
||||
featureType: 'vector',
|
||||
|
||||
/**
|
||||
* Property: geometryName
|
||||
* {String} The name to use for the geometry attribute when writing out
|
||||
* InlineGeometry
|
||||
*/
|
||||
geometryName: 'geometry',
|
||||
|
||||
/**
|
||||
* Property: nestingLayerLookup
|
||||
* {Object} Hashtable lookup for nesting layer nodes. Used while writing
|
||||
* the OWS context document. It is necessary to keep track of the
|
||||
* nestingPaths for which nesting layer nodes have already been
|
||||
* created, so (nesting) layer nodes are added to those nodes.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* If there are three layers with nestingPaths:
|
||||
* layer1.metadata.nestingPath = "a/b/"
|
||||
* layer2.metadata.nestingPath = "a/b/"
|
||||
* layer2.metadata.nestingPath = "a/c"
|
||||
*
|
||||
* then a nesting layer node "a" should be created once and added
|
||||
* to the resource list, a nesting layer node "b" should be created
|
||||
* once and added under "a", and a nesting layer node "c" should be
|
||||
* created and added under "a". The lookup paths for these nodes
|
||||
* will be "a", "a/b", and "a/c" respectively.
|
||||
*/
|
||||
nestingLayerLookup: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.OWSContext.v0_3_1
|
||||
* Instances of this class are not created directly. Use the
|
||||
* <OpenLayers.Format.OWSContext> constructor instead.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
|
||||
OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setNestingPath
|
||||
* Set the nestingPath property of the layer depending on the position
|
||||
* of the layer in hierarchy of layers.
|
||||
*
|
||||
* Parameters:
|
||||
* l - {Object} An object that may have a layersContext array property.
|
||||
*
|
||||
*/
|
||||
setNestingPath : function(l){
|
||||
if(l.layersContext){
|
||||
for (var i = 0, len = l.layersContext.length; i < len; i++) {
|
||||
var layerContext = l.layersContext[i];
|
||||
var nPath = [];
|
||||
var nTitle = l.title || "";
|
||||
if(l.metadata && l.metadata.nestingPath){
|
||||
nPath = l.metadata.nestingPath.slice();
|
||||
}
|
||||
if (nTitle != "") {
|
||||
nPath.push(nTitle);
|
||||
}
|
||||
layerContext.metadata.nestingPath = nPath;
|
||||
if(layerContext.layersContext){
|
||||
this.setNestingPath(layerContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: decomposeNestingPath
|
||||
* Takes a nestingPath like "a/b/c" and decomposes it into subpaths:
|
||||
* "a", "a/b", "a/b/c"
|
||||
*
|
||||
* Parameters:
|
||||
* nPath - {Array} the nesting path
|
||||
*
|
||||
* Returns:
|
||||
* Array({String}) Array with subpaths, or empty array if there is nothing
|
||||
* to decompose
|
||||
*/
|
||||
decomposeNestingPath: function(nPath){
|
||||
var a = [];
|
||||
if (nPath instanceof Array) {
|
||||
while (nPath.length > 0) {
|
||||
a.push(nPath.slice());
|
||||
nPath.pop();
|
||||
}
|
||||
a.reverse();
|
||||
}
|
||||
return a;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Read OWS context data from a string or DOMElement, and return a list
|
||||
* of layers.
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} The context object with a flat layer list as a property named
|
||||
* layersContext.
|
||||
*/
|
||||
read: function(data) {
|
||||
if(typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
if(data && data.nodeType == 9) {
|
||||
data = data.documentElement;
|
||||
}
|
||||
var context = {};
|
||||
this.readNode(data, context);
|
||||
// since an OWSContext can be nested we need to go through this
|
||||
// structure recursively
|
||||
this.setNestingPath({layersContext : context.layersContext});
|
||||
// after nesting path has been set, create a flat list of layers
|
||||
var layers = [];
|
||||
this.processLayer(layers, context);
|
||||
delete context.layersContext;
|
||||
context.layersContext = layers;
|
||||
return context;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: processLayer
|
||||
* Recursive function to get back a flat list of layers from the hierarchic
|
||||
* layer structure.
|
||||
*
|
||||
* Parameters:
|
||||
* layerArray - {Array({Object})} Array of layerContext objects
|
||||
* layerContext - {Object} layerContext object
|
||||
*/
|
||||
processLayer: function(layerArray, layer) {
|
||||
if (layer.layersContext) {
|
||||
for (var i=0, len = layer.layersContext.length; i<len; i++) {
|
||||
var l = layer.layersContext[i];
|
||||
layerArray.push(l);
|
||||
if (l.layersContext) {
|
||||
this.processLayer(layerArray, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: write
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} An object representing the map context.
|
||||
* options - {Object} Optional object.
|
||||
*
|
||||
* Returns:
|
||||
* {String} An OWS Context document string.
|
||||
*/
|
||||
write: function(context, options) {
|
||||
var name = "OWSContext";
|
||||
this.nestingLayerLookup = {}; //start with empty lookup
|
||||
options = options || {};
|
||||
OpenLayers.Util.applyDefaults(options, context);
|
||||
var root = this.writeNode(name, options);
|
||||
this.nestingLayerLookup = null; //clear lookup
|
||||
this.setAttributeNS(
|
||||
root, this.namespaces["xsi"],
|
||||
"xsi:schemaLocation", this.schemaLocation
|
||||
);
|
||||
return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
* be applied when a namespaced node is found matching the function
|
||||
* name. The function will be applied in the scope of this parser
|
||||
* with two arguments: the node being read and a context object passed
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"kml": {
|
||||
"Document": function(node, obj) {
|
||||
obj.features = new OpenLayers.Format.KML(
|
||||
{kmlns: this.namespaces.kml,
|
||||
extractStyles: true}).read(node);
|
||||
}
|
||||
},
|
||||
"owc": {
|
||||
"OWSContext": function(node, obj) {
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"General": function(node, obj) {
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"ResourceList": function(node, obj) {
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"Layer": function(node, obj) {
|
||||
var layerContext = {
|
||||
metadata: {},
|
||||
visibility: (node.getAttribute("hidden") != "1"),
|
||||
queryable: (node.getAttribute("queryable") == "1"),
|
||||
opacity: ((node.getAttribute("opacity") != null) ?
|
||||
parseFloat(node.getAttribute("opacity")) : null),
|
||||
name: node.getAttribute("name"),
|
||||
/* A category layer is a dummy layer meant for creating
|
||||
hierarchies. It is not a physical layer in the
|
||||
OpenLayers sense. The assumption we make here is that
|
||||
category layers do not have a name attribute */
|
||||
categoryLayer: (node.getAttribute("name") == null),
|
||||
formats: [],
|
||||
styles: []
|
||||
};
|
||||
if (!obj.layersContext) {
|
||||
obj.layersContext = [];
|
||||
}
|
||||
obj.layersContext.push(layerContext);
|
||||
this.readChildNodes(node, layerContext);
|
||||
},
|
||||
"InlineGeometry": function(node, obj) {
|
||||
obj.features = [];
|
||||
var elements = this.getElementsByTagNameNS(node,
|
||||
this.namespaces.gml, "featureMember");
|
||||
var el;
|
||||
if (elements.length >= 1) {
|
||||
el = elements[0];
|
||||
}
|
||||
if (el && el.firstChild) {
|
||||
var featurenode = (el.firstChild.nextSibling) ?
|
||||
el.firstChild.nextSibling : el.firstChild;
|
||||
this.setNamespace("feature", featurenode.namespaceURI);
|
||||
this.featureType = featurenode.localName ||
|
||||
featurenode.nodeName.split(":").pop();
|
||||
this.readChildNodes(node, obj);
|
||||
}
|
||||
},
|
||||
"Server": function(node, obj) {
|
||||
// when having multiple Server types, we prefer WMS
|
||||
if ((!obj.service && !obj.version) ||
|
||||
(obj.service !=
|
||||
OpenLayers.Format.Context.serviceTypes.WMS)) {
|
||||
obj.service = node.getAttribute("service");
|
||||
obj.version = node.getAttribute("version");
|
||||
this.readChildNodes(node, obj);
|
||||
}
|
||||
},
|
||||
"Name": function(node, obj) {
|
||||
obj.name = this.getChildValue(node);
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"Title": function(node, obj) {
|
||||
obj.title = this.getChildValue(node);
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"StyleList": function(node, obj) {
|
||||
this.readChildNodes(node, obj.styles);
|
||||
},
|
||||
"Style": function(node, obj) {
|
||||
var style = {};
|
||||
obj.push(style);
|
||||
this.readChildNodes(node, style);
|
||||
},
|
||||
"LegendURL": function(node, obj) {
|
||||
var legend = {};
|
||||
obj.legend = legend;
|
||||
this.readChildNodes(node, legend);
|
||||
},
|
||||
"OnlineResource": function(node, obj) {
|
||||
obj.url = this.getAttributeNS(node, this.namespaces.xlink,
|
||||
"href");
|
||||
this.readChildNodes(node, obj);
|
||||
}
|
||||
},
|
||||
"ows": OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,
|
||||
"gml": OpenLayers.Format.GML.v2.prototype.readers.gml,
|
||||
"sld": OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,
|
||||
"feature": OpenLayers.Format.GML.v2.prototype.readers.feature
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: writers
|
||||
* As a compliment to the readers property, this structure contains public
|
||||
* writing functions grouped by namespace alias and named like the
|
||||
* node names they produce.
|
||||
*/
|
||||
writers: {
|
||||
"owc": {
|
||||
"OWSContext": function(options) {
|
||||
var node = this.createElementNSPlus("OWSContext", {
|
||||
attributes: {
|
||||
version: this.VERSION,
|
||||
id: options.id || OpenLayers.Util.createUniqueID("OpenLayers_OWSContext_")
|
||||
}
|
||||
});
|
||||
this.writeNode("General", options, node);
|
||||
this.writeNode("ResourceList", options, node);
|
||||
return node;
|
||||
},
|
||||
"General": function(options) {
|
||||
var node = this.createElementNSPlus("General");
|
||||
this.writeNode("ows:BoundingBox", options, node);
|
||||
this.writeNode("ows:Title", options.title || 'OpenLayers OWSContext', node);
|
||||
return node;
|
||||
},
|
||||
"ResourceList": function(options) {
|
||||
var node = this.createElementNSPlus("ResourceList");
|
||||
for (var i=0, len=options.layers.length; i<len; i++) {
|
||||
var layer = options.layers[i];
|
||||
var decomposedPath = this.decomposeNestingPath(layer.metadata.nestingPath);
|
||||
this.writeNode("_Layer", {layer: layer, subPaths: decomposedPath}, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"Server": function(options) {
|
||||
var node = this.createElementNSPlus("Server", {attributes: {
|
||||
version: options.version,
|
||||
service: options.service }
|
||||
});
|
||||
this.writeNode("OnlineResource", options, node);
|
||||
return node;
|
||||
},
|
||||
"OnlineResource": function(options) {
|
||||
var node = this.createElementNSPlus("OnlineResource", {attributes: {
|
||||
"xlink:href": options.url }
|
||||
});
|
||||
return node;
|
||||
},
|
||||
"InlineGeometry": function(layer) {
|
||||
var node = this.createElementNSPlus("InlineGeometry");
|
||||
this.writeNode("gml:boundedBy", layer.getDataExtent(), node);
|
||||
for (var i=0, len=layer.features.length; i<len; i++) {
|
||||
this.writeNode("gml:featureMember", layer.features[i], node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"StyleList": function(styles) {
|
||||
var node = this.createElementNSPlus("StyleList");
|
||||
for (var i=0, len=styles.length; i<len; i++) {
|
||||
this.writeNode("Style", styles[i], node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"Style": function(style) {
|
||||
var node = this.createElementNSPlus("Style");
|
||||
this.writeNode("Name", style, node);
|
||||
this.writeNode("Title", style, node);
|
||||
this.writeNode("LegendURL", style, node);
|
||||
return node;
|
||||
},
|
||||
"Name": function(obj) {
|
||||
var node = this.createElementNSPlus("Name", {
|
||||
value: obj.name });
|
||||
return node;
|
||||
},
|
||||
"Title": function(obj) {
|
||||
var node = this.createElementNSPlus("Title", {
|
||||
value: obj.title });
|
||||
return node;
|
||||
},
|
||||
"LegendURL": function(style) {
|
||||
var node = this.createElementNSPlus("LegendURL");
|
||||
this.writeNode("OnlineResource", style.legend, node);
|
||||
return node;
|
||||
},
|
||||
"_WMS": function(layer) {
|
||||
var node = this.createElementNSPlus("Layer", {attributes: {
|
||||
name: layer.params.LAYERS,
|
||||
queryable: layer.queryable ? "1" : "0",
|
||||
hidden: layer.visibility ? "0" : "1",
|
||||
opacity: layer.opacity ? layer.opacity: null}
|
||||
});
|
||||
this.writeNode("ows:Title", layer.name, node);
|
||||
this.writeNode("ows:OutputFormat", layer.params.FORMAT, node);
|
||||
this.writeNode("Server", {service:
|
||||
OpenLayers.Format.Context.serviceTypes.WMS,
|
||||
version: layer.params.VERSION, url: layer.url}, node);
|
||||
if (layer.metadata.styles && layer.metadata.styles.length > 0) {
|
||||
this.writeNode("StyleList", layer.metadata.styles, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"_Layer": function(options) {
|
||||
var layer, subPaths, node, title;
|
||||
layer = options.layer;
|
||||
subPaths = options.subPaths;
|
||||
node = null;
|
||||
title = null;
|
||||
// subPaths is an array of an array
|
||||
// recursively calling _Layer writer eats up subPaths, until a
|
||||
// real writer is called and nodes are returned.
|
||||
if(subPaths.length > 0){
|
||||
var path = subPaths[0].join("/");
|
||||
var index = path.lastIndexOf("/");
|
||||
node = this.nestingLayerLookup[path];
|
||||
title = (index > 0)?path.substring(index + 1, path.length):path;
|
||||
if(!node){
|
||||
// category layer
|
||||
node = this.createElementNSPlus("Layer");
|
||||
this.writeNode("ows:Title", title, node);
|
||||
this.nestingLayerLookup[path] = node;
|
||||
}
|
||||
options.subPaths.shift();//remove a path after each call
|
||||
this.writeNode("_Layer", options, node);
|
||||
return node;
|
||||
} else {
|
||||
// write out the actual layer
|
||||
if (layer instanceof OpenLayers.Layer.WMS) {
|
||||
node = this.writeNode("_WMS", layer);
|
||||
} else if (layer instanceof OpenLayers.Layer.Vector) {
|
||||
if (layer.protocol instanceof OpenLayers.Protocol.WFS.v1) {
|
||||
node = this.writeNode("_WFS", layer);
|
||||
} else if (layer.protocol instanceof OpenLayers.Protocol.HTTP) {
|
||||
if (layer.protocol.format instanceof OpenLayers.Format.GML) {
|
||||
layer.protocol.format.version = "2.1.2";
|
||||
node = this.writeNode("_GML", layer);
|
||||
} else if (layer.protocol.format instanceof OpenLayers.Format.KML) {
|
||||
layer.protocol.format.version = "2.2";
|
||||
node = this.writeNode("_KML", layer);
|
||||
}
|
||||
} else {
|
||||
// write out as inline GML since we have no idea
|
||||
// about the original Format
|
||||
this.setNamespace("feature", this.featureNS);
|
||||
node = this.writeNode("_InlineGeometry", layer);
|
||||
}
|
||||
}
|
||||
if (layer.options.maxScale) {
|
||||
this.writeNode("sld:MinScaleDenominator",
|
||||
layer.options.maxScale, node);
|
||||
}
|
||||
if (layer.options.minScale) {
|
||||
this.writeNode("sld:MaxScaleDenominator",
|
||||
layer.options.minScale, node);
|
||||
}
|
||||
this.nestingLayerLookup[layer.name] = node;
|
||||
return node;
|
||||
}
|
||||
},
|
||||
"_WFS": function(layer) {
|
||||
var node = this.createElementNSPlus("Layer", {attributes: {
|
||||
name: layer.protocol.featurePrefix + ":" + layer.protocol.featureType,
|
||||
hidden: layer.visibility ? "0" : "1" }
|
||||
});
|
||||
this.writeNode("ows:Title", layer.name, node);
|
||||
this.writeNode("Server", {service:
|
||||
OpenLayers.Format.Context.serviceTypes.WFS,
|
||||
version: layer.protocol.version,
|
||||
url: layer.protocol.url}, node);
|
||||
return node;
|
||||
},
|
||||
"_InlineGeometry": function(layer) {
|
||||
var node = this.createElementNSPlus("Layer", {attributes: {
|
||||
name: this.featureType,
|
||||
hidden: layer.visibility ? "0" : "1" }
|
||||
});
|
||||
this.writeNode("ows:Title", layer.name, node);
|
||||
this.writeNode("InlineGeometry", layer, node);
|
||||
return node;
|
||||
},
|
||||
"_GML": function(layer) {
|
||||
var node = this.createElementNSPlus("Layer");
|
||||
this.writeNode("ows:Title", layer.name, node);
|
||||
this.writeNode("Server", {service:
|
||||
OpenLayers.Format.Context.serviceTypes.GML,
|
||||
url: layer.protocol.url, version:
|
||||
layer.protocol.format.version}, node);
|
||||
return node;
|
||||
},
|
||||
"_KML": function(layer) {
|
||||
var node = this.createElementNSPlus("Layer");
|
||||
this.writeNode("ows:Title", layer.name, node);
|
||||
this.writeNode("Server", {service:
|
||||
OpenLayers.Format.Context.serviceTypes.KML,
|
||||
version: layer.protocol.format.version, url:
|
||||
layer.protocol.url}, node);
|
||||
return node;
|
||||
}
|
||||
},
|
||||
"gml": OpenLayers.Util.applyDefaults({
|
||||
"boundedBy": function(bounds) {
|
||||
var node = this.createElementNSPlus("gml:boundedBy");
|
||||
this.writeNode("gml:Box", bounds, node);
|
||||
return node;
|
||||
}
|
||||
}, OpenLayers.Format.GML.v2.prototype.writers.gml),
|
||||
"ows": OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,
|
||||
"sld": OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,
|
||||
"feature": OpenLayers.Format.GML.v2.prototype.writers.feature
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.OWSContext.v0_3_1"
|
||||
|
||||
});
|
||||
@@ -39,6 +39,27 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
* {String} Schema location for a particular minor version.
|
||||
*/
|
||||
schemaLocation: null,
|
||||
|
||||
/**
|
||||
* APIProperty: multipleSymbolizers
|
||||
* {Boolean} Support multiple symbolizers per rule. Default is false. if
|
||||
* true, an OpenLayers.Style2 instance will be created to represent
|
||||
* user styles instead of an OpenLayers.Style instace. The
|
||||
* OpenLayers.Style2 class allows collections of rules with multiple
|
||||
* symbolizers, but is not currently useful for client side rendering.
|
||||
* If multiple symbolizers is true, multiple FeatureTypeStyle elements
|
||||
* are preserved in reading/writing by setting symbolizer zIndex values.
|
||||
* In addition, the <defaultSymbolizer> property is ignored if
|
||||
* multiple symbolizers are supported (defaults should be applied
|
||||
* when rendering).
|
||||
*/
|
||||
multipleSymbolizers: false,
|
||||
|
||||
/**
|
||||
* Property: featureTypeCounter
|
||||
* {Number} Private counter for multiple feature type styles.
|
||||
*/
|
||||
featureTypeCounter: null,
|
||||
|
||||
/**
|
||||
* APIProperty: defaultSymbolizer.
|
||||
@@ -138,8 +159,15 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
},
|
||||
"UserStyle": function(node, layer) {
|
||||
var obj = {defaultsPerSymbolizer: true, rules: []};
|
||||
this.featureTypeCounter = -1;
|
||||
this.readChildNodes(node, obj);
|
||||
var style = new OpenLayers.Style(this.defaultSymbolizer, obj);
|
||||
var style;
|
||||
if (this.multipleSymbolizers) {
|
||||
delete obj.defaultsPerSymbolizer;
|
||||
style = new OpenLayers.Style2(obj);
|
||||
} else {
|
||||
style = new OpenLayers.Style(this.defaultSymbolizer, obj);
|
||||
}
|
||||
layer.userStyles.push(style);
|
||||
},
|
||||
"IsDefault": function(node, style) {
|
||||
@@ -148,18 +176,21 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
}
|
||||
},
|
||||
"FeatureTypeStyle": function(node, style) {
|
||||
// OpenLayers doesn't have a place for FeatureTypeStyle
|
||||
// Name, Title, Abstract, FeatureTypeName, or
|
||||
// SemanticTypeIdentifier so, we make a temporary object
|
||||
// and later just use the Rule(s).
|
||||
++this.featureTypeCounter;
|
||||
var obj = {
|
||||
rules: []
|
||||
rules: this.multipleSymbolizers ? style.rules : []
|
||||
};
|
||||
this.readChildNodes(node, obj);
|
||||
style.rules = obj.rules;
|
||||
if (!this.multipleSymbolizers) {
|
||||
style.rules = obj.rules;
|
||||
}
|
||||
},
|
||||
"Rule": function(node, obj) {
|
||||
var rule = new OpenLayers.Rule();
|
||||
var config;
|
||||
if (this.multipleSymbolizers) {
|
||||
config = {symbolizers: []};
|
||||
}
|
||||
var rule = new OpenLayers.Rule(config);
|
||||
this.readChildNodes(node, rule);
|
||||
obj.rules.push(rule);
|
||||
},
|
||||
@@ -173,11 +204,18 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
rule.maxScaleDenominator = parseFloat(this.getChildValue(node));
|
||||
},
|
||||
"TextSymbolizer": function(node, rule) {
|
||||
// OpenLayers doens't do painter's order, instead we extend
|
||||
var symbolizer = rule.symbolizer["Text"] || {};
|
||||
this.readChildNodes(node, symbolizer);
|
||||
// in case it didn't exist before
|
||||
rule.symbolizer["Text"] = symbolizer;
|
||||
var config = {};
|
||||
this.readChildNodes(node, config);
|
||||
if (this.multipleSymbolizers) {
|
||||
config.zIndex = this.featureTypeCounter;
|
||||
rule.symbolizers.push(
|
||||
new OpenLayers.Symbolizer.Text(config)
|
||||
);
|
||||
} else {
|
||||
rule.symbolizer["Text"] = OpenLayers.Util.applyDefaults(
|
||||
config, rule.symbolizer["Text"]
|
||||
);
|
||||
}
|
||||
},
|
||||
"Label": function(node, symbolizer) {
|
||||
// only supporting literal or property name
|
||||
@@ -210,26 +248,88 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
symbolizer.haloRadius = radius;
|
||||
}
|
||||
},
|
||||
"RasterSymbolizer": function(node, rule) {
|
||||
var config = {};
|
||||
this.readChildNodes(node, config);
|
||||
if (this.multipleSymbolizers) {
|
||||
config.zIndex = this.featureTypeCounter;
|
||||
rule.symbolizers.push(
|
||||
new OpenLayers.Symbolizer.Raster(config)
|
||||
);
|
||||
} else {
|
||||
rule.symbolizer["Raster"] = OpenLayers.Util.applyDefaults(
|
||||
config, rule.symbolizer["Raster"]
|
||||
);
|
||||
}
|
||||
},
|
||||
"Geometry": function(node, obj) {
|
||||
obj.geometry = {};
|
||||
this.readChildNodes(node, obj.geometry);
|
||||
},
|
||||
"ColorMap": function(node, symbolizer) {
|
||||
symbolizer.colorMap = [];
|
||||
this.readChildNodes(node, symbolizer.colorMap);
|
||||
},
|
||||
"ColorMapEntry": function(node, colorMap) {
|
||||
var q = node.getAttribute("quantity");
|
||||
var o = node.getAttribute("opacity");
|
||||
colorMap.push({
|
||||
color: node.getAttribute("color"),
|
||||
quantity: q !== null ? parseFloat(q) : undefined,
|
||||
label: node.getAttribute("label") || undefined,
|
||||
opacity: o !== null ? parseFloat(o) : undefined
|
||||
});
|
||||
},
|
||||
"LineSymbolizer": function(node, rule) {
|
||||
// OpenLayers doesn't do painter's order, instead we extend
|
||||
var symbolizer = rule.symbolizer["Line"] || {};
|
||||
this.readChildNodes(node, symbolizer);
|
||||
// in case it didn't exist before
|
||||
rule.symbolizer["Line"] = symbolizer;
|
||||
var config = {};
|
||||
this.readChildNodes(node, config);
|
||||
if (this.multipleSymbolizers) {
|
||||
config.zIndex = this.featureTypeCounter;
|
||||
rule.symbolizers.push(
|
||||
new OpenLayers.Symbolizer.Line(config)
|
||||
);
|
||||
} else {
|
||||
rule.symbolizer["Line"] = OpenLayers.Util.applyDefaults(
|
||||
config, rule.symbolizer["Line"]
|
||||
);
|
||||
}
|
||||
},
|
||||
"PolygonSymbolizer": function(node, rule) {
|
||||
// OpenLayers doens't do painter's order, instead we extend
|
||||
var symbolizer = rule.symbolizer["Polygon"] || {};
|
||||
this.readChildNodes(node, symbolizer);
|
||||
// in case it didn't exist before
|
||||
rule.symbolizer["Polygon"] = symbolizer;
|
||||
var config = {
|
||||
fill: false,
|
||||
stroke: false
|
||||
};
|
||||
if (!this.multipleSymbolizers) {
|
||||
config = rule.symbolizer["Polygon"] || config;
|
||||
}
|
||||
this.readChildNodes(node, config);
|
||||
if (this.multipleSymbolizers) {
|
||||
config.zIndex = this.featureTypeCounter;
|
||||
rule.symbolizers.push(
|
||||
new OpenLayers.Symbolizer.Polygon(config)
|
||||
);
|
||||
} else {
|
||||
rule.symbolizer["Polygon"] = config;
|
||||
}
|
||||
},
|
||||
"PointSymbolizer": function(node, rule) {
|
||||
// OpenLayers doens't do painter's order, instead we extend
|
||||
var symbolizer = rule.symbolizer["Point"] || {};
|
||||
this.readChildNodes(node, symbolizer);
|
||||
// in case it didn't exist before
|
||||
rule.symbolizer["Point"] = symbolizer;
|
||||
var config = {
|
||||
fill: false,
|
||||
stroke: false,
|
||||
graphic: false
|
||||
};
|
||||
if (!this.multipleSymbolizers) {
|
||||
config = rule.symbolizer["Point"] || config;
|
||||
}
|
||||
this.readChildNodes(node, config);
|
||||
if (this.multipleSymbolizers) {
|
||||
config.zIndex = this.featureTypeCounter;
|
||||
rule.symbolizers.push(
|
||||
new OpenLayers.Symbolizer.Point(config)
|
||||
);
|
||||
} else {
|
||||
rule.symbolizer["Point"] = config;
|
||||
}
|
||||
},
|
||||
"Stroke": function(node, symbolizer) {
|
||||
symbolizer.stroke = true;
|
||||
@@ -258,8 +358,8 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
this.readChildNodes(node, graphic);
|
||||
// directly properties with names that match symbolizer properties
|
||||
var properties = [
|
||||
"strokeColor", "strokeWidth", "strokeOpacity",
|
||||
"strokeLinecap", "fillColor", "fillOpacity",
|
||||
"stroke", "strokeColor", "strokeWidth", "strokeOpacity",
|
||||
"strokeLinecap", "fill", "fillColor", "fillOpacity",
|
||||
"graphicName", "rotation", "graphicFormat"
|
||||
];
|
||||
var prop, value;
|
||||
@@ -534,7 +634,53 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
}
|
||||
|
||||
// add FeatureTypeStyles
|
||||
this.writeNode("FeatureTypeStyle", style, node);
|
||||
if (this.multipleSymbolizers && style.rules) {
|
||||
// group style objects by symbolizer zIndex
|
||||
var rulesByZ = {
|
||||
0: []
|
||||
};
|
||||
var zValues = [0];
|
||||
var rule, ruleMap, symbolizer, zIndex, clone;
|
||||
for (var i=0, ii=style.rules.length; i<ii; ++i) {
|
||||
rule = style.rules[i];
|
||||
if (rule.symbolizers) {
|
||||
ruleMap = {};
|
||||
for (var j=0, jj=rule.symbolizers.length; j<jj; ++j) {
|
||||
symbolizer = rule.symbolizers[j];
|
||||
zIndex = symbolizer.zIndex;
|
||||
if (!(zIndex in ruleMap)) {
|
||||
clone = rule.clone();
|
||||
clone.symbolizers = [];
|
||||
ruleMap[zIndex] = clone;
|
||||
}
|
||||
ruleMap[zIndex].symbolizers.push(symbolizer.clone());
|
||||
}
|
||||
for (zIndex in ruleMap) {
|
||||
if (!(zIndex in rulesByZ)) {
|
||||
zValues.push(zIndex);
|
||||
rulesByZ[zIndex] = [];
|
||||
}
|
||||
rulesByZ[zIndex].push(ruleMap[zIndex]);
|
||||
}
|
||||
} else {
|
||||
// no symbolizers in rule
|
||||
rulesByZ[0].push(rule.clone());
|
||||
}
|
||||
}
|
||||
// write one FeatureTypeStyle per zIndex
|
||||
zValues.sort();
|
||||
var rules;
|
||||
for (var i=0, ii=zValues.length; i<ii; ++i) {
|
||||
rules = rulesByZ[zValues[i]];
|
||||
if (rules.length > 0) {
|
||||
clone = style.clone();
|
||||
clone.rules = rulesByZ[zValues[i]];
|
||||
this.writeNode("FeatureTypeStyle", clone, node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.writeNode("FeatureTypeStyle", style, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
@@ -594,17 +740,28 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
);
|
||||
}
|
||||
|
||||
// add in symbolizers (relies on geometry type keys)
|
||||
var types = OpenLayers.Style.SYMBOLIZER_PREFIXES;
|
||||
var type, symbolizer;
|
||||
for(var i=0, len=types.length; i<len; ++i) {
|
||||
type = types[i];
|
||||
symbolizer = rule.symbolizer[type];
|
||||
if(symbolizer) {
|
||||
if (this.multipleSymbolizers && rule.symbolizers) {
|
||||
var symbolizer;
|
||||
for (var i=0, ii=rule.symbolizers.length; i<ii; ++i) {
|
||||
symbolizer = rule.symbolizers[i];
|
||||
type = symbolizer.CLASS_NAME.split(".").pop();
|
||||
this.writeNode(
|
||||
type + "Symbolizer", symbolizer, node
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// add in symbolizers (relies on geometry type keys)
|
||||
var types = OpenLayers.Style.SYMBOLIZER_PREFIXES;
|
||||
for(var i=0, len=types.length; i<len; ++i) {
|
||||
type = types[i];
|
||||
symbolizer = rule.symbolizer[type];
|
||||
if(symbolizer) {
|
||||
this.writeNode(
|
||||
type + "Symbolizer", symbolizer, node
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
|
||||
@@ -780,20 +937,54 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
return node;
|
||||
},
|
||||
"Radius": function(value) {
|
||||
return node = this.createElementNSPlus("sld:Radius", {
|
||||
return this.createElementNSPlus("sld:Radius", {
|
||||
value: value
|
||||
});
|
||||
},
|
||||
"RasterSymbolizer": function(symbolizer) {
|
||||
var node = this.createElementNSPlus("sld:RasterSymbolizer");
|
||||
if (symbolizer.geometry) {
|
||||
this.writeNode("Geometry", symbolizer.geometry, node);
|
||||
}
|
||||
if (symbolizer.opacity) {
|
||||
this.writeNode("Opacity", symbolizer.opacity, node);
|
||||
}
|
||||
if (symbolizer.colorMap) {
|
||||
this.writeNode("ColorMap", symbolizer.colorMap, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"Geometry": function(geometry) {
|
||||
var node = this.createElementNSPlus("sld:Geometry");
|
||||
if (geometry.property) {
|
||||
this.writeNode("ogc:PropertyName", geometry, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"ColorMap": function(colorMap) {
|
||||
var node = this.createElementNSPlus("sld:ColorMap");
|
||||
for (var i=0, len=colorMap.length; i<len; ++i) {
|
||||
this.writeNode("ColorMapEntry", colorMap[i], node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"ColorMapEntry": function(colorMapEntry) {
|
||||
var node = this.createElementNSPlus("sld:ColorMapEntry");
|
||||
var a = colorMapEntry;
|
||||
node.setAttribute("color", a.color);
|
||||
a.opacity !== undefined && node.setAttribute("opacity",
|
||||
parseFloat(a.opacity));
|
||||
a.quantity !== undefined && node.setAttribute("quantity",
|
||||
parseFloat(a.quantity));
|
||||
a.label !== undefined && node.setAttribute("label", a.label);
|
||||
return node;
|
||||
},
|
||||
"PolygonSymbolizer": function(symbolizer) {
|
||||
var node = this.createElementNSPlus("sld:PolygonSymbolizer");
|
||||
if(symbolizer.fillColor != undefined ||
|
||||
symbolizer.fillOpacity != undefined) {
|
||||
if(symbolizer.fill !== false) {
|
||||
this.writeNode("Fill", symbolizer, node);
|
||||
}
|
||||
if(symbolizer.strokeWidth != undefined ||
|
||||
symbolizer.strokeColor != undefined ||
|
||||
symbolizer.strokeOpacity != undefined ||
|
||||
symbolizer.strokeDashstyle != undefined) {
|
||||
if(symbolizer.stroke !== false) {
|
||||
this.writeNode("Stroke", symbolizer, node);
|
||||
}
|
||||
return node;
|
||||
@@ -859,8 +1050,12 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
if(symbolizer.graphicName) {
|
||||
this.writeNode("WellKnownName", symbolizer.graphicName, node);
|
||||
}
|
||||
this.writeNode("Fill", symbolizer, node);
|
||||
this.writeNode("Stroke", symbolizer, node);
|
||||
if (symbolizer.fill !== false) {
|
||||
this.writeNode("Fill", symbolizer, node);
|
||||
}
|
||||
if (symbolizer.stroke !== false) {
|
||||
this.writeNode("Stroke", symbolizer, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"WellKnownName": function(name) {
|
||||
@@ -901,4 +1096,4 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.SLD.v1"
|
||||
|
||||
});
|
||||
});
|
||||
@@ -115,6 +115,7 @@ OpenLayers.Format.SOSCapabilities.v1_0_0 = OpenLayers.Class(
|
||||
var id = this.getAttributeNS(node, this.namespaces.gml, "id");
|
||||
offeringList[id] = {
|
||||
procedures: [],
|
||||
observedProperties: [],
|
||||
featureOfInterestIds: [],
|
||||
responseFormats: [],
|
||||
resultModels: [],
|
||||
@@ -131,8 +132,8 @@ OpenLayers.Format.SOSCapabilities.v1_0_0 = OpenLayers.Class(
|
||||
this.namespaces.xlink, "href"));
|
||||
},
|
||||
"observedProperty": function(node, offering) {
|
||||
offering.observedProperty = this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href");
|
||||
offering.observedProperties.push(this.getAttributeNS(node,
|
||||
this.namespaces.xlink, "href"));
|
||||
},
|
||||
"featureOfInterest": function(node, offering) {
|
||||
offering.featureOfInterestIds.push(this.getAttributeNS(node,
|
||||
|
||||
@@ -88,7 +88,11 @@ OpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(
|
||||
read_cap_Name: function(obj, node) {
|
||||
var name = this.getChildValue(node);
|
||||
if(name) {
|
||||
obj.name = name;
|
||||
var parts = name.split(":");
|
||||
obj.name = parts.pop();
|
||||
if(parts.length > 0) {
|
||||
obj.featureNS = this.lookupNamespaceURI(node, parts[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -114,4 +118,4 @@ OpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.WFSCapabilities.v1"
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -105,13 +105,31 @@ OpenLayers.Format.WFST.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: read
|
||||
* APIMethod: read
|
||||
* Parse the response from a transaction. Because WFS is split into
|
||||
* Transaction requests (create, update, and delete) and GetFeature
|
||||
* requests (read), this method handles parsing of both types of
|
||||
* responses.
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String | Document} The WFST document to read
|
||||
* options - {Object} Options for the reader
|
||||
*
|
||||
* Valid options properties:
|
||||
* output - {String} either "features" or "object". The default is
|
||||
* "features", which means that the method will return an array of
|
||||
* features. If set to "object", an object with a "features" property
|
||||
* and other properties read by the parser will be returned.
|
||||
*
|
||||
* Returns:
|
||||
* {Array | Object} Output depending on the output option.
|
||||
*/
|
||||
read: function(data) {
|
||||
read: function(data, options) {
|
||||
options = options || {};
|
||||
OpenLayers.Util.applyDefaults(options, {
|
||||
output: "features"
|
||||
});
|
||||
|
||||
if(typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
@@ -122,7 +140,7 @@ OpenLayers.Format.WFST.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
if(data) {
|
||||
this.readNode(data, obj);
|
||||
}
|
||||
if(obj.features) {
|
||||
if(obj.features && options.output === "features") {
|
||||
obj = obj.features;
|
||||
}
|
||||
return obj;
|
||||
@@ -186,7 +204,14 @@ OpenLayers.Format.WFST.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
"xsi:schemaLocation": this.schemaLocationAttr(options)
|
||||
}
|
||||
});
|
||||
this.writeNode("Query", options, node);
|
||||
if (typeof this.featureType == "string") {
|
||||
this.writeNode("Query", options, node);
|
||||
} else {
|
||||
for (var i=0,len = this.featureType.length; i<len; i++) {
|
||||
options.featureType = this.featureType[i];
|
||||
this.writeNode("Query", options, node);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
},
|
||||
"Transaction": function(features) {
|
||||
|
||||
@@ -33,6 +33,12 @@ OpenLayers.Format.WFST.v1_1_0 = OpenLayers.Class(
|
||||
* Constructor: OpenLayers.Format.WFST.v1_1_0
|
||||
* A class for parsing and generating WFS v1.1.0 transactions.
|
||||
*
|
||||
* To read additional information like hit count (numberOfFeatures) from
|
||||
* the FeatureCollection, call the <OpenLayers.Format.WFST.v1.read> method
|
||||
* with {output: "object"} as 2nd argument. Note that it is possible to
|
||||
* just request the hit count from a WFS 1.1.0 server with the
|
||||
* resultType="hits" request parameter.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} Optional object whose properties will be set on the
|
||||
* instance.
|
||||
@@ -59,6 +65,12 @@ OpenLayers.Format.WFST.v1_1_0 = OpenLayers.Class(
|
||||
*/
|
||||
readers: {
|
||||
"wfs": OpenLayers.Util.applyDefaults({
|
||||
"FeatureCollection": function(node, obj) {
|
||||
obj.numberOfFeatures = parseInt(node.getAttribute(
|
||||
"numberOfFeatures"));
|
||||
OpenLayers.Format.WFST.v1.prototype.readers["wfs"]["FeatureCollection"].apply(
|
||||
this, arguments);
|
||||
},
|
||||
"TransactionResponse": function(node, obj) {
|
||||
obj.insertIds = [];
|
||||
obj.success = false;
|
||||
@@ -90,6 +102,13 @@ OpenLayers.Format.WFST.v1_1_0 = OpenLayers.Class(
|
||||
*/
|
||||
writers: {
|
||||
"wfs": OpenLayers.Util.applyDefaults({
|
||||
"GetFeature": function(options) {
|
||||
var node = OpenLayers.Format.WFST.v1.prototype.writers["wfs"]["GetFeature"].apply(this, arguments);
|
||||
options && options.resultType && this.setAttributes(node, {
|
||||
resultType: options.resultType
|
||||
});
|
||||
return node;
|
||||
},
|
||||
"Query": function(options) {
|
||||
options = OpenLayers.Util.extend({
|
||||
featureNS: this.featureNS,
|
||||
|
||||
@@ -151,7 +151,9 @@ OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
|
||||
'multipoint': function(multipoint) {
|
||||
var array = [];
|
||||
for(var i=0, len=multipoint.components.length; i<len; ++i) {
|
||||
array.push(this.extract.point.apply(this, [multipoint.components[i]]));
|
||||
array.push('(' +
|
||||
this.extract.point.apply(this, [multipoint.components[i]]) +
|
||||
')');
|
||||
}
|
||||
return array.join(',');
|
||||
},
|
||||
@@ -244,10 +246,12 @@ OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
|
||||
* @private
|
||||
*/
|
||||
'multipoint': function(str) {
|
||||
var points = OpenLayers.String.trim(str).split(',');
|
||||
var point;
|
||||
var points = OpenLayers.String.trim(str).split(this.regExes.parenComma);
|
||||
var components = [];
|
||||
for(var i=0, len=points.length; i<len; ++i) {
|
||||
components.push(this.parse.point.apply(this, [points[i]]).geometry);
|
||||
point = points[i].replace(this.regExes.trimParens, '$1');
|
||||
components.push(this.parse.point.apply(this, [point]).geometry);
|
||||
}
|
||||
return new OpenLayers.Feature.Vector(
|
||||
new OpenLayers.Geometry.MultiPoint(components)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
* @requires OpenLayers/Format/Context.js
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -13,7 +14,7 @@
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.WMC = OpenLayers.Class({
|
||||
OpenLayers.Format.WMC = OpenLayers.Class(OpenLayers.Format.Context, {
|
||||
|
||||
/**
|
||||
* APIProperty: defaultVersion
|
||||
@@ -21,98 +22,6 @@ OpenLayers.Format.WMC = OpenLayers.Class({
|
||||
*/
|
||||
defaultVersion: "1.1.0",
|
||||
|
||||
/**
|
||||
* APIProperty: version
|
||||
* {String} Specify a version string if one is known.
|
||||
*/
|
||||
version: null,
|
||||
|
||||
/**
|
||||
* Property: layerOptions
|
||||
* {Object} Default options for layers created by the parser. These
|
||||
* options are overridden by the options which are read from the
|
||||
* capabilities document.
|
||||
*/
|
||||
layerOptions: null,
|
||||
|
||||
/**
|
||||
* Property: layerParams
|
||||
* {Object} Default parameters for layers created by the parser. This
|
||||
* can be used to override DEFAULT_PARAMS for OpenLayers.Layer.WMS.
|
||||
*/
|
||||
layerParams: null,
|
||||
|
||||
/**
|
||||
* Property: parser
|
||||
* {Object} Instance of the versioned parser. Cached for multiple read and
|
||||
* write calls of the same version.
|
||||
*/
|
||||
parser: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.WMC
|
||||
* Create a new parser for WMC docs.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Util.extend(this, options);
|
||||
this.options = options;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Read WMC data from a string, and return an object with map properties
|
||||
* and a list of layers.
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
* options - {Object} The options object must contain a map property. If
|
||||
* the map property is a string, it must be the id of a dom element
|
||||
* where the new map will be placed. If the map property is an
|
||||
* <OpenLayers.Map>, the layers from the context document will be added
|
||||
* to the map. If the map property is an object, this will be
|
||||
* considered as options to create the map with, in most cases, it would
|
||||
* have a div property.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} A map based on the context.
|
||||
*/
|
||||
read: function(data, options) {
|
||||
if(typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
var root = data.documentElement;
|
||||
var version = this.version;
|
||||
if(!version) {
|
||||
version = root.getAttribute("version");
|
||||
}
|
||||
var parser = this.getParser(version);
|
||||
var context = parser.read(data, options);
|
||||
var map;
|
||||
if(options && options.map) {
|
||||
this.context = context;
|
||||
if(options.map instanceof OpenLayers.Map) {
|
||||
map = this.mergeContextToMap(context, options.map);
|
||||
} else {
|
||||
var mapOptions = options.map;
|
||||
if(OpenLayers.Util.isElement(mapOptions) ||
|
||||
typeof mapOptions == "string") {
|
||||
// we assume mapOptions references a div
|
||||
// element
|
||||
mapOptions = {div: mapOptions};
|
||||
}
|
||||
map = this.contextToMap(context, mapOptions);
|
||||
}
|
||||
} else {
|
||||
// not documented as part of the API, provided as a non-API option
|
||||
map = context;
|
||||
}
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getParser
|
||||
* Get the WMC parser given a version. Create a new parser if it does not
|
||||
@@ -138,162 +47,6 @@ OpenLayers.Format.WMC = OpenLayers.Class({
|
||||
return this.parser;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getLayerFromContext
|
||||
* Create a WMS layer from a layerContext object.
|
||||
*
|
||||
* Parameters:
|
||||
* layerContext - {Object} An object representing a WMS layer.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.WMS>} A WMS layer.
|
||||
*/
|
||||
getLayerFromContext: function(layerContext) {
|
||||
var i, len;
|
||||
// fill initial options object from layerContext
|
||||
var options = {
|
||||
queryable: layerContext.queryable, //keep queryable for api compatibility
|
||||
visibility: layerContext.visibility,
|
||||
maxExtent: layerContext.maxExtent,
|
||||
numZoomLevels: layerContext.numZoomLevels,
|
||||
units: layerContext.units,
|
||||
isBaseLayer: layerContext.isBaseLayer,
|
||||
opacity: layerContext.opacity,
|
||||
displayInLayerSwitcher: layerContext.displayInLayerSwitcher,
|
||||
singleTile: layerContext.singleTile,
|
||||
minScale: layerContext.minScale,
|
||||
maxScale: layerContext.maxScale
|
||||
};
|
||||
if (this.layerOptions) {
|
||||
OpenLayers.Util.applyDefaults(options, this.layerOptions);
|
||||
}
|
||||
|
||||
var params = {
|
||||
layers: layerContext.name,
|
||||
transparent: layerContext.transparent,
|
||||
version: layerContext.version
|
||||
};
|
||||
if (layerContext.formats && layerContext.formats.length>0) {
|
||||
// set default value for params if current attribute is not positionned
|
||||
params.format = layerContext.formats[0].value;
|
||||
for (i=0, len=layerContext.formats.length; i<len; i++) {
|
||||
var format = layerContext.formats[i];
|
||||
if (format.current == true) {
|
||||
params.format = format.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layerContext.styles && layerContext.styles.length>0) {
|
||||
for (i=0, len=layerContext.styles.length; i<len; i++) {
|
||||
var style = layerContext.styles[i];
|
||||
if (style.current == true) {
|
||||
// three style types to consider
|
||||
// 1) linked SLD
|
||||
// 2) inline SLD
|
||||
// 3) named style
|
||||
if(style.href) {
|
||||
params.sld = style.href;
|
||||
} else if(style.body) {
|
||||
params.sld_body = style.body;
|
||||
} else {
|
||||
params.styles = style.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.layerParams) {
|
||||
OpenLayers.Util.applyDefaults(params, this.layerParams);
|
||||
}
|
||||
|
||||
var layer = new OpenLayers.Layer.WMS(
|
||||
layerContext.title || layerContext.name,
|
||||
layerContext.url,
|
||||
params,
|
||||
options
|
||||
);
|
||||
return layer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getLayersFromContext
|
||||
* Create an array of WMS layers from an array of layerContext objects.
|
||||
*
|
||||
* Parameters:
|
||||
* layersContext - {Array(Object)} An array of objects representing WMS layers.
|
||||
*
|
||||
* Returns:
|
||||
* {Array(<OpenLayers.Layer.WMS>)} An array of WMS layers.
|
||||
*/
|
||||
getLayersFromContext: function(layersContext) {
|
||||
var layers = [];
|
||||
for (var i=0, len=layersContext.length; i<len; i++) {
|
||||
layers.push(this.getLayerFromContext(layersContext[i]));
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: contextToMap
|
||||
* Create a map given a context object.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} The context object.
|
||||
* options - {Object} Default map options.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} A map based on the context object.
|
||||
*/
|
||||
contextToMap: function(context, options) {
|
||||
options = OpenLayers.Util.applyDefaults({
|
||||
maxExtent: context.maxExtent,
|
||||
projection: context.projection
|
||||
}, options);
|
||||
var map = new OpenLayers.Map(options);
|
||||
map.addLayers(this.getLayersFromContext(context.layersContext));
|
||||
map.setCenter(
|
||||
context.bounds.getCenterLonLat(),
|
||||
map.getZoomForExtent(context.bounds, true)
|
||||
);
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: mergeContextToMap
|
||||
* Add layers from a context object to a map.
|
||||
*
|
||||
* Parameters:
|
||||
* context - {Object} The context object.
|
||||
* map - {<OpenLayers.Map>} The map.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Map>} The same map with layers added.
|
||||
*/
|
||||
mergeContextToMap: function(context, map) {
|
||||
map.addLayers(this.getLayersFromContext(context.layersContext));
|
||||
return map;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: write
|
||||
* Write a WMC document given a map.
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {<OpenLayers.Map> | Object} A map or context object.
|
||||
* options - {Object} Optional configuration object.
|
||||
*
|
||||
* Returns:
|
||||
* {String} A WMC document string.
|
||||
*/
|
||||
write: function(obj, options) {
|
||||
obj = this.toContext(obj);
|
||||
var version = options && options.version;
|
||||
var parser = this.getParser(version);
|
||||
var wmc = parser.write(obj, options);
|
||||
return wmc;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: layerToContext
|
||||
* Create a layer context object given a wms layer object.
|
||||
@@ -322,6 +75,8 @@ OpenLayers.Format.WMC = OpenLayers.Class({
|
||||
opacity: layer.opacity,
|
||||
displayInLayerSwitcher: layer.displayInLayerSwitcher,
|
||||
singleTile: layer.singleTile,
|
||||
tileSize: (layer.singleTile || !layer.tileSize) ?
|
||||
undefined : {width: layer.tileSize.w, height: layer.tileSize.h},
|
||||
minScale : (layer.options.resolutions ||
|
||||
layer.options.scales ||
|
||||
layer.options.maxResolution ||
|
||||
|
||||
@@ -231,6 +231,14 @@ OpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
layerContext.singleTile = (this.getChildValue(node) == "true");
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: read_ol_tileSize
|
||||
*/
|
||||
read_ol_tileSize: function(layerContext, node) {
|
||||
var obj = {"width": node.getAttribute("width"), "height": node.getAttribute("height")};
|
||||
layerContext.tileSize = obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: read_ol_isBaseLayer
|
||||
*/
|
||||
@@ -618,6 +626,14 @@ OpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
});
|
||||
node.appendChild(maxExtent);
|
||||
|
||||
if (context.tileSize && !context.singleTile) {
|
||||
var size = this.createElementNS(
|
||||
this.namespaces.ol, "ol:tileSize"
|
||||
);
|
||||
this.setAttributes(size, context.tileSize);
|
||||
node.appendChild(size);
|
||||
}
|
||||
|
||||
var properties = [
|
||||
"transparent", "numZoomLevels", "units", "isBaseLayer",
|
||||
"opacity", "displayInLayerSwitcher", "singleTile"
|
||||
|
||||
@@ -65,9 +65,9 @@ OpenLayers.Format.WMSCapabilities = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
if(!constr) {
|
||||
throw "Can't find a WMS capabilities parser for version " + version;
|
||||
}
|
||||
var parser = new constr(this.options);
|
||||
this.parser = new constr(this.options);
|
||||
}
|
||||
var capabilities = parser.read(data);
|
||||
var capabilities = this.parser.read(data);
|
||||
capabilities.version = version;
|
||||
return capabilities;
|
||||
},
|
||||
|
||||
@@ -186,7 +186,7 @@ OpenLayers.Format.WMSCapabilities.v1 = OpenLayers.Class(
|
||||
obj.title = this.getChildValue(node);
|
||||
},
|
||||
"Abstract": function(node, obj) {
|
||||
obj.abstract = this.getChildValue(node);
|
||||
obj["abstract"] = this.getChildValue(node);
|
||||
},
|
||||
"BoundingBox": function(node, obj) {
|
||||
var bbox = {};
|
||||
|
||||
@@ -55,6 +55,7 @@ OpenLayers.Format.WMSDescribeLayer.v1_1 = OpenLayers.Class(
|
||||
var root = data.documentElement;
|
||||
var children = root.childNodes;
|
||||
var describelayer = [];
|
||||
var childNode, nodeName;
|
||||
for(var i=0; i<children.length; ++i) {
|
||||
childNode = children[i];
|
||||
nodeName = childNode.nodeName;
|
||||
@@ -78,7 +79,7 @@ OpenLayers.Format.WMSDescribeLayer.v1_1 = OpenLayers.Class(
|
||||
}
|
||||
}
|
||||
// look for Query child
|
||||
query = childNode.getElementsByTagName('Query');
|
||||
var query = childNode.getElementsByTagName('Query');
|
||||
if(query.length > 0) {
|
||||
typeName = query[0].getAttribute('typeName');
|
||||
if (!typeName) {
|
||||
|
||||
@@ -229,7 +229,7 @@ OpenLayers.Format.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
var attributes = {};
|
||||
if (node.nodeType == 1) {
|
||||
var children = node.childNodes;
|
||||
n = children.length;
|
||||
var n = children.length;
|
||||
for (var i = 0; i < n; ++i) {
|
||||
var child = children[i];
|
||||
if (child.nodeType == 1) {
|
||||
@@ -270,8 +270,8 @@ OpenLayers.Format.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
}
|
||||
var feature = this.gmlFormat.parseFeature(node);
|
||||
var geometry, bounds = null;
|
||||
if (feature && feature.geometry) {
|
||||
geometry = feature.geometry.clone();
|
||||
if (feature) {
|
||||
geometry = feature.geometry && feature.geometry.clone();
|
||||
bounds = feature.bounds && feature.bounds.clone();
|
||||
feature.destroy();
|
||||
}
|
||||
|
||||
161
lib/OpenLayers/Format/WMTSCapabilities.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/* Copyright (c) 2006-2009 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.WMTSCapabilities
|
||||
* Read WMTS Capabilities.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
/**
|
||||
* APIProperty: defaultVersion
|
||||
* {String} Version number to assume if none found. Default is "1.0.0".
|
||||
*/
|
||||
defaultVersion: "1.0.0",
|
||||
|
||||
/**
|
||||
* APIProperty: version
|
||||
* {String} Specify a version string if one is known.
|
||||
*/
|
||||
version: null,
|
||||
|
||||
/**
|
||||
* Property: parser
|
||||
* {<OpenLayers.Format>} A cached versioned format used for reading.
|
||||
*/
|
||||
parser: null,
|
||||
|
||||
/**
|
||||
* APIProperty: yx
|
||||
* {Object} Members in the yx object are used to determine if a CRS URN
|
||||
* corresponds to a CRS with y,x axis order. Member names are CRS URNs
|
||||
* and values are boolean. By default, the following CRS URN are
|
||||
* assumed to correspond to a CRS with y,x axis order:
|
||||
*
|
||||
* * urn:ogc:def:crs:EPSG::4326
|
||||
*/
|
||||
yx: {
|
||||
"urn:ogc:def:crs:EPSG::4326": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.WMTSCapabilities
|
||||
* Create a new parser for WMTS capabilities.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
|
||||
this.options = options;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Read capabilities data from a string, and return information about
|
||||
* the service (offering and observedProperty mostly).
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} Info about the WMTS Capabilities
|
||||
*/
|
||||
read: function(data) {
|
||||
if (typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
var root = data.documentElement;
|
||||
var version = this.version || root.getAttribute("version") || this.defaultVersion;
|
||||
if (!this.parser || this.parser.version !== version) {
|
||||
var constr = OpenLayers.Format.WMTSCapabilities[
|
||||
"v" + version.replace(/\./g, "_")
|
||||
];
|
||||
if (!constr) {
|
||||
throw new Error("Can't find a WMTS capabilities parser for version " + version);
|
||||
}
|
||||
this.parser = new constr(this.options);
|
||||
}
|
||||
return this.parser.read(data);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: createLayer
|
||||
* Create a WMTS layer given a capabilities object.
|
||||
*
|
||||
* Parameters:
|
||||
* capabilities - {Object} The object returned from a <read> call to this
|
||||
* format.
|
||||
* config - {Object} Configuration properties for the layer. Defaults for
|
||||
* the layer will apply if not provided.
|
||||
*
|
||||
* Required config properties:
|
||||
* layer - {String} The layer identifier.
|
||||
* matrixSet - {String} The matrix set identifier.
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.WMTS>} A properly configured WMTS layer. Throws an
|
||||
* error if an incomplete config is provided. Returns undefined if no
|
||||
* layer could be created with the provided config.
|
||||
*/
|
||||
createLayer: function(capabilities, config) {
|
||||
var layer;
|
||||
|
||||
// confirm required properties are supplied in config
|
||||
var required = {
|
||||
layer: true,
|
||||
matrixSet: true
|
||||
};
|
||||
for (var prop in required) {
|
||||
if (!(prop in config)) {
|
||||
throw new Error("Missing property '" + prop + "' in layer configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
var contents = capabilities.contents;
|
||||
var matrixSet = contents.tileMatrixSets[config.matrixSet];
|
||||
|
||||
// find the layer definition with the given identifier
|
||||
var layers = contents.layers;
|
||||
var layerDef;
|
||||
for (var i=0, ii=contents.layers.length; i<ii; ++i) {
|
||||
if (contents.layers[i].identifier === config.layer) {
|
||||
layerDef = contents.layers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (layerDef && matrixSet) {
|
||||
// get the default style for the layer
|
||||
var style;
|
||||
for (var i=0, ii=layerDef.styles.length; i<ii; ++i) {
|
||||
style = layerDef.styles[i];
|
||||
if (style.isDefault) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
layer = new OpenLayers.Layer.WMTS(
|
||||
OpenLayers.Util.applyDefaults(config, {
|
||||
url: capabilities.operationsMetadata.GetTile.dcp.http.get,
|
||||
name: layerDef.title,
|
||||
style: style,
|
||||
matrixIds: matrixSet.matrixIds
|
||||
})
|
||||
);
|
||||
}
|
||||
return layer;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.WMTSCapabilities"
|
||||
|
||||
});
|
||||
220
lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js
Normal file
@@ -0,0 +1,220 @@
|
||||
/* Copyright (c) 2006-2009 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/WMTSCapabilities.js
|
||||
* @requires OpenLayers/Format/OWSCommon/v1_1_0.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Format.WMTSCapabilities.v1_0_0
|
||||
* Read WMTS Capabilities version 1.0.0.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.WMTSCapabilities>
|
||||
*/
|
||||
OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class(
|
||||
OpenLayers.Format.OWSCommon.v1_1_0, {
|
||||
|
||||
/**
|
||||
* Property: version
|
||||
* {String} The parser version ("1.0.0").
|
||||
*/
|
||||
version: "1.0.0",
|
||||
|
||||
/**
|
||||
* Property: namespaces
|
||||
* {Object} Mapping of namespace aliases to namespace URIs.
|
||||
*/
|
||||
namespaces: {
|
||||
ows: "http://www.opengis.net/ows/1.1",
|
||||
wmts: "http://www.opengis.net/wmts/1.0",
|
||||
xlink: "http://www.w3.org/1999/xlink"
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: yx
|
||||
* {Object} Members in the yx object are used to determine if a CRS URN
|
||||
* corresponds to a CRS with y,x axis order. Member names are CRS URNs
|
||||
* and values are boolean. Defaults come from the
|
||||
* <OpenLayers.Format.WMTSCapabilities> prototype.
|
||||
*/
|
||||
yx: null,
|
||||
|
||||
/**
|
||||
* Property: defaultPrefix
|
||||
* {String} The default namespace alias for creating element nodes.
|
||||
*/
|
||||
defaultPrefix: "wmts",
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.WMTSCapabilities.v1_0_0
|
||||
* Create a new parser for WMTS capabilities version 1.0.0.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
|
||||
this.options = options;
|
||||
var yx = OpenLayers.Util.extend(
|
||||
{}, OpenLayers.Format.WMTSCapabilities.prototype.yx
|
||||
);
|
||||
this.yx = OpenLayers.Util.extend(yx, this.yx);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Read capabilities data from a string, and return info about the WMTS.
|
||||
*
|
||||
* Parameters:
|
||||
* data - {String} or {DOMElement} data to read/parse.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} Information about the SOS service.
|
||||
*/
|
||||
read: function(data) {
|
||||
if(typeof data == "string") {
|
||||
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
|
||||
}
|
||||
if(data && data.nodeType == 9) {
|
||||
data = data.documentElement;
|
||||
}
|
||||
var capabilities = {};
|
||||
this.readNode(data, capabilities);
|
||||
capabilities.version = this.version;
|
||||
return capabilities;
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: readers
|
||||
* Contains public functions, grouped by namespace prefix, that will
|
||||
* be applied when a namespaced node is found matching the function
|
||||
* name. The function will be applied in the scope of this parser
|
||||
* with two arguments: the node being read and a context object passed
|
||||
* from the parent.
|
||||
*/
|
||||
readers: {
|
||||
"wmts": {
|
||||
"Capabilities": function(node, obj) {
|
||||
this.readChildNodes(node, obj);
|
||||
},
|
||||
"Contents": function(node, obj) {
|
||||
obj.contents = {};
|
||||
obj.contents.layers = [];
|
||||
obj.contents.tileMatrixSets = {};
|
||||
this.readChildNodes(node, obj.contents);
|
||||
},
|
||||
"Layer": function(node, obj) {
|
||||
var layer = {
|
||||
styles: [],
|
||||
formats: [],
|
||||
tileMatrixSetLinks: []
|
||||
};
|
||||
layer.layers = [];
|
||||
this.readChildNodes(node, layer);
|
||||
obj.layers.push(layer);
|
||||
},
|
||||
"Style": function(node, obj) {
|
||||
var style = {};
|
||||
style.isDefault = (node.getAttribute("isDefault") === "true");
|
||||
this.readChildNodes(node, style);
|
||||
obj.styles.push(style);
|
||||
},
|
||||
"Format": function(node, obj) {
|
||||
obj.formats.push(this.getChildValue(node));
|
||||
},
|
||||
"TileMatrixSetLink": function(node, obj) {
|
||||
var tileMatrixSetLink = {};
|
||||
this.readChildNodes(node, tileMatrixSetLink);
|
||||
obj.tileMatrixSetLinks.push(tileMatrixSetLink);
|
||||
},
|
||||
"TileMatrixSet": function(node, obj) {
|
||||
// node could be child of wmts:Contents or wmts:TileMatrixSetLink
|
||||
// duck type wmts:Contents by looking for layers
|
||||
if (obj.layers) {
|
||||
// TileMatrixSet as object type in schema
|
||||
var tileMatrixSet = {
|
||||
matrixIds: []
|
||||
};
|
||||
this.readChildNodes(node, tileMatrixSet);
|
||||
obj.tileMatrixSets[tileMatrixSet.identifier] = tileMatrixSet;
|
||||
} else {
|
||||
// TileMatrixSet as string type in schema
|
||||
obj.tileMatrixSet = this.getChildValue(node);
|
||||
}
|
||||
},
|
||||
"TileMatrix": function(node, obj) {
|
||||
var tileMatrix = {
|
||||
supportedCRS: obj.supportedCRS
|
||||
};
|
||||
this.readChildNodes(node, tileMatrix);
|
||||
obj.matrixIds.push(tileMatrix);
|
||||
},
|
||||
"ScaleDenominator": function(node, obj) {
|
||||
obj.scaleDenominator = parseFloat(this.getChildValue(node));
|
||||
},
|
||||
"TopLeftCorner": function(node, obj) {
|
||||
var topLeftCorner = this.getChildValue(node);
|
||||
var coords = topLeftCorner.split(" ");
|
||||
// decide on axis order for the given CRS
|
||||
var yx;
|
||||
if (obj.supportedCRS) {
|
||||
// extract out version from URN
|
||||
var crs = obj.supportedCRS.replace(
|
||||
/urn:ogc:def:crs:(\w+):.+:(\w+)$/,
|
||||
"urn:ogc:def:crs:$1::$2"
|
||||
);
|
||||
yx = !!this.yx[crs];
|
||||
}
|
||||
if (yx) {
|
||||
obj.topLeftCorner = new OpenLayers.LonLat(
|
||||
coords[1], coords[0]
|
||||
);
|
||||
} else {
|
||||
obj.topLeftCorner = new OpenLayers.LonLat(
|
||||
coords[0], coords[1]
|
||||
);
|
||||
}
|
||||
},
|
||||
"TileWidth": function(node, obj) {
|
||||
obj.tileWidth = parseInt(this.getChildValue(node));
|
||||
},
|
||||
"TileHeight": function(node, obj) {
|
||||
obj.tileHeight = parseInt(this.getChildValue(node));
|
||||
},
|
||||
"MatrixWidth": function(node, obj) {
|
||||
obj.matrixWidth = parseInt(this.getChildValue(node));
|
||||
},
|
||||
"MatrixHeight": function(node, obj) {
|
||||
obj.matrixHeight = parseInt(this.getChildValue(node));
|
||||
},
|
||||
// not used for now, can be added in the future though
|
||||
/*"Themes": function(node, obj) {
|
||||
obj.themes = [];
|
||||
this.readChildNodes(node, obj.themes);
|
||||
},
|
||||
"Theme": function(node, obj) {
|
||||
var theme = {};
|
||||
this.readChildNodes(node, theme);
|
||||
obj.push(theme);
|
||||
},*/
|
||||
"WSDL": function(node, obj) {
|
||||
obj.wsdl = {};
|
||||
obj.wsdl.href = node.getAttribute("xlink:href");
|
||||
// TODO: other attributes of <WSDL> element
|
||||
},
|
||||
"ServiceMetadataURL": function(node, obj) {
|
||||
obj.serviceMetadataUrl = {};
|
||||
obj.serviceMetadataUrl.href = node.getAttribute("xlink:href");
|
||||
// TODO: other attributes of <ServiceMetadataURL> element
|
||||
}
|
||||
},
|
||||
"ows": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.WMTSCapabilities.v1_0_0"
|
||||
|
||||
});
|
||||