diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/apidoc_config/Menu.txt b/apidoc_config/Menu.txt index 5db99243..af9eea3b 100644 --- a/apidoc_config/Menu.txt +++ b/apidoc_config/Menu.txt @@ -79,9 +79,7 @@ Group: OpenLayers { File: LayerSwitcher (no auto-title, OpenLayers/Control/LayerSwitcher.js) File: Measure (no auto-title, OpenLayers/Control/Measure.js) File: ModifyFeature (no auto-title, OpenLayers/Control/ModifyFeature.js) - File: MouseDefaults (no auto-title, OpenLayers/Control/MouseDefaults.js) File: MousePosition (no auto-title, OpenLayers/Control/MousePosition.js) - File: MouseToolbar (no auto-title, OpenLayers/Control/MouseToolbar.js) File: Navigation (no auto-title, OpenLayers/Control/Navigation.js) File: NavigationHistory (no auto-title, OpenLayers/Control/NavigationHistory.js) File: NavToolbar (no auto-title, OpenLayers/Control/NavToolbar.js) @@ -319,7 +317,6 @@ Group: OpenLayers { File: KaMapCache (no auto-title, OpenLayers/Layer/KaMapCache.js) File: MapGuide (no auto-title, OpenLayers/Layer/MapGuide.js) File: MapServer (no auto-title, OpenLayers/Layer/MapServer.js) - File: MapServer.Untiled (no auto-title, OpenLayers/Layer/MapServer/Untiled.js) File: Markers (no auto-title, OpenLayers/Layer/Markers.js) File: MultiMap (no auto-title, OpenLayers/Layer/MultiMap.js) File: PointTrack (no auto-title, OpenLayers/Layer/PointTrack.js) @@ -330,9 +327,7 @@ Group: OpenLayers { File: Vector (no auto-title, OpenLayers/Layer/Vector.js) File: Vector.RootContainer (no auto-title, OpenLayers/Layer/Vector/RootContainer.js) File: VirtualEarth (no auto-title, OpenLayers/Layer/VirtualEarth.js) - File: WFS (no auto-title, OpenLayers/Layer/WFS.js) File: WMS (no auto-title, OpenLayers/Layer/WMS.js) - File: WMS.Untiled (no auto-title, OpenLayers/Layer/WMS/Untiled.js) File: WMS.Post (no auto-title, OpenLayers/Layer/WMS/Post.js) File: WorldWind (no auto-title, OpenLayers/Layer/WorldWind.js) File: Yahoo (no auto-title, OpenLayers/Layer/Yahoo.js) diff --git a/authors.txt b/authors.txt index fa31dac6..c92f258d 100644 --- a/authors.txt +++ b/authors.txt @@ -1,12 +1,12 @@ ahocevar = ahocevar -bartvde = bartvde +bartvde = bartvde crschmidt = crschmidt elemoine = Éric Lemoine euzuro = euzuro follower = follower fredj = Frédéric Junod jrf = jrf -pagameba = pagameba -pgiraud = pgiraud -sderle = sderle -tschaub = tschaub +pagameba = Paul Spencer +pgiraud = pgiraud +sderle = Schuyler Erle +tschaub = Tim Schaub diff --git a/build/build.py b/build/build.py index 45c41da7..0f46a035 100755 --- a/build/build.py +++ b/build/build.py @@ -4,47 +4,51 @@ 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 - -sourceDirectory = "../lib" -configFilename = "full.cfg" -outputFilename = "OpenLayers.js" - -if len(sys.argv) > 1: - configFilename = sys.argv[1] - extension = configFilename[-4:] - - if extension != ".cfg": - configFilename = sys.argv[1] + ".cfg" - -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 "Writing to %s." % outputFilename -file(outputFilename, "w").write(minimized) - -print "Done." + 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" + + if len(sys.argv) > 1: + configFilename = sys.argv[1] + extension = configFilename[-4:] + + if extension != ".cfg": + configFilename = sys.argv[1] + ".cfg" + + 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 "Writing to %s." % outputFilename + file(outputFilename, "w").write(minimized) + + print "Done." + +if __name__ == '__main__': + build() \ No newline at end of file diff --git a/doc/customization b/doc/customization index f4b5b98a..0209e661 100644 --- a/doc/customization +++ b/doc/customization @@ -4,10 +4,6 @@ Customizing OpenLayers OpenLayers is designed to fit many needs -- fitting in alongside all kinds of various applications which are currently in use. -Currently, OpenLayers supports a 'theme' option when creating a map. This -theme option allows you to specify the location of a CSS theme which should -be included. - A default theme is available as an example in the theme/ directory: the setup is: diff --git a/doc_config/Menu.txt b/doc_config/Menu.txt index 5db99243..af9eea3b 100644 --- a/doc_config/Menu.txt +++ b/doc_config/Menu.txt @@ -79,9 +79,7 @@ Group: OpenLayers { File: LayerSwitcher (no auto-title, OpenLayers/Control/LayerSwitcher.js) File: Measure (no auto-title, OpenLayers/Control/Measure.js) File: ModifyFeature (no auto-title, OpenLayers/Control/ModifyFeature.js) - File: MouseDefaults (no auto-title, OpenLayers/Control/MouseDefaults.js) File: MousePosition (no auto-title, OpenLayers/Control/MousePosition.js) - File: MouseToolbar (no auto-title, OpenLayers/Control/MouseToolbar.js) File: Navigation (no auto-title, OpenLayers/Control/Navigation.js) File: NavigationHistory (no auto-title, OpenLayers/Control/NavigationHistory.js) File: NavToolbar (no auto-title, OpenLayers/Control/NavToolbar.js) @@ -319,7 +317,6 @@ Group: OpenLayers { File: KaMapCache (no auto-title, OpenLayers/Layer/KaMapCache.js) File: MapGuide (no auto-title, OpenLayers/Layer/MapGuide.js) File: MapServer (no auto-title, OpenLayers/Layer/MapServer.js) - File: MapServer.Untiled (no auto-title, OpenLayers/Layer/MapServer/Untiled.js) File: Markers (no auto-title, OpenLayers/Layer/Markers.js) File: MultiMap (no auto-title, OpenLayers/Layer/MultiMap.js) File: PointTrack (no auto-title, OpenLayers/Layer/PointTrack.js) @@ -330,9 +327,7 @@ Group: OpenLayers { File: Vector (no auto-title, OpenLayers/Layer/Vector.js) File: Vector.RootContainer (no auto-title, OpenLayers/Layer/Vector/RootContainer.js) File: VirtualEarth (no auto-title, OpenLayers/Layer/VirtualEarth.js) - File: WFS (no auto-title, OpenLayers/Layer/WFS.js) File: WMS (no auto-title, OpenLayers/Layer/WMS.js) - File: WMS.Untiled (no auto-title, OpenLayers/Layer/WMS/Untiled.js) File: WMS.Post (no auto-title, OpenLayers/Layer/WMS/Post.js) File: WorldWind (no auto-title, OpenLayers/Layer/WorldWind.js) File: Yahoo (no auto-title, OpenLayers/Layer/Yahoo.js) diff --git a/examples/all-overlays-google.html b/examples/all-overlays-google.html new file mode 100644 index 00000000..cc3e2da0 --- /dev/null +++ b/examples/all-overlays-google.html @@ -0,0 +1,29 @@ + + + + OpenLayers All Overlays with Google and OSM + + + + + + + + +

All Overlays with Google and OSM

+

+ Using the Google and OSM layers as overlays. +

+
+
+

+ 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. +

+ See the + all-overlays-google.js source to see how this is done. +

+
+ + diff --git a/examples/all-overlays-google.js b/examples/all-overlays-google.js new file mode 100644 index 00000000..f26d3fc8 --- /dev/null +++ b/examples/all-overlays-google.js @@ -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(); + +} diff --git a/examples/baseLayers.html b/examples/baseLayers.html index 32073b57..4494a97f 100644 --- a/examples/baseLayers.html +++ b/examples/baseLayers.html @@ -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); }; diff --git a/examples/custom-control-point.html b/examples/custom-control-point.html index 3c3f6600..c4b65438 100644 --- a/examples/custom-control-point.html +++ b/examples/custom-control-point.html @@ -11,7 +11,7 @@ var map, layer; function init(){ - map = new OpenLayers.Map( $('map') ); + map = new OpenLayers.Map('map'); layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); @@ -20,7 +20,7 @@ OpenLayers.Util.extend(control, { draw: function () { // this Handler.Point will intercept the shift-mousedown - // before Control.MouseDefault gets to see it + // before Control.Navigation gets to see it this.point = new OpenLayers.Handler.Point( control, {"done": this.notice}, {keyMask: OpenLayers.Handler.MOD_SHIFT}); diff --git a/examples/custom-control.html b/examples/custom-control.html index 8164a5b5..0cfbb051 100644 --- a/examples/custom-control.html +++ b/examples/custom-control.html @@ -19,7 +19,7 @@ OpenLayers.Util.extend(control, { draw: function () { // this Handler.Box will intercept the shift-mousedown - // before Control.MouseDefault gets to see it + // before Control.Navigation gets to see it this.box = new OpenLayers.Handler.Box( control, {"done": this.notice}, {keyMask: OpenLayers.Handler.MOD_SHIFT}); diff --git a/examples/filter-strategy.html b/examples/filter-strategy.html new file mode 100644 index 00000000..0bc4c170 --- /dev/null +++ b/examples/filter-strategy.html @@ -0,0 +1,48 @@ + + + + OpenLayers Filter Strategy Example + + + + + + + + + +

Filter Strategy

+

+ Demonstrates the filter strategy for limiting features passed to the layer. +

+
+ + + +

+
+

+ This example uses a filter strategy to limit the features that are passed + to a layer. Features bound for this layer have a when 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 when values, calling setFilter + on the strategy with an updated filter. +

+ View the filter-strategy.js + source to see how this is done +

+
+ + diff --git a/examples/filter-strategy.js b/examples/filter-strategy.js new file mode 100644 index 00000000..1c7802c1 --- /dev/null +++ b/examples/filter-strategy.js @@ -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; + } +} + diff --git a/examples/getfeatureinfo-control.html b/examples/getfeatureinfo-control.html index 4943cdb7..6fd0abdc 100644 --- a/examples/getfeatureinfo-control.html +++ b/examples/getfeatureinfo-control.html @@ -121,7 +121,7 @@ highlightLayer.addFeatures(evt.features); highlightLayer.redraw(); } else { - $('responseText').innerHTML = evt.text; + OpenLayers.Util.getElement('responseText').innerHTML = evt.text; } } diff --git a/examples/google-v3-alloverlays.html b/examples/google-v3-alloverlays.html new file mode 100644 index 00000000..08b360b2 --- /dev/null +++ b/examples/google-v3-alloverlays.html @@ -0,0 +1,28 @@ + + + + OpenLayers Google (v3) Layer Example + + + + + + + + +

Google (v3) allOverlays Layer Example

+

+ Demonstrate use the Google Maps v3 API with allOverlays set to true on the map. +

+
+
+

+ 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 + google-v3-alloverlays.js source + to see how this is done. +

+
+ + diff --git a/examples/google-v3-alloverlays.js b/examples/google-v3-alloverlays.js new file mode 100644 index 00000000..e2e4da43 --- /dev/null +++ b/examples/google-v3-alloverlays.js @@ -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); +} diff --git a/examples/google-v3.html b/examples/google-v3.html new file mode 100644 index 00000000..0b650739 --- /dev/null +++ b/examples/google-v3.html @@ -0,0 +1,32 @@ + + + + OpenLayers Google (v3) Layer Example + + + + + + + + +

Google (v3) Layer Example

+

+ Demonstrate use the Google Maps v3 API. +

+
+
+

+ 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 + google-v3.js source + to see how this is done. +

+ In order to position the Google attribution div in the default + location, you must include the extra theme/default/google.css + stylesheet. +

+
+ + diff --git a/examples/google-v3.js b/examples/google-v3.js new file mode 100644 index 00000000..9c173e31 --- /dev/null +++ b/examples/google-v3.js @@ -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); +} diff --git a/examples/graticule.html b/examples/graticule.html index ed441cd6..f133225c 100644 --- a/examples/graticule.html +++ b/examples/graticule.html @@ -23,19 +23,20 @@ + + + +

Parsing gx:Track in KML

+

+ Demonstrates parsing of gx:Track elements from KML. +

+
+
+

+ If a KML document contains <gx:Track> + 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 <when> element from + the track. +

+

+ View the kml-track.js + source to see how this is done. +

+ + diff --git a/examples/kml-track.js b/examples/kml-track.js new file mode 100644 index 00000000..56698472 --- /dev/null +++ b/examples/kml-track.js @@ -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 + }); + +}; + diff --git a/examples/kml-track.kml b/examples/kml-track.kml new file mode 100644 index 00000000..2ab90aed --- /dev/null +++ b/examples/kml-track.kml @@ -0,0 +1,3359 @@ + + + + + + 2010-05-01T13:00:00-05:00 + + -93.2207 + 44.882 + 50000 + 0 + 0 + + + + + + +Flight Tracks + + Arrivals + + B752 + A + DAL2973 + #arrival + + + E170 + A + TCF7521 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:04-05 + 2010-05-01T13:00:09-05 + 2010-05-01T13:00:13-05 + 2010-05-01T13:00:18-05 + 2010-05-01T13:00:23-05 + 2010-05-01T13:00:27-05 + 2010-05-01T13:00:32-05 + 2010-05-01T13:00:37-05 + 2010-05-01T13:00:41-05 + 2010-05-01T13:00:46-05 + 2010-05-01T13:00:51-05 + 2010-05-01T13:00:55-05 + 2010-05-01T13:01:00-05 + 2010-05-01T13:01:05-05 + 2010-05-01T13:01:09-05 + 2010-05-01T13:01:14-05 + 2010-05-01T13:01:19-05 + 2010-05-01T13:01:23-05 + 2010-05-01T13:01:28-05 + 2010-05-01T13:01:33-05 + 2010-05-01T13:01:37-05 + 2010-05-01T13:01:42-05 + 2010-05-01T13:01:47-05 + 2010-05-01T13:01:51-05 + 2010-05-01T13:01:56-05 + 2010-05-01T13:02:00-05 + 2010-05-01T13:02:05-05 + 2010-05-01T13:02:10-05 + 2010-05-01T13:02:14-05 + 2010-05-01T13:02:19-05 + 2010-05-01T13:02:24-05 + 2010-05-01T13:02:28-05 + 2010-05-01T13:02:33-05 + 2010-05-01T13:02:38-05 + 2010-05-01T13:02:42-05 + 2010-05-01T13:02:47-05 + 2010-05-01T13:02:52-05 + 2010-05-01T13:02:56-05 + 2010-05-01T13:03:01-05 + 2010-05-01T13:03:06-05 + 2010-05-01T13:03:10-05 + 2010-05-01T13:03:15-05 + 2010-05-01T13:03:20-05 + 2010-05-01T13:03:24-05 + 2010-05-01T13:03:29-05 + 2010-05-01T13:03:33-05 + 2010-05-01T13:03:38-05 + 2010-05-01T13:03:43-05 + 2010-05-01T13:03:47-05 + 2010-05-01T13:03:52-05 + 2010-05-01T13:03:57-05 + 2010-05-01T13:04:01-05 + 2010-05-01T13:04:06-05 + 2010-05-01T13:04:11-05 + 2010-05-01T13:04:15-05 + 2010-05-01T13:04:20-05 + 2010-05-01T13:04:24-05 + 2010-05-01T13:04:29-05 + 2010-05-01T13:04:34-05 + 2010-05-01T13:04:38-05 + 2010-05-01T13:04:43-05 + 2010-05-01T13:04:48-05 + 2010-05-01T13:04:52-05 + 2010-05-01T13:04:57-05 + 2010-05-01T13:05:00-05 + -93.3806146339391 44.8823651507134 2743 + -93.3773041814209 44.887531728655 2743 + -93.3742856469083 44.8942041806778 2743 + -93.3722375106026 44.9009231720158 2743 + -93.3711934089417 44.9077495987718 2712 + -93.3707288919852 44.9145219645156 2712 + -93.3703882714439 44.921240089024 2682 + -93.3700882719793 44.9278850664392 2682 + -93.369810041597 44.934389356737 2651 + -93.3696836566166 44.9408553642446 2651 + -93.3695425129226 44.9473561165969 2621 + -93.3693185423471 44.9537360442564 2621 + -93.3693194298816 44.9599975904123 2590 + -93.3694031671108 44.9661411653607 2590 + -93.3693840701674 44.9721433662718 2560 + -93.3692180132117 44.9781295444861 2530 + -93.3691451194519 44.9840448037796 2530 + -93.3691016671806 44.9899713582099 2499 + -93.3689494749454 44.9958413836039 2469 + -93.3687664425911 45.0015898503441 2469 + -93.3686331392066 45.0072067405394 2438 + -93.368599726987 45.0127741072778 2438 + -93.3686335399802 45.0181909829245 2408 + -93.3686494842522 45.0234209328517 2377 + -93.3684675008434 45.0286421277802 2377 + -93.3683004008135 45.0337736830037 2347 + -93.3682154531592 45.0388787100883 2347 + -93.3683732351584 45.0439463933312 2316 + -93.3684142261585 45.0490625635571 2286 + -93.368143196103 45.0541794203461 2286 + -93.367535632513 45.0592327492686 2255 + -93.3659957839062 45.0642802941983 2225 + -93.3633687278349 45.0690971409498 2194 + -93.3595471289752 45.0735562314314 2164 + -93.354507806741 45.0775832626329 2133 + -93.3485772854268 45.0808293296313 2103 + -93.3421088995911 45.0832469498159 2072 + -93.3351951799649 45.0848109253641 2042 + -93.3280418232705 45.0854246893649 2011 + -93.3209037884868 45.085161376704 1981 + -93.3144723535558 45.0839515303103 1920 + -93.3088086501455 45.0819151336509 1859 + -93.3036917357871 45.0792511074707 1828 + -93.2993102013018 45.0761649196153 1798 + -93.2958637974439 45.0728030913231 1768 + -93.2932247031583 45.0693710694135 1737 + -93.2910486937635 45.0659261208859 1707 + -93.2888955993508 45.0625213360315 1646 + -93.2867217490801 45.0591551785287 1615 + -93.2847336413534 45.0557231883841 1554 + -93.28312407167 45.0523278244803 1493 + -93.2820244198825 45.0489932635616 1463 + -93.280973634799 45.045699024227 1432 + -93.2799787649067 45.0423671615142 1402 + -93.2791066054659 45.0390946347227 1341 + -93.2784127726862 45.0358634874951 1310 + -93.2779112647802 45.0326008999249 1249 + -93.2774525889269 45.029330264578 1219 + -93.2770784201422 45.0260213245381 1188 + -93.2766188240203 45.0227403501287 1158 + -93.275816823547 45.0195461585342 1127 + -93.2748914840222 45.0163603671711 1066 + -93.2740540575136 45.0131542183389 1036 + -93.2733145981662 45.010040506328 1006 + -93.2724700860766 45.0070495365802 975 + -93.2720166974715 45.0052389419128 957 + 20 0 0 + 20 0 0 + 20 0 0 + 10 0 0 + 10 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 10 0 0 + 20 0 0 + 30 0 0 + 40 0 0 + 50 0 0 + 60 0 0 + 70 0 0 + 80 0 0 + 90 0 0 + 100 0 0 + 110 0 0 + 120 0 0 + 130 0 0 + 140 0 0 + 150 0 0 + 150 0 0 + 150 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 376 + 367 + 361 + 371 + 367 + 363 + 359 + 356 + 352 + 347 + 343 + 339 + 334 + 329 + 326 + 321 + 318 + 315 + 311 + 307 + 301 + 294 + 289 + 295 + 280 + 277 + 287 + 275 + 275 + 276 + 277 + 279 + 281 + 282 + 282 + 281 + 280 + 274 + 266 + 260 + 254 + 244 + 235 + 235 + 219 + 212 + 214 + 201 + 197 + 193 + 190 + 187 + 183 + 180 + 186 + 178 + 177 + 183 + 177 + 176 + 175 + 173 + 171 + 165 + 166 + 167 + + + BE33 + A + N38175 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:02-05 + 2010-05-01T13:00:07-05 + 2010-05-01T13:00:12-05 + 2010-05-01T13:00:16-05 + 2010-05-01T13:00:21-05 + 2010-05-01T13:00:25-05 + 2010-05-01T13:00:30-05 + 2010-05-01T13:00:35-05 + 2010-05-01T13:00:39-05 + 2010-05-01T13:00:44-05 + 2010-05-01T13:00:49-05 + 2010-05-01T13:00:53-05 + 2010-05-01T13:00:58-05 + 2010-05-01T13:01:03-05 + 2010-05-01T13:01:07-05 + 2010-05-01T13:01:12-05 + 2010-05-01T13:01:16-05 + 2010-05-01T13:01:21-05 + 2010-05-01T13:01:26-05 + 2010-05-01T13:01:30-05 + 2010-05-01T13:01:35-05 + 2010-05-01T13:01:40-05 + 2010-05-01T13:01:44-05 + 2010-05-01T13:01:49-05 + 2010-05-01T13:01:54-05 + 2010-05-01T13:01:58-05 + 2010-05-01T13:02:03-05 + 2010-05-01T13:02:08-05 + 2010-05-01T13:02:12-05 + 2010-05-01T13:02:17-05 + 2010-05-01T13:02:21-05 + 2010-05-01T13:02:26-05 + 2010-05-01T13:02:31-05 + 2010-05-01T13:02:35-05 + 2010-05-01T13:02:40-05 + 2010-05-01T13:02:45-05 + 2010-05-01T13:02:49-05 + 2010-05-01T13:02:54-05 + 2010-05-01T13:02:59-05 + 2010-05-01T13:03:03-05 + 2010-05-01T13:03:08-05 + 2010-05-01T13:03:13-05 + 2010-05-01T13:03:17-05 + 2010-05-01T13:03:22-05 + 2010-05-01T13:03:27-05 + 2010-05-01T13:03:31-05 + 2010-05-01T13:03:36-05 + 2010-05-01T13:03:40-05 + 2010-05-01T13:03:45-05 + 2010-05-01T13:03:50-05 + 2010-05-01T13:03:54-05 + 2010-05-01T13:03:59-05 + 2010-05-01T13:04:04-05 + 2010-05-01T13:04:08-05 + 2010-05-01T13:04:13-05 + 2010-05-01T13:04:18-05 + 2010-05-01T13:04:22-05 + 2010-05-01T13:04:27-05 + 2010-05-01T13:04:32-05 + 2010-05-01T13:04:36-05 + 2010-05-01T13:04:41-05 + 2010-05-01T13:04:46-05 + 2010-05-01T13:04:50-05 + 2010-05-01T13:04:55-05 + 2010-05-01T13:04:59-05 + 2010-05-01T13:05:00-05 + -93.0144637208028 44.6541474764804 1006 + -93.0162681345228 44.6547274296664 1006 + -93.0196734868835 44.6559915702004 975 + -93.0231899415297 44.657188463998 945 + -93.0267619421777 44.6582849847887 945 + -93.0302021384369 44.6594728216183 914 + -93.0338776768471 44.6606515995762 914 + -93.0375866343814 44.6618806707998 884 + -93.0411146687035 44.6632657982455 884 + -93.0447829038862 44.6646495821585 884 + -93.0486933143218 44.6659856209571 914 + -93.0525604964428 44.6672664774449 884 + -93.0559892061682 44.6686325276705 884 + -93.0595122787868 44.6700360197293 884 + -93.0633002358996 44.6714677760105 884 + -93.0669378047758 44.6729112967405 884 + -93.0703945562928 44.6742924439153 884 + -93.0739155391788 44.675662416586 853 + -93.0775155708379 44.677089176175 853 + -93.0809933799389 44.6786451836444 884 + -93.0844890660754 44.6803751966183 884 + -93.0880299182291 44.6822044360867 884 + -93.0915094168569 44.6840756286875 884 + -93.0948937737562 44.6859682015167 853 + -93.0981262632978 44.6879373605934 853 + -93.101454986707 44.6899364101225 792 + -93.1050116792292 44.6917700662615 823 + -93.1086488406447 44.6935571270851 792 + -93.1123714592033 44.6950844029867 792 + -93.1160669441025 44.6961547755501 792 + -93.1198701422529 44.6969844340505 823 + -93.1236851662824 44.6978291490322 823 + -93.1274225659796 44.6986718065416 823 + -93.1311942704264 44.6993984412966 853 + -93.1349381107515 44.6999999769729 823 + -93.1389399866831 44.7004676966664 823 + -93.1429353283304 44.7008467726719 792 + -93.1467319575358 44.7012413854652 792 + -93.1499628617348 44.701745671311 256 + -93.153336892791 44.7021601177798 823 + -93.1573155649233 44.7025431241565 823 + -93.1612285414011 44.7030631821633 853 + -93.1650893906409 44.7036343060226 823 + -93.168735434804 44.7041440584898 823 + -93.1724202011042 44.7046128372079 823 + -93.1761398862948 44.7051091435166 792 + -93.1796630936383 44.7055777394683 792 + -93.1832380178971 44.7060406072565 823 + -93.1866638342882 44.7066093849988 823 + -93.1899087146892 44.7071801343989 823 + -93.193359587537 44.7076743817907 823 + -93.1967000778824 44.7081822996347 823 + -93.1999669003743 44.7087817760063 823 + -93.2034706963438 44.7093224014614 823 + -93.2071875434321 44.7097715459537 823 + -93.2107765241539 44.7103153755538 823 + -93.2143295791529 44.7108254548145 823 + -93.2178486234666 44.7112392078782 792 + -93.2211867867256 44.7116696952986 823 + -93.2243580018062 44.7121483598855 823 + -93.2273334445383 44.712639974576 823 + -93.230487243959 44.7131510651587 823 + -93.233844667064 44.7137558527546 823 + -93.2369967848442 44.714497155781 823 + -93.2401184808953 44.7154113173173 823 + -93.2431805770012 44.7167484248595 792 + -93.2437334091088 44.7170975413723 792 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 290 0 0 + 290 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 300 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 300 0 0 + 300 0 0 + 290 0 0 + 290 0 0 + 290 0 0 + 290 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 290 0 0 + 290 0 0 + 300 0 0 + 300 0 0 + 310 0 0 + 150 + 156 + 152 + 156 + 151 + 152 + 160 + 157 + 159 + 158 + 158 + 160 + 160 + 158 + 162 + 157 + 158 + 164 + 159 + 161 + 163 + 164 + 166 + 167 + 167 + 166 + 164 + 163 + 166 + 157 + 154 + 157 + 152 + 152 + 151 + 147 + 144 + 146 + 145 + 145 + 144 + 146 + 148 + 145 + 143 + 146 + 138 + 137 + 140 + 133 + 133 + 135 + 137 + 137 + 138 + 138 + 136 + 131 + 129 + 128 + 126 + 126 + 133 + 132 + 136 + 139 + 136 + + + A319 + A + DAL1588 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:04-05 + 2010-05-01T13:00:08-05 + 2010-05-01T13:00:13-05 + 2010-05-01T13:00:18-05 + 2010-05-01T13:00:22-05 + 2010-05-01T13:00:27-05 + 2010-05-01T13:00:31-05 + 2010-05-01T13:00:36-05 + 2010-05-01T13:00:41-05 + 2010-05-01T13:00:45-05 + 2010-05-01T13:00:50-05 + 2010-05-01T13:00:55-05 + 2010-05-01T13:00:59-05 + 2010-05-01T13:01:04-05 + 2010-05-01T13:01:09-05 + 2010-05-01T13:01:13-05 + 2010-05-01T13:01:18-05 + 2010-05-01T13:01:22-05 + 2010-05-01T13:01:27-05 + 2010-05-01T13:01:32-05 + 2010-05-01T13:01:36-05 + 2010-05-01T13:01:41-05 + 2010-05-01T13:01:46-05 + 2010-05-01T13:01:50-05 + 2010-05-01T13:01:55-05 + 2010-05-01T13:02:00-05 + 2010-05-01T13:02:04-05 + 2010-05-01T13:02:09-05 + 2010-05-01T13:02:13-05 + 2010-05-01T13:02:18-05 + 2010-05-01T13:02:23-05 + 2010-05-01T13:02:27-05 + 2010-05-01T13:02:32-05 + 2010-05-01T13:02:37-05 + 2010-05-01T13:02:41-05 + 2010-05-01T13:02:46-05 + 2010-05-01T13:02:51-05 + 2010-05-01T13:02:55-05 + 2010-05-01T13:03:00-05 + 2010-05-01T13:03:05-05 + 2010-05-01T13:03:09-05 + 2010-05-01T13:03:14-05 + 2010-05-01T13:03:19-05 + 2010-05-01T13:03:23-05 + 2010-05-01T13:03:28-05 + 2010-05-01T13:03:33-05 + 2010-05-01T13:03:37-05 + 2010-05-01T13:03:42-05 + 2010-05-01T13:03:47-05 + 2010-05-01T13:03:51-05 + 2010-05-01T13:03:56-05 + 2010-05-01T13:04:01-05 + 2010-05-01T13:04:05-05 + 2010-05-01T13:04:10-05 + 2010-05-01T13:04:15-05 + 2010-05-01T13:04:19-05 + 2010-05-01T13:04:24-05 + 2010-05-01T13:04:29-05 + 2010-05-01T13:04:33-05 + 2010-05-01T13:04:38-05 + 2010-05-01T13:04:42-05 + 2010-05-01T13:04:47-05 + 2010-05-01T13:04:52-05 + 2010-05-01T13:04:56-05 + 2010-05-01T13:05:00-05 + -93.6927825194056 44.7952011849485 3011 + -93.6850156681578 44.7968042586582 2987 + -93.6752785488692 44.7990458605003 2956 + -93.6657083011645 44.8014897663497 2926 + -93.6560029615388 44.803768841381 2865 + -93.6462045264035 44.8058749817725 2834 + -93.6365671200126 44.8080848199989 2804 + -93.6269933807039 44.8102767000109 2773 + -93.6175405757462 44.8123960709083 2743 + -93.6082528975965 44.8146455509748 2743 + -93.599077315807 44.816765612372 2743 + -93.5899428762254 44.8186933623744 2743 + -93.5809104439923 44.8205403457841 2743 + -93.5720785209701 44.8224608846058 2743 + -93.5634871751281 44.8245259755976 2743 + -93.5549873819943 44.8264288380043 2743 + -93.5465301417765 44.828146963076 2743 + -93.5382602633868 44.8299225976982 2743 + -93.5299909540853 44.8317218299661 2743 + -93.5217290971281 44.8335486849228 2743 + -93.5135254319341 44.8354478299135 2743 + -93.5052463800971 44.8374557781543 2743 + -93.4970241378696 44.8393862625467 2743 + -93.4888916549316 44.8410628089589 2743 + -93.48064759949 44.8427813728647 2743 + -93.4722750572418 44.8445241451071 2712 + -93.4639262889443 44.8463688032483 2743 + -93.4556378890352 44.8482208160082 2743 + -93.447407568623 44.8500947691895 2743 + -93.4393642055014 44.8523517774191 2743 + -93.4316071047585 44.8551246076581 2743 + -93.4244028068218 44.8584705613027 2743 + -93.4178621631751 44.8625068369064 2743 + -93.412146307774 44.867174139387 2743 + -93.4075995385136 44.8722931076546 2743 + -93.4039820359465 44.8777375352403 2743 + -93.4016072978871 44.8833117162528 2743 + -93.4005924913122 44.8890542850171 2743 + -93.4005563275156 44.8948199828389 2712 + -93.401452844832 44.9002595243996 2682 + -93.4032713926758 44.905357711587 2651 + -93.4058979070097 44.9101654056189 2621 + -93.4092802306306 44.9145600538157 2590 + -93.4134192058116 44.9185233235535 2530 + -93.4181155067703 44.9222086893794 2499 + -93.4230280156053 44.9256003980833 2469 + -93.4278299295206 44.9290448932076 2469 + -93.4322535173586 44.9329315139411 2438 + -93.4361102418566 44.9372336672133 2438 + -93.4389664177141 44.9421107629499 2438 + -93.4407103051748 44.9473646343685 2438 + -93.4416032158439 44.9527430754122 2408 + -93.4419308994101 44.9581538029148 2408 + -93.4419313717103 44.9636029026039 2377 + -93.4417378352424 44.9690628839115 2347 + -93.4415990458805 44.9744028948354 2347 + -93.4414478519305 44.9796663959001 2316 + -93.4413557290344 44.9848518867987 2316 + -93.4412896011133 44.9899566690879 2316 + -93.4411625354696 44.9949926823698 2286 + -93.4411216122071 45.000018474264 2225 + -93.4409537301264 45.0051267594771 2194 + -93.4408143120176 45.0101358999996 2133 + -93.4405516208864 45.0150761969136 2103 + -93.4397025278204 45.0199965135021 2042 + -93.4384243921567 45.02391596133 1993.2 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 70 0 0 + 60 0 0 + 50 0 0 + 50 0 0 + 40 0 0 + 30 0 0 + 20 0 0 + 10 0 0 + 0 0 0 + 360 0 0 + 350 0 0 + 340 0 0 + 340 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 340 0 0 + 350 0 0 + 350 0 0 + 360 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 10 0 0 + 10 0 0 + 10 0 0 + 390 + 383 + 397 + 390 + 405 + 388 + 386 + 397 + 377 + 373 + 367 + 362 + 357 + 350 + 345 + 353 + 336 + 334 + 346 + 332 + 331 + 330 + 331 + 332 + 331 + 331 + 345 + 333 + 332 + 344 + 331 + 331 + 329 + 326 + 324 + 320 + 314 + 307 + 298 + 291 + 284 + 276 + 271 + 268 + 266 + 267 + 270 + 274 + 279 + 283 + 288 + 291 + 292 + 290 + 288 + 286 + 281 + 278 + 286 + 273 + 271 + 280 + 270 + 274 + 263 + 268 + + + E145 + A + CHQ1453 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:01-05 + 2010-05-01T13:00:06-05 + 2010-05-01T13:00:11-05 + 2010-05-01T13:00:15-05 + 2010-05-01T13:00:20-05 + 2010-05-01T13:00:24-05 + 2010-05-01T13:00:29-05 + 2010-05-01T13:00:34-05 + 2010-05-01T13:00:38-05 + 2010-05-01T13:00:43-05 + 2010-05-01T13:00:48-05 + 2010-05-01T13:00:52-05 + 2010-05-01T13:00:57-05 + 2010-05-01T13:01:02-05 + 2010-05-01T13:01:06-05 + 2010-05-01T13:01:11-05 + 2010-05-01T13:01:15-05 + 2010-05-01T13:01:20-05 + 2010-05-01T13:01:25-05 + 2010-05-01T13:01:29-05 + 2010-05-01T13:01:34-05 + 2010-05-01T13:01:39-05 + 2010-05-01T13:01:43-05 + 2010-05-01T13:01:48-05 + 2010-05-01T13:01:52-05 + 2010-05-01T13:01:57-05 + 2010-05-01T13:02:02-05 + 2010-05-01T13:02:06-05 + 2010-05-01T13:02:11-05 + 2010-05-01T13:02:16-05 + 2010-05-01T13:02:20-05 + 2010-05-01T13:02:25-05 + 2010-05-01T13:02:29-05 + 2010-05-01T13:02:34-05 + 2010-05-01T13:02:39-05 + 2010-05-01T13:02:43-05 + 2010-05-01T13:02:48-05 + 2010-05-01T13:02:53-05 + 2010-05-01T13:02:57-05 + 2010-05-01T13:03:02-05 + 2010-05-01T13:03:07-05 + 2010-05-01T13:03:11-05 + 2010-05-01T13:03:16-05 + 2010-05-01T13:03:21-05 + 2010-05-01T13:03:25-05 + 2010-05-01T13:03:30-05 + 2010-05-01T13:03:34-05 + 2010-05-01T13:03:39-05 + 2010-05-01T13:03:44-05 + 2010-05-01T13:03:48-05 + 2010-05-01T13:03:53-05 + 2010-05-01T13:03:58-05 + 2010-05-01T13:04:02-05 + 2010-05-01T13:04:07-05 + 2010-05-01T13:04:11-05 + 2010-05-01T13:04:16-05 + 2010-05-01T13:04:21-05 + 2010-05-01T13:04:25-05 + 2010-05-01T13:04:30-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:39-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.5727580977974 45.0236058844647 2530 + -92.5742776202954 45.0237913896498 2530 + -92.5803397933112 45.0241784662561 2499 + -92.5865075192046 45.0247891381303 2469 + -92.5926877928765 45.0257073410966 2469 + -92.5986546763805 45.0261844476041 2438 + -92.6046737535477 45.0267206733977 2438 + -92.6106885874739 45.0275061986719 2438 + -92.616359210337 45.027935793162 2438 + -92.6220735719954 45.028379077688 2438 + -92.6280403097635 45.0290552550566 2438 + -92.6341725652711 45.029824064212 2438 + -92.640279209769 45.0304963952702 2438 + -92.6463747377703 45.0311129317319 2438 + -92.6524891739589 45.0317396965059 2438 + -92.6587083612282 45.0325526597288 2438 + -92.6649573988971 45.0334560566121 2438 + -92.6712436344147 45.0343516389227 2438 + -92.6777900587447 45.0353199754833 2438 + -92.6842020644974 45.0361081217423 2438 + -92.6904510353584 45.0368379981793 2438 + -92.6968618406938 45.0376828531019 2438 + -92.7033318031208 45.0383078021685 2438 + -92.709766951172 45.0386241893014 2438 + -92.7161769864286 45.0390317903939 2438 + -92.7225665589756 45.0396570251316 2408 + -92.7288886541216 45.0403373286575 2438 + -92.7352120601109 45.0409943934305 2438 + -92.7414745561156 45.0416276553236 2438 + -92.7477923122779 45.0424046535325 2438 + -92.7541218465412 45.0434006217761 2438 + -92.7601214481636 45.0440713086474 2438 + -92.7660333478225 45.0444426749968 2438 + -92.772102853148 45.0448779180664 2438 + -92.7780236703859 45.0449122731228 2408 + -92.7839974197715 45.0449532357526 2408 + -92.7902562936361 45.0450709796934 2377 + -92.7962688995386 45.0448540267375 2347 + -92.8024120242439 45.0448640459334 2316 + -92.8087530574681 45.0449050506622 2316 + -92.814709697375 45.0446514037676 2286 + -92.8205575663732 45.0444101119805 2255 + -92.8266048584444 45.0442428819735 2225 + -92.8327618067112 45.0440942522516 2194 + -92.83872651911 45.0438644076684 2164 + -92.8446994303267 45.043730942658 2133 + -92.8506627055935 45.0435520713609 2103 + -92.8563938230908 45.0431897062426 2072 + -92.8622525737075 45.0428768437665 2042 + -92.8680590561999 45.0424504399663 2011 + -92.8739470985612 45.0422191353343 1981 + -92.879905503922 45.0421676833604 1950 + -92.8859780438424 45.0420919545536 1920 + -92.8920993846605 45.0419574098772 1889 + -92.8980850189767 45.041613347859 1859 + -92.9042733870782 45.041256341571 1828 + -92.9105676382912 45.0409944306292 1798 + -92.9169019856279 45.0406669834687 1768 + -92.9233572619921 45.0402533884047 1737 + -92.9301295670095 45.0401453351324 1707 + -92.9368012064813 45.0400078656145 1676 + -92.943436221178 45.0397167044808 1646 + -92.9503058450392 45.0396542676205 1615 + -92.9570389363135 45.0394266771585 1585 + -92.9637736326563 45.0390859598898 1554 + -92.9705134597343 45.0387846980464 1524 + -92.973755360354 45.0384258824988 1508.5 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 260 0 0 + 260 0 0 + 235 + 246 + 239 + 244 + 234 + 232 + 238 + 227 + 228 + 229 + 229 + 232 + 236 + 238 + 249 + 243 + 245 + 255 + 247 + 248 + 248 + 247 + 256 + 247 + 246 + 254 + 244 + 245 + 242 + 239 + 246 + 235 + 232 + 240 + 231 + 232 + 234 + 234 + 233 + 232 + 233 + 232 + 229 + 229 + 237 + 227 + 225 + 233 + 224 + 225 + 228 + 228 + 240 + 233 + 236 + 248 + 243 + 246 + 250 + 253 + 255 + 257 + 257 + 266 + 261 + 265 + 275 + + + E170 + A + CPZ5695 + #arrival + + absolute + 1 + 2010-05-01T13:00:11-05 + 2010-05-01T13:00:15-05 + 2010-05-01T13:00:20-05 + 2010-05-01T13:00:25-05 + 2010-05-01T13:00:29-05 + 2010-05-01T13:00:34-05 + 2010-05-01T13:00:38-05 + 2010-05-01T13:00:43-05 + 2010-05-01T13:00:48-05 + 2010-05-01T13:00:52-05 + 2010-05-01T13:00:57-05 + 2010-05-01T13:01:02-05 + 2010-05-01T13:01:06-05 + 2010-05-01T13:01:11-05 + 2010-05-01T13:01:16-05 + 2010-05-01T13:01:20-05 + 2010-05-01T13:01:25-05 + 2010-05-01T13:01:29-05 + 2010-05-01T13:01:34-05 + 2010-05-01T13:01:39-05 + 2010-05-01T13:01:43-05 + 2010-05-01T13:01:48-05 + 2010-05-01T13:01:53-05 + 2010-05-01T13:01:57-05 + 2010-05-01T13:02:02-05 + 2010-05-01T13:02:06-05 + 2010-05-01T13:02:11-05 + 2010-05-01T13:02:16-05 + 2010-05-01T13:02:20-05 + 2010-05-01T13:02:25-05 + 2010-05-01T13:02:30-05 + 2010-05-01T13:02:34-05 + 2010-05-01T13:02:39-05 + 2010-05-01T13:02:44-05 + 2010-05-01T13:02:48-05 + 2010-05-01T13:02:53-05 + 2010-05-01T13:02:58-05 + 2010-05-01T13:03:02-05 + 2010-05-01T13:03:07-05 + 2010-05-01T13:03:11-05 + 2010-05-01T13:03:16-05 + 2010-05-01T13:03:21-05 + 2010-05-01T13:03:25-05 + 2010-05-01T13:03:30-05 + 2010-05-01T13:03:35-05 + 2010-05-01T13:03:39-05 + 2010-05-01T13:03:44-05 + 2010-05-01T13:03:48-05 + 2010-05-01T13:03:53-05 + 2010-05-01T13:03:58-05 + 2010-05-01T13:04:02-05 + 2010-05-01T13:04:07-05 + 2010-05-01T13:04:12-05 + 2010-05-01T13:04:16-05 + 2010-05-01T13:04:21-05 + 2010-05-01T13:04:25-05 + 2010-05-01T13:04:30-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:39-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.3689380245182 45.0389467469425 2804 + -92.3759530819834 45.0380951007958 2773 + -92.3831159633175 45.0369957486846 2712 + -92.3901362714549 45.0355238496347 2651 + -92.3970814910858 45.0339385808083 2621 + -92.4043121546626 45.032585906621 2560 + -92.4118367565321 45.0319048652958 2499 + -92.419078934653 45.030875157485 2469 + -92.4262095560369 45.0291153314744 2438 + -92.4335237384463 45.0273941113051 2438 + -92.4408178608932 45.0260076351757 2438 + -92.4480506692593 45.0250407396261 2438 + -92.4553504288427 45.0241919539362 2438 + -92.4628196268122 45.0233514202756 2438 + -92.4702544151504 45.0225228770055 2438 + -92.47749082249 45.0211454469826 2438 + -92.4849952170224 45.020108381381 2438 + -92.4924975545976 45.0191930140492 2438 + -92.4998773018653 45.018051767506 2438 + -92.507186344501 45.0168407571941 2438 + -92.5143825240876 45.0156216694574 2438 + -92.5215706342598 45.0143945866018 2438 + -92.5287558465591 45.0131646175633 2408 + -92.535858877656 45.0118804989009 2438 + -92.5428413996463 45.0103972607613 2438 + -92.5499799537839 45.0091469907013 2438 + -92.5571487214372 45.0079107943641 2438 + -92.5643503087637 45.0069312146329 2438 + -92.5715906639656 45.0060256188488 2438 + -92.5787232800865 45.0051593960756 2438 + -92.5859075456731 45.0042853983707 2438 + -92.5932558590921 45.0033774426771 2438 + -92.6008071462461 45.003154553905 2438 + -92.6083537686074 45.0033879703399 2438 + -92.6158581079963 45.0039900406543 2438 + -92.6233760961899 45.0046768119547 2438 + -92.6308149850999 45.0051419435105 2438 + -92.6382172211892 45.0057401438498 2438 + -92.6454696132537 45.005920412465 2438 + -92.6528385211424 45.0061349890872 2438 + -92.6604262143734 45.0071927884136 2438 + -92.6679454156809 45.0082888895876 2438 + -92.6753888547959 45.008928558351 2438 + -92.6828869677601 45.0095857895273 2438 + -92.6904366005728 45.0101503984089 2438 + -92.6979032678841 45.0107232636276 2438 + -92.7052708180676 45.0115414340457 2438 + -92.7127263858549 45.0123186978698 2438 + -92.7203010090271 45.0129672732945 2438 + -92.7279385048165 45.0135255760157 2438 + -92.7356653752599 45.0142972080147 2438 + -92.7433569853567 45.0149059605824 2438 + -92.7510393079923 45.0155634422272 2438 + -92.7586012608679 45.0164147107502 2438 + -92.7660563085583 45.0171035403725 2438 + -92.7735654020359 45.0178109394289 2408 + -92.7808966683949 45.0181973511467 2347 + -92.7882227912656 45.0186079478789 2316 + -92.7955583985804 45.0193002290468 2255 + -92.802877137723 45.0198997944223 2194 + -92.810330496953 45.0205558578153 2164 + -92.8178805010647 45.0213805814075 2103 + -92.8253364059255 45.0220160857506 2072 + -92.8282952283228 45.0222965993536 2047.6 + 260 0 0 + 260 0 0 + 260 0 0 + 250 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 250 0 0 + 250 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 270 0 0 + 270 0 0 + 280 0 0 + 280 0 0 + 270 0 0 + 270 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 277 + 288 + 283 + 291 + 283 + 284 + 298 + 288 + 288 + 286 + 287 + 287 + 286 + 286 + 299 + 289 + 289 + 299 + 287 + 286 + 284 + 282 + 292 + 281 + 281 + 291 + 280 + 280 + 281 + 282 + 283 + 284 + 286 + 287 + 287 + 286 + 295 + 285 + 286 + 297 + 287 + 289 + 290 + 288 + 298 + 288 + 289 + 302 + 292 + 294 + 294 + 294 + 304 + 290 + 288 + 297 + 284 + 284 + 284 + 285 + 286 + 278 + 282 + 288 + + + DC95 + A + DAL2858 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:03-05 + 2010-05-01T13:00:07-05 + 2010-05-01T13:00:12-05 + 2010-05-01T13:00:17-05 + 2010-05-01T13:00:21-05 + 2010-05-01T13:00:26-05 + 2010-05-01T13:00:30-05 + 2010-05-01T13:00:35-05 + 2010-05-01T13:00:40-05 + 2010-05-01T13:00:44-05 + 2010-05-01T13:00:49-05 + 2010-05-01T13:00:54-05 + 2010-05-01T13:00:58-05 + 2010-05-01T13:01:03-05 + 2010-05-01T13:01:07-05 + 2010-05-01T13:01:12-05 + 2010-05-01T13:01:17-05 + 2010-05-01T13:01:21-05 + 2010-05-01T13:01:26-05 + 2010-05-01T13:01:31-05 + 2010-05-01T13:01:35-05 + 2010-05-01T13:01:40-05 + 2010-05-01T13:01:45-05 + 2010-05-01T13:01:49-05 + 2010-05-01T13:01:54-05 + 2010-05-01T13:01:58-05 + 2010-05-01T13:02:03-05 + 2010-05-01T13:02:08-05 + 2010-05-01T13:02:12-05 + 2010-05-01T13:02:17-05 + 2010-05-01T13:02:22-05 + 2010-05-01T13:02:26-05 + 2010-05-01T13:02:31-05 + 2010-05-01T13:02:35-05 + 2010-05-01T13:02:40-05 + 2010-05-01T13:02:45-05 + 2010-05-01T13:02:49-05 + 2010-05-01T13:02:54-05 + 2010-05-01T13:02:59-05 + 2010-05-01T13:03:03-05 + 2010-05-01T13:03:08-05 + 2010-05-01T13:03:12-05 + 2010-05-01T13:03:17-05 + 2010-05-01T13:03:22-05 + 2010-05-01T13:03:26-05 + 2010-05-01T13:03:31-05 + 2010-05-01T13:03:36-05 + 2010-05-01T13:03:40-05 + 2010-05-01T13:03:45-05 + 2010-05-01T13:03:49-05 + 2010-05-01T13:03:54-05 + 2010-05-01T13:03:59-05 + 2010-05-01T13:04:03-05 + 2010-05-01T13:04:08-05 + 2010-05-01T13:04:12-05 + 2010-05-01T13:04:17-05 + 2010-05-01T13:04:22-05 + 2010-05-01T13:04:26-05 + 2010-05-01T13:04:31-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:40-05 + 2010-05-01T13:04:45-05 + 2010-05-01T13:04:50-05 + 2010-05-01T13:04:54-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -93.1962465696187 44.4584257162471 3078 + -93.1954858158128 44.462643897726 3078 + -93.1945524569257 44.4696206853623 3048 + -93.1935347734104 44.4765680167011 3048 + -93.1921548885013 44.4834366892852 3048 + -93.1912787899895 44.4902740201102 3048 + -93.190869393024 44.496999598511 3048 + -93.190355669541 44.503701889363 3048 + -93.1899042890233 44.510392533924 3048 + -93.1894352972433 44.5171043633827 3048 + -93.1887272976791 44.523838031578 3017 + -93.1882343860587 44.5305421014878 2987 + -93.1878483537445 44.5373007218153 2987 + -93.187206305476 44.5440099500882 2956 + -93.1868272718258 44.5507044137326 2956 + -93.1868012917709 44.5573772972405 2926 + -93.1866210269778 44.5640837167977 2895 + -93.1864907616916 44.5708828364002 2865 + -93.1863883659992 44.5775823065512 2865 + -93.1863783383684 44.5842436541366 2834 + -93.1864309457268 44.5909344741626 2804 + -93.1861870344 44.5974636699094 2804 + -93.1859399656477 44.6039556552385 2804 + -93.1853781106637 44.6104625660741 2773 + -93.1842558921345 44.6168860904061 2743 + -93.1824878787618 44.6232658876223 2712 + -93.1803879773166 44.6294813300019 2743 + -93.1780367881352 44.6355848757922 2743 + -93.1752316985335 44.6415358145216 2743 + -93.1723853204738 44.6473610477966 2743 + -93.1695650439908 44.6531642714264 2743 + -93.1665274417428 44.6589294401132 2743 + -93.163312582578 44.6647085135481 2743 + -93.160128277284 44.6704265732562 2743 + -93.1572001510497 44.6760520191633 2743 + -93.1543945309268 44.6816953047965 2743 + -93.1513717350775 44.6874085817504 2743 + -93.148373004873 44.693058643812 2743 + -93.1453860883093 44.6986645847547 2743 + -93.1421804531017 44.7042897996493 2743 + -93.1388918899721 44.7099624804852 2743 + -93.1358117624936 44.7156532681924 2743 + -93.1330575833882 44.7212682920708 2743 + -93.1302162164891 44.7268585149398 2743 + -93.1271891227658 44.7324687008066 2743 + -93.1242151781308 44.7380337584283 2743 + -93.1211166531293 44.7436002967353 2743 + -93.1178719942563 44.7492107287761 2743 + -93.1146752953943 44.7548599499827 2743 + -93.1117422413574 44.7605559725452 2743 + -93.1091424380409 44.7663214899376 2743 + -93.1066566399229 44.7720715320148 2743 + -93.1040152138285 44.7778692510771 2743 + -93.1012154435684 44.7836013270224 2743 + -93.0982479017436 44.7892173348525 2743 + -93.0950640890821 44.7947430846626 2743 + -93.0915034480367 44.800094039287 2743 + -93.0873387008124 44.8052382540424 2743 + -93.0825976468131 44.8101709774442 2743 + -93.0776830792116 44.815032321238 2773 + -93.0728317182526 44.8197880022073 2773 + -93.0680578728105 44.8244689148117 2773 + -93.0633853777291 44.829181080911 2743 + -93.0589797309512 44.8338258031244 2743 + -93.0546552480593 44.8384413086509 2743 + -93.0501805533684 44.8430463359799 2743 + -93.0484252769533 44.8448678241347 2743 + 10 0 0 + 10 0 0 + 10 0 0 + 10 0 0 + 10 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 0 0 0 + 10 0 0 + 10 0 0 + 10 0 0 + 10 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 20 0 0 + 30 0 0 + 30 0 0 + 30 0 0 + 40 0 0 + 40 0 0 + 40 0 0 + 30 0 0 + 30 0 0 + 30 0 0 + 30 0 0 + 30 0 0 + 378 + 370 + 381 + 373 + 384 + 367 + 365 + 377 + 362 + 362 + 362 + 362 + 376 + 361 + 362 + 375 + 361 + 361 + 359 + 358 + 355 + 353 + 352 + 362 + 347 + 346 + 355 + 339 + 336 + 335 + 333 + 343 + 329 + 329 + 340 + 325 + 325 + 326 + 327 + 338 + 325 + 325 + 336 + 322 + 322 + 324 + 325 + 338 + 326 + 327 + 339 + 326 + 337 + 324 + 323 + 334 + 321 + 332 + 318 + 317 + 314 + 310 + 318 + 303 + 306 + 311 + 322 + + + B737 + A + SWA1488 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:01-05 + 2010-05-01T13:00:06-05 + 2010-05-01T13:00:11-05 + 2010-05-01T13:00:15-05 + 2010-05-01T13:00:20-05 + 2010-05-01T13:00:24-05 + 2010-05-01T13:00:29-05 + 2010-05-01T13:00:34-05 + 2010-05-01T13:00:38-05 + 2010-05-01T13:00:43-05 + 2010-05-01T13:00:48-05 + 2010-05-01T13:00:52-05 + 2010-05-01T13:00:57-05 + 2010-05-01T13:01:01-05 + 2010-05-01T13:01:06-05 + 2010-05-01T13:01:11-05 + 2010-05-01T13:01:15-05 + 2010-05-01T13:01:20-05 + 2010-05-01T13:01:25-05 + 2010-05-01T13:01:29-05 + 2010-05-01T13:01:34-05 + 2010-05-01T13:01:38-05 + 2010-05-01T13:01:43-05 + 2010-05-01T13:01:48-05 + 2010-05-01T13:01:52-05 + 2010-05-01T13:01:57-05 + 2010-05-01T13:02:02-05 + 2010-05-01T13:02:06-05 + 2010-05-01T13:02:11-05 + 2010-05-01T13:02:15-05 + 2010-05-01T13:02:20-05 + 2010-05-01T13:02:25-05 + 2010-05-01T13:02:29-05 + 2010-05-01T13:02:34-05 + 2010-05-01T13:02:39-05 + 2010-05-01T13:02:43-05 + 2010-05-01T13:02:48-05 + 2010-05-01T13:02:53-05 + 2010-05-01T13:02:57-05 + 2010-05-01T13:03:02-05 + 2010-05-01T13:03:06-05 + 2010-05-01T13:03:11-05 + 2010-05-01T13:03:16-05 + 2010-05-01T13:03:20-05 + 2010-05-01T13:03:25-05 + 2010-05-01T13:03:30-05 + 2010-05-01T13:03:34-05 + 2010-05-01T13:03:39-05 + 2010-05-01T13:03:44-05 + 2010-05-01T13:03:48-05 + 2010-05-01T13:03:53-05 + 2010-05-01T13:03:57-05 + 2010-05-01T13:04:02-05 + 2010-05-01T13:04:07-05 + 2010-05-01T13:04:11-05 + 2010-05-01T13:04:16-05 + 2010-05-01T13:04:21-05 + 2010-05-01T13:04:25-05 + 2010-05-01T13:04:30-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:39-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.7436038977339 45.0176449723009 2438 + -92.745419752639 45.0178405701636 2438 + -92.7525586927583 45.0181852080204 2438 + -92.7599978682742 45.0189437491361 2438 + -92.7673964649616 45.0200176804669 2438 + -92.7743047878147 45.0206512321095 2438 + -92.7812211106102 45.0212438545962 2438 + -92.7880905786106 45.0219352711124 2438 + -92.7948110303679 45.0225135550872 2438 + -92.8016256231407 45.0231539091809 2377 + -92.808436321378 45.0237782407713 2316 + -92.8153060032773 45.0245123996427 2255 + -92.8220950756464 45.0250388052127 2194 + -92.8289929014999 45.0256725515916 2164 + -92.8360303531199 45.0266058986232 2103 + -92.8429329578141 45.0273764305379 2072 + -92.8498901242601 45.0280031718838 2011 + -92.8570769257727 45.0288350738651 1981 + -92.8642468830706 45.0297437485852 1920 + -92.87096733955 45.0302316004222 1859 + -92.8776991433842 45.0308036595577 1828 + -92.8848051869188 45.0317355139572 1768 + -92.891849836226 45.032372254553 1737 + -92.8988806858275 45.0330472653869 1676 + -92.9059183042329 45.0336591058208 1646 + -92.9127864875957 45.0340529790218 1554 + -92.9198394657117 45.0347605723218 1554 + -92.9271188759936 45.0355320490291 1493 + -92.9342496165443 45.0361866089878 1463 + -92.9413321497396 45.0366031935849 1402 + -92.9482307097935 45.0364375819171 1371 + -92.9549267830033 45.0357359075476 1341 + -92.9616308114574 45.0349106615543 1310 + -92.9680840982828 45.0340026299843 1280 + -92.9744518648424 45.0330474137801 1280 + -92.9808447078198 45.0322448064613 1249 + -92.9869393112267 45.0312693675023 1219 + -92.9930579883147 45.0303271096009 1219 + -92.9991883691893 45.0295800716662 1219 + -93.0050223477826 45.028724083281 1219 + -93.010614076045 45.0278629900138 1219 + -93.0160206405037 45.0268346460011 1219 + -93.0211552000865 45.0253145800507 1219 + -93.0258637412524 45.0233023458284 1219 + -93.0300671724338 45.0208133465794 1219 + -93.0339928023023 45.0180815293661 1219 + -93.0378123650471 45.015386905955 1219 + -93.0413573567597 45.0126147468646 1219 + -93.0448863339261 45.0099395682965 1219 + -93.0485234513263 45.0073532174657 1219 + -93.0521310871894 45.0048422081768 1219 + -93.0555350014272 45.0023982293894 1219 + -93.0589786824276 45.0000288885742 1188 + -93.0623077105646 44.9977133640953 1188 + -93.065360230814 44.995356896404 1158 + -93.0685763415021 44.9931569267686 1158 + -93.0718407580212 44.9911674357548 1097 + -93.0748577258473 44.9891037291536 1066 + -93.0778092168993 44.9869633801591 1036 + -93.0808539061589 44.9848563483924 1006 + -93.0836846650629 44.9827278139486 975 + -93.0863847135489 44.9806419407598 945 + -93.0891432094711 44.978586338985 945 + -93.0918882385755 44.9764807737863 945 + -93.0946313764692 44.9743266948072 914 + -93.0974123770403 44.9722534220515 914 + -93.0987847859357 44.9712598545857 899 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 280 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 250 0 0 + 250 0 0 + 240 0 0 + 240 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 280 + 293 + 284 + 288 + 274 + 272 + 279 + 263 + 263 + 262 + 262 + 275 + 266 + 267 + 279 + 272 + 271 + 268 + 269 + 280 + 269 + 267 + 278 + 270 + 271 + 272 + 272 + 281 + 270 + 268 + 273 + 259 + 255 + 250 + 247 + 244 + 239 + 235 + 238 + 224 + 220 + 224 + 212 + 210 + 208 + 206 + 204 + 200 + 197 + 200 + 189 + 185 + 188 + 176 + 172 + 168 + 165 + 163 + 159 + 158 + 157 + 156 + 155 + 159 + 156 + 160 + 165 + + + CRJ2 + A + MES3237 + #arrival + + absolute + 1 + 2010-05-01T13:02:11-05 + 2010-05-01T13:02:16-05 + 2010-05-01T13:02:20-05 + 2010-05-01T13:02:25-05 + 2010-05-01T13:02:30-05 + 2010-05-01T13:02:34-05 + 2010-05-01T13:02:39-05 + 2010-05-01T13:02:44-05 + 2010-05-01T13:02:48-05 + 2010-05-01T13:02:53-05 + 2010-05-01T13:02:58-05 + 2010-05-01T13:03:02-05 + 2010-05-01T13:03:07-05 + 2010-05-01T13:03:11-05 + 2010-05-01T13:03:16-05 + 2010-05-01T13:03:21-05 + 2010-05-01T13:03:25-05 + 2010-05-01T13:03:30-05 + 2010-05-01T13:03:35-05 + 2010-05-01T13:03:39-05 + 2010-05-01T13:03:44-05 + 2010-05-01T13:03:49-05 + 2010-05-01T13:03:53-05 + 2010-05-01T13:03:58-05 + 2010-05-01T13:04:02-05 + 2010-05-01T13:04:07-05 + 2010-05-01T13:04:12-05 + 2010-05-01T13:04:16-05 + 2010-05-01T13:04:21-05 + 2010-05-01T13:04:26-05 + 2010-05-01T13:04:30-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:39-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.3654525809466 45.0395326832503 2865 + -92.3722148453194 45.0383957360594 2804 + -92.3789968405533 45.0372550297716 2743 + -92.3857717937338 45.035790850493 2712 + -92.3928268643983 45.0344988210948 2651 + -92.4001469312933 45.033871851974 2560 + -92.4074037761026 45.0334790794383 2530 + -92.4143764863149 45.0325702739764 2469 + -92.4212444848282 45.0311814951256 2438 + -92.4279010170141 45.0296690432212 2438 + -92.4345565361906 45.0284146419212 2438 + -92.4413302267182 45.0272251811423 2438 + -92.4480836488953 45.0260669070124 2438 + -92.4551038107528 45.0251701649012 2438 + -92.4620867595928 45.0240801934066 2469 + -92.4688445943801 45.0226696219111 2438 + -92.475770828578 45.0214068742927 2438 + -92.4828770275976 45.0207461539528 2438 + -92.4898573176066 45.0197355515252 2438 + -92.4967644710332 45.0183323474054 2438 + -92.5037089663701 45.0170733409348 2438 + -92.5107248421742 45.0161283120616 2438 + -92.5176434168212 45.0153021033734 2438 + -92.5246160799064 45.014766408047 2438 + -92.5318394590384 45.0148138551787 2438 + -92.5390862704917 45.0145094336569 2438 + -92.5463963852328 45.0143318745824 2438 + -92.5536631015454 45.0147147936455 2438 + -92.5607664550331 45.014765244052 2438 + -92.5679894227165 45.0149152572076 2438 + -92.5752195833593 45.0150827900687 2438 + -92.582448917158 45.015235432103 2438 + -92.5897932283758 45.0155897891663 2438 + -92.5970842773637 45.0160017913126 2438 + -92.6042355431238 45.0161855996339 2438 + -92.6114545174405 45.0162505274554 2438 + -92.6187520939916 45.0164837409472 2438 + -92.6216565981247 45.0165937676212 2438 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 250 0 0 + 250 0 0 + 250 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 267 + 265 + 277 + 273 + 274 + 275 + 275 + 272 + 270 + 268 + 278 + 268 + 268 + 280 + 271 + 272 + 273 + 273 + 273 + 272 + 271 + 283 + 273 + 273 + 285 + 275 + 276 + 276 + 276 + 287 + 277 + 277 + 288 + 278 + 278 + 268 + 271 + 277 + + + A318 + A + FFT106 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:05-05 + 2010-05-01T13:00:09-05 + 2010-05-01T13:00:14-05 + 2010-05-01T13:00:19-05 + 2010-05-01T13:00:23-05 + 2010-05-01T13:00:28-05 + 2010-05-01T13:00:33-05 + 2010-05-01T13:00:37-05 + 2010-05-01T13:00:42-05 + 2010-05-01T13:00:47-05 + 2010-05-01T13:00:51-05 + 2010-05-01T13:00:56-05 + 2010-05-01T13:01:00-05 + 2010-05-01T13:01:05-05 + 2010-05-01T13:01:10-05 + 2010-05-01T13:01:14-05 + 2010-05-01T13:01:19-05 + 2010-05-01T13:01:24-05 + 2010-05-01T13:01:28-05 + 2010-05-01T13:01:33-05 + 2010-05-01T13:01:37-05 + 2010-05-01T13:01:42-05 + 2010-05-01T13:01:47-05 + 2010-05-01T13:01:51-05 + 2010-05-01T13:01:56-05 + 2010-05-01T13:02:01-05 + 2010-05-01T13:02:05-05 + 2010-05-01T13:02:10-05 + 2010-05-01T13:02:15-05 + 2010-05-01T13:02:19-05 + 2010-05-01T13:02:24-05 + 2010-05-01T13:02:28-05 + 2010-05-01T13:02:33-05 + 2010-05-01T13:02:38-05 + 2010-05-01T13:02:42-05 + 2010-05-01T13:02:47-05 + 2010-05-01T13:02:52-05 + 2010-05-01T13:02:56-05 + 2010-05-01T13:03:01-05 + 2010-05-01T13:03:06-05 + 2010-05-01T13:03:10-05 + 2010-05-01T13:03:15-05 + 2010-05-01T13:03:19-05 + 2010-05-01T13:03:24-05 + 2010-05-01T13:03:29-05 + 2010-05-01T13:03:33-05 + 2010-05-01T13:03:38-05 + 2010-05-01T13:03:43-05 + 2010-05-01T13:03:47-05 + 2010-05-01T13:03:52-05 + 2010-05-01T13:03:56-05 + 2010-05-01T13:04:01-05 + 2010-05-01T13:04:05-05 + 2010-05-01T13:04:10-05 + 2010-05-01T13:04:14-05 + 2010-05-01T13:04:18-05 + 2010-05-01T13:04:23-05 + 2010-05-01T13:04:27-05 + 2010-05-01T13:04:32-05 + 2010-05-01T13:04:37-05 + 2010-05-01T13:04:41-05 + 2010-05-01T13:04:46-05 + 2010-05-01T13:04:50-05 + 2010-05-01T13:04:55-05 + 2010-05-01T13:04:59-05 + 2010-05-01T13:05:00-05 + -93.2974568508014 45.0687622602847 1432 + -93.2934457905393 45.0660257042941 1371 + -93.2902010482642 45.0627382200457 1341 + -93.2880735868205 45.0592062737728 1280 + -93.2866251180089 45.0556538417996 1280 + -93.2855706436895 45.0521555770546 1249 + -93.2848929213344 45.0486326683558 1249 + -93.284149302237 45.0450445279501 1219 + -93.2832681542582 45.0414770478452 1219 + -93.2822163760078 45.0378266141909 1219 + -93.2810695206555 45.0339762188888 1249 + -93.2800852709943 45.0300242656845 1249 + -93.2789451826991 45.026165428423 1249 + -93.2776553627852 45.0222881273358 1219 + -93.2762849051262 45.0183879412865 1219 + -93.2750227859231 45.01452278975 1188 + -93.2739788608525 45.0107480537055 1188 + -93.27273416536 45.0071654180353 1158 + -93.271440533456 45.0036211770402 1127 + -93.2702510339155 45.0000676438878 1066 + -93.2689856900965 44.9965088916327 1036 + -93.2677450407515 44.9930289132183 1006 + -93.2665628070763 44.9897678001495 975 + -93.2654695900875 44.9865668331562 945 + -93.2643275310433 44.9833330918205 914 + -93.2631023843797 44.9801905024626 823 + -93.2621060751847 44.9769860428905 823 + -93.2613793333571 44.9737243608145 762 + -93.2609358268711 44.970517162552 762 + -93.260628015146 44.9674064044388 762 + -93.2602996952247 44.9643597216492 731 + -93.2599595576737 44.9613320303757 731 + -93.2594994071955 44.9582185681901 701 + -93.2589507888497 44.9549930481613 670 + -93.2583578824759 44.9518211731838 670 + -93.2577038531017 44.9485831657195 640 + -93.2570809594468 44.9453063523228 609 + -93.2563271653062 44.942138873467 609 + -93.2554358149374 44.9390293085691 579 + -93.2546255139468 44.9359025243045 579 + -93.2538265267143 44.9327450699088 548 + -93.2530252021259 44.9297128380021 548 + -93.2522809727351 44.9267689034144 518 + -93.2515035867768 44.9237188014152 487 + -93.2506543465894 44.9207369723461 487 + -93.2498548488919 44.9178124047958 457 + -93.2489961276719 44.9148538675761 426 + -93.2481063345252 44.9118432075909 426 + -93.2475702164253 44.9090871778968 396 + -93.2468054019883 44.9062896891392 365 + -93.2459138821779 44.9031220636101 365 + -93.2451839956313 44.9003646144392 335 + -93.2442620734973 44.8974631820496 335 + -93.2437934615496 44.8946084310426 335 + -93.2430623256379 44.8915836945618 365 + -93.2424772474959 44.8888394893853 426 + -93.2417795129824 44.8858318116166 487 + -93.2411065382114 44.882678391429 518 + -93.2402313646157 44.879530182788 579 + -93.2392009410817 44.8759747599643 609 + -93.2377852820119 44.872769339825 670 + -93.2363530715176 44.8696281486003 731 + -93.23475664131 44.866270773938 762 + -93.2331575993176 44.8629492601519 823 + -93.2317272590921 44.8596791368118 853 + -93.2301662617953 44.8564215369107 884 + -93.2298549002314 44.8557795687872 884 + 140 0 0 + 150 0 0 + 150 0 0 + 160 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 180 0 0 + 180 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 160 0 0 + 212 + 205 + 208 + 203 + 201 + 196 + 196 + 197 + 202 + 205 + 216 + 212 + 214 + 221 + 210 + 208 + 205 + 202 + 206 + 194 + 191 + 195 + 184 + 181 + 178 + 177 + 175 + 173 + 171 + 176 + 169 + 168 + 176 + 172 + 174 + 174 + 174 + 174 + 172 + 169 + 175 + 167 + 165 + 170 + 164 + 162 + 159 + 161 + 165 + 158 + 163 + 165 + 164 + 169 + 167 + 175 + 175 + 178 + 183 + 181 + 191 + 186 + 192 + 192 + 189 + 193 + 184 + + + BE35 + A + N46JJ + #arrival + + absolute + 1 + 2010-05-01T13:01:21-05 + 2010-05-01T13:01:26-05 + 2010-05-01T13:01:31-05 + 2010-05-01T13:01:35-05 + 2010-05-01T13:01:40-05 + 2010-05-01T13:01:44-05 + 2010-05-01T13:01:49-05 + 2010-05-01T13:01:54-05 + 2010-05-01T13:01:58-05 + 2010-05-01T13:02:03-05 + 2010-05-01T13:02:08-05 + 2010-05-01T13:02:12-05 + 2010-05-01T13:02:17-05 + 2010-05-01T13:02:22-05 + 2010-05-01T13:02:26-05 + 2010-05-01T13:02:31-05 + 2010-05-01T13:02:35-05 + 2010-05-01T13:02:40-05 + 2010-05-01T13:02:45-05 + 2010-05-01T13:02:49-05 + 2010-05-01T13:02:54-05 + 2010-05-01T13:02:59-05 + 2010-05-01T13:03:03-05 + 2010-05-01T13:03:08-05 + 2010-05-01T13:03:13-05 + 2010-05-01T13:03:17-05 + 2010-05-01T13:03:22-05 + 2010-05-01T13:03:26-05 + 2010-05-01T13:03:31-05 + 2010-05-01T13:03:36-05 + 2010-05-01T13:03:40-05 + 2010-05-01T13:03:45-05 + 2010-05-01T13:03:50-05 + 2010-05-01T13:03:54-05 + 2010-05-01T13:03:59-05 + 2010-05-01T13:04:04-05 + 2010-05-01T13:04:08-05 + 2010-05-01T13:04:13-05 + 2010-05-01T13:04:17-05 + 2010-05-01T13:04:22-05 + 2010-05-01T13:04:27-05 + 2010-05-01T13:04:31-05 + 2010-05-01T13:04:36-05 + 2010-05-01T13:04:41-05 + 2010-05-01T13:04:45-05 + 2010-05-01T13:04:50-05 + 2010-05-01T13:04:55-05 + 2010-05-01T13:04:59-05 + 2010-05-01T13:05:00-05 + -92.9339221048924 44.2950315742565 1524 + -92.9350064014678 44.2979570591066 1524 + -92.937652997869 44.3004478107577 1524 + -92.9407116824041 44.302846514598 1524 + -92.9430921358657 44.3054902041603 1524 + -92.9452136372834 44.308154578993 1524 + -92.9479783757094 44.310667507076 1524 + -92.9505645579644 44.3132980584321 1524 + -92.953176931421 44.3159244553921 1524 + -92.955790238918 44.3185524033008 1524 + -92.9581111706922 44.3212990950149 1524 + -92.9605941160522 44.3239309610271 1524 + -92.9634150903891 44.3264339577567 1524 + -92.9661669042714 44.3290084280208 1524 + -92.9689057275993 44.3316511959644 1524 + -92.9719191039836 44.3342289723207 1524 + -92.9745609220571 44.3367593382531 1524 + -92.9767073261514 44.3394303305052 1524 + -92.9791044580601 44.34211951331 1524 + -92.9818312662522 44.3446672608847 1524 + -92.98437591379 44.3472600312903 1524 + -92.9873161522272 44.3497184463263 1524 + -92.9898453395122 44.3523721849065 1524 + -92.992276996923 44.3551963485207 1524 + -92.9947092219658 44.3579338326741 1524 + -92.9972281517299 44.3606240814545 1524 + -92.9993151368602 44.3634480822621 1524 + -93.0016285033253 44.3662342282271 1524 + -93.0048280633172 44.3687843972879 1524 + -93.0078776508536 44.371448246948 1524 + -93.0107556818704 44.3741327819505 1524 + -93.0132474745541 44.3767834196569 1524 + -93.015638082508 44.3795081186135 1524 + -93.0183495942011 44.3821828750482 1524 + -93.0215077436058 44.3847489346551 1524 + -93.024007943771 44.3874959321693 1524 + -93.0264526837138 44.3902468927735 1524 + -93.0287728968074 44.3929994156644 1524 + -93.0313252807714 44.3957423196104 1524 + -93.0340309029643 44.3984682572521 1554 + -93.0367834033903 44.4012140197658 1554 + -93.039886374743 44.4039013532069 1524 + -93.0431213002073 44.4066598090273 1524 + -93.0456886621799 44.4095616223744 1524 + -93.0477227123297 44.4124371862128 1524 + -93.0506396295538 44.4152339455378 1524 + -93.0533566431572 44.4181925397398 1524 + -93.0556214357794 44.421167115874 1524 + -93.0562077996189 44.4217279400145 1524 + 330 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 320 0 0 + 320 0 0 + 320 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 330 0 0 + 169 + 166 + 171 + 169 + 171 + 178 + 171 + 172 + 173 + 173 + 173 + 174 + 175 + 181 + 174 + 174 + 180 + 172 + 171 + 172 + 174 + 174 + 174 + 175 + 181 + 176 + 177 + 186 + 179 + 179 + 179 + 179 + 178 + 177 + 177 + 184 + 178 + 177 + 186 + 182 + 184 + 184 + 185 + 186 + 185 + 184 + 187 + 184 + 187 + + + + A + + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:05-05 + 2010-05-01T13:00:10-05 + 2010-05-01T13:00:14-05 + 2010-05-01T13:00:24-05 + 2010-05-01T13:00:33-05 + 2010-05-01T13:00:37-05 + 2010-05-01T13:00:42-05 + 2010-05-01T13:00:47-05 + 2010-05-01T13:00:51-05 + 2010-05-01T13:00:56-05 + 2010-05-01T13:01:00-05 + 2010-05-01T13:01:05-05 + 2010-05-01T13:01:10-05 + 2010-05-01T13:01:14-05 + 2010-05-01T13:01:19-05 + 2010-05-01T13:01:24-05 + 2010-05-01T13:01:28-05 + 2010-05-01T13:01:33-05 + 2010-05-01T13:01:38-05 + 2010-05-01T13:01:43-05 + 2010-05-01T13:01:47-05 + 2010-05-01T13:01:51-05 + 2010-05-01T13:01:56-05 + 2010-05-01T13:02:01-05 + 2010-05-01T13:02:05-05 + 2010-05-01T13:02:10-05 + 2010-05-01T13:02:15-05 + 2010-05-01T13:02:19-05 + 2010-05-01T13:02:24-05 + 2010-05-01T13:02:28-05 + 2010-05-01T13:02:33-05 + 2010-05-01T13:02:38-05 + 2010-05-01T13:02:42-05 + 2010-05-01T13:02:47-05 + 2010-05-01T13:02:52-05 + 2010-05-01T13:02:56-05 + 2010-05-01T13:03:01-05 + 2010-05-01T13:03:06-05 + 2010-05-01T13:03:10-05 + 2010-05-01T13:03:15-05 + 2010-05-01T13:03:20-05 + 2010-05-01T13:03:24-05 + 2010-05-01T13:03:29-05 + 2010-05-01T13:03:33-05 + 2010-05-01T13:03:38-05 + 2010-05-01T13:03:43-05 + 2010-05-01T13:03:47-05 + 2010-05-01T13:03:52-05 + 2010-05-01T13:03:57-05 + 2010-05-01T13:04:01-05 + 2010-05-01T13:04:06-05 + 2010-05-01T13:04:11-05 + 2010-05-01T13:04:15-05 + 2010-05-01T13:04:20-05 + 2010-05-01T13:04:24-05 + 2010-05-01T13:04:29-05 + 2010-05-01T13:04:34-05 + 2010-05-01T13:04:38-05 + 2010-05-01T13:04:43-05 + 2010-05-01T13:04:48-05 + 2010-05-01T13:04:52-05 + 2010-05-01T13:04:57-05 + 2010-05-01T13:05:00-05 + -93.5287325331323 45.3502794027397 731 + -93.5305174337715 45.3463816209029 731 + -93.532323089283 45.3433065196778 731 + -93.5344374505075 45.3397938806867 731 + -93.5365879669744 45.3355152994798 731 + -93.538455345577 45.3317693717468 731 + -93.5402440337749 45.3288175816964 731 + -93.5420054353005 45.3261482119682 701 + -93.5437972875724 45.3236486426325 701 + -93.5449025453586 45.3213557809437 670 + -93.5460939368394 45.3190373998605 670 + -93.5479457332637 45.3165177805485 670 + -93.5493974388824 45.3141793458801 670 + -93.5513867211372 45.311763387862 640 + -93.5535208279901 45.3092989037314 640 + -93.5553972702218 45.3069522366272 609 + -93.5571429777693 45.3046054644141 609 + -93.5579199353617 45.3025960765579 640 + -93.5593045947048 45.3003990165413 640 + -93.5616831509882 45.2976828740205 640 + -93.5637771433208 45.2950299257309 640 + -93.5655282859852 45.2925928168771 640 + -93.5670151031996 45.2901828629185 640 + -93.5687097888584 45.2875722909995 609 + -93.5700169391262 45.2851834796592 670 + -93.5710302700083 45.2828077246619 640 + -93.5718507391893 45.2803449539575 670 + -93.5725921190677 45.2778546051997 670 + -93.5735869984384 45.2752499819516 670 + -93.5746474214783 45.2726078789038 670 + -93.5759690717845 45.2698099999195 670 + -93.5773880658931 45.2669964536541 701 + -93.5786320195651 45.2643944197042 701 + -93.5801045228797 45.2617721181735 731 + -93.5812823080336 45.2592837181772 762 + -93.5824999029929 45.2568982323771 792 + -93.584184493492 45.2545288880291 792 + -93.5856799945281 45.2523235684068 792 + -93.5867865417154 45.2502484182149 792 + -93.5877350378085 45.2481996073608 792 + -93.5890621470214 45.2458286959404 762 + -93.5904952245442 45.2433496248092 762 + -93.5917459859832 45.2410175205115 762 + -93.592940308901 45.2387518649986 792 + -93.5943516581034 45.2363760400415 792 + -93.595835737429 45.2339795097202 792 + -93.5970428000944 45.2316738651172 792 + -93.598068247895 45.2293303072495 792 + -93.5992987604295 45.2268750160339 762 + -93.6008769052334 45.2242985661919 762 + -93.6025298777898 45.2216628823159 762 + -93.6039679259902 45.2191586079975 762 + -93.6055530853699 45.2165615203343 762 + -93.6071850685486 45.213948758836 792 + -93.6085800541819 45.2114666338841 792 + -93.6099900017953 45.2087907684969 762 + -93.6111813373289 45.2058856405005 762 + -93.6116978316508 45.2030015871681 762 + -93.6118935129054 45.2001474423799 762 + -93.6120686576365 45.1971548169968 731 + -93.6120488607103 45.1942250308012 731 + -93.6121619193052 45.1911822627783 731 + -93.6123153707665 45.188122812492 731 + -93.6121210225109 45.1864342009565 731 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 200 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 210 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 190 0 0 + 190 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 200 0 0 + 190 0 0 + 190 0 0 + 180 0 0 + 180 0 0 + 180 0 0 + 180 0 0 + 180 0 0 + 180 0 0 + 202 + 180 + 166 + 171 + 162 + 157 + 143 + 145 + 156 + 144 + 142 + 149 + 146 + 148 + 140 + 139 + 142 + 137 + 143 + 149 + 151 + 152 + 151 + 147 + 140 + 141 + 140 + 149 + 148 + 150 + 158 + 152 + 150 + 147 + 142 + 138 + 131 + 131 + 132 + 130 + 130 + 138 + 138 + 137 + 140 + 136 + 139 + 142 + 143 + 146 + 150 + 151 + 157 + 152 + 154 + 160 + 155 + 157 + 159 + 160 + 159 + 155 + 157 + 161 + + + B752 + A + DAL2731 + #arrival + + absolute + 1 + 2010-05-01T13:04:40-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.3671504733075 45.0392472395977 2743 + -92.3742258682339 45.0377289236059 2712 + -92.3813215867021 45.0364293844267 2682 + -92.3883643499875 45.0352118386382 2651 + -92.3954606917206 45.0343296776778 2621 + -92.3983011205325 45.0338926726637 2608.6 + 250 0 0 + 250 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 260 0 0 + 301 + 289 + 283 + 283 + 272 + 276 + + + CRJ2 + A + SKW4805 + #arrival + + + CRJ2 + A + FLG4092 + #arrival + + + E170 + A + CPZ5667 + #arrival + + absolute + 1 + 2010-05-01T13:00:00-05 + 2010-05-01T13:00:01-05 + 2010-05-01T13:00:06-05 + 2010-05-01T13:00:10-05 + 2010-05-01T13:00:15-05 + 2010-05-01T13:00:20-05 + 2010-05-01T13:00:24-05 + 2010-05-01T13:00:29-05 + 2010-05-01T13:00:34-05 + 2010-05-01T13:00:38-05 + 2010-05-01T13:00:43-05 + 2010-05-01T13:00:47-05 + 2010-05-01T13:00:52-05 + 2010-05-01T13:00:57-05 + 2010-05-01T13:01:01-05 + 2010-05-01T13:01:06-05 + 2010-05-01T13:01:11-05 + 2010-05-01T13:01:15-05 + 2010-05-01T13:01:20-05 + 2010-05-01T13:01:24-05 + 2010-05-01T13:01:29-05 + 2010-05-01T13:01:34-05 + 2010-05-01T13:01:38-05 + 2010-05-01T13:01:43-05 + 2010-05-01T13:01:48-05 + 2010-05-01T13:01:52-05 + 2010-05-01T13:01:57-05 + 2010-05-01T13:02:02-05 + 2010-05-01T13:02:06-05 + 2010-05-01T13:02:11-05 + 2010-05-01T13:02:15-05 + 2010-05-01T13:02:20-05 + 2010-05-01T13:02:25-05 + 2010-05-01T13:02:29-05 + 2010-05-01T13:02:34-05 + 2010-05-01T13:02:39-05 + 2010-05-01T13:02:43-05 + 2010-05-01T13:02:48-05 + 2010-05-01T13:02:53-05 + 2010-05-01T13:02:57-05 + 2010-05-01T13:03:02-05 + 2010-05-01T13:03:06-05 + 2010-05-01T13:03:11-05 + 2010-05-01T13:03:16-05 + 2010-05-01T13:03:20-05 + 2010-05-01T13:03:25-05 + 2010-05-01T13:03:30-05 + 2010-05-01T13:03:34-05 + 2010-05-01T13:03:39-05 + 2010-05-01T13:03:44-05 + 2010-05-01T13:03:48-05 + 2010-05-01T13:03:53-05 + 2010-05-01T13:03:57-05 + 2010-05-01T13:04:02-05 + 2010-05-01T13:04:07-05 + 2010-05-01T13:04:11-05 + 2010-05-01T13:04:16-05 + 2010-05-01T13:04:21-05 + 2010-05-01T13:04:25-05 + 2010-05-01T13:04:30-05 + 2010-05-01T13:04:35-05 + 2010-05-01T13:04:39-05 + 2010-05-01T13:04:44-05 + 2010-05-01T13:04:49-05 + 2010-05-01T13:04:53-05 + 2010-05-01T13:04:58-05 + 2010-05-01T13:05:00-05 + -92.9496238812799 45.0117549407746 1438.2 + -92.9507065768732 45.0116702587604 1432 + -92.9563739191926 45.0116271226204 1432 + -92.9620225732021 45.0115639668496 1432 + -92.9673675587699 45.0113432900049 1402 + -92.9725115032188 45.0111442254373 1402 + -92.9778810091229 45.0112050922639 1371 + -92.9832227114571 45.0112143826731 1371 + -92.9884546803523 45.0110418166788 1341 + -92.9938268606229 45.0109652220709 1341 + -92.9991151069756 45.010802144845 1310 + -93.0041467584036 45.0105516668541 1310 + -93.0090742909164 45.0105233046799 1280 + -93.0139435770527 45.0106265340001 1280 + -93.0186698179379 45.010634924101 1249 + -93.0233769482656 45.0105798571028 1219 + -93.027863445495 45.0103319372353 1219 + -93.0321355024912 45.009785470284 1188 + -93.0364774006258 45.0090804055343 1188 + -93.0406972054631 45.008159893417 1158 + -93.044688438093 45.0070424610069 1158 + -93.048236193366 45.0055626328365 1127 + -93.0515060655523 45.0038918034748 1097 + -93.0547412568513 45.002203639943 1097 + -93.057960971331 45.0002785469345 1066 + -93.061163597597 44.9982000732934 1036 + -93.0642340616386 44.9961004469539 1036 + -93.0673288162316 44.9939827866134 1036 + -93.0705257535347 44.9919340234479 1006 + -93.0737651809484 44.9898497469776 1006 + -93.0766698334355 44.9874752633062 975 + -93.0795448300029 44.9851003293423 945 + -93.0826513591394 44.982853369523 914 + -93.0857494236443 44.9806128435883 914 + -93.0889594989987 44.9783354445401 884 + -93.0921516080765 44.9761326356492 853 + -93.0951593343498 44.9739412329465 823 + -93.098173526634 44.9718087345519 792 + -93.1011828507638 44.9697896030084 792 + -93.1041138105741 44.9676784537011 762 + -93.1070716804749 44.9654796588945 762 + -93.1101959375488 44.9632479940121 731 + -93.1134259541861 44.9611142324701 731 + -93.1164777263599 44.9590021654861 701 + -93.119453084479 44.9567137200248 701 + -93.1225749783361 44.9543749518252 670 + -93.1257330391052 44.9521434289046 640 + -93.1288583838247 44.9499086265813 640 + -93.1320823896043 44.947732382611 609 + -93.1352777130563 44.9456935460161 609 + -93.1382372228923 44.9435026223594 579 + -93.1412308158626 44.9413228585563 548 + -93.1440834422772 44.9393578781327 548 + -93.1468380987104 44.937418270883 548 + -93.1496706928566 44.9354098449433 548 + -93.1524193130388 44.9334175710809 548 + -93.1552204975698 44.931467153437 548 + -93.1580221467789 44.9294054329873 548 + -93.1608324983225 44.9273103160518 548 + -93.163576735833 44.9252792086421 518 + -93.1662777029414 44.923281165701 518 + -93.1691629183162 44.9213004519466 518 + -93.1721326207182 44.9193080290794 487 + -93.1750564756636 44.9172689130085 487 + -93.1778338144972 44.915261757476 457 + -93.1805696776089 44.9132626732327 457 + -93.1819903937475 44.9122233325116 441.5 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 270 0 0 + 260 0 0 + 260 0 0 + 250 0 0 + 250 0 0 + 240 0 0 + 240 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 230 0 0 + 220 0 0 + 220 0 0 + 220 0 0 + 214 + 207 + 202 + 208 + 207 + 205 + 203 + 202 + 209 + 199 + 196 + 200 + 188 + 183 + 178 + 175 + 179 + 170 + 166 + 169 + 161 + 160 + 159 + 159 + 160 + 162 + 164 + 172 + 166 + 167 + 174 + 169 + 170 + 169 + 168 + 166 + 165 + 163 + 169 + 164 + 164 + 172 + 168 + 169 + 169 + 169 + 169 + 168 + 167 + 170 + 160 + 158 + 161 + 153 + 151 + 152 + 153 + 152 + 153 + 154 + 154 + 153 + 153 + 160 + 156 + 160 + 164 + + + + Departures + + TEX2 + D + HOOK67 + #departure + + absolute + 1 + 2010-05-01T13:02:46-05 + 2010-05-01T13:02:50-05 + 2010-05-01T13:02:54-05 + 2010-05-01T13:02:59-05 + 2010-05-01T13:03:04-05 + 2010-05-01T13:03:08-05 + 2010-05-01T13:03:13-05 + 2010-05-01T13:03:18-05 + 2010-05-01T13:03:22-05 + 2010-05-01T13:03:27-05 + 2010-05-01T13:03:31-05 + 2010-05-01T13:03:36-05 + 2010-05-01T13:03:41-05 + 2010-05-01T13:03:45-05 + 2010-05-01T13:03:50-05 + 2010-05-01T13:03:55-05 + 2010-05-01T13:03:59-05 + 2010-05-01T13:04:04-05 + 2010-05-01T13:04:09-05 + 2010-05-01T13:04:13-05 + 2010-05-01T13:04:18-05 + 2010-05-01T13:04:23-05 + 2010-05-01T13:04:28-05 + 2010-05-01T13:04:32-05 + 2010-05-01T13:04:37-05 + 2010-05-01T13:04:42-05 + 2010-05-01T13:04:46-05 + 2010-05-01T13:04:51-05 + 2010-05-01T13:04:56-05 + 2010-05-01T13:05:00-05 + -93.2379571205595 44.872806349747 365 + -93.2370660925484 44.870006118743 396 + -93.236355767523 44.8669752777211 426 + -93.2354887209031 44.863712193489 487 + -93.2347087148419 44.8604536579846 548 + -93.2338531241111 44.8572464977323 609 + -93.2329069833652 44.8540674818656 670 + -93.2321075679892 44.8508271074111 731 + -93.2318979317232 44.8475791496379 792 + -93.2324245825346 44.8444239832126 884 + -93.2337414411031 44.8414077607553 945 + -93.2358704572033 44.8386783246771 1006 + -93.2388663703645 44.836365445841 1066 + -93.2426861295915 44.8345537010783 1127 + -93.2472528925157 44.8333824186694 1158 + -93.252467378877 44.8329692039001 1188 + -93.25805239674 44.8333893976675 1219 + -93.2638450577518 44.8346083411457 1219 + -93.2696754993405 44.83650914188 1219 + -93.2753673121587 44.8390951418887 1219 + -93.2808543977574 44.8421681587795 1219 + -93.2861853262416 44.8454128516506 1249 + -93.29145969331 44.8487370983379 1219 + -93.2967095159 44.8520389729185 1219 + -93.3019214165294 44.8553364257712 1219 + -93.3070477220233 44.8587223340278 1219 + -93.3121286565238 44.8620050415952 1219 + -93.3171626530446 44.8652559523285 1219 + -93.3221179929219 44.868582313462 1219 + -93.3270963865766 44.8718050975636 1219 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 170 0 0 + 180 0 0 + 180 0 0 + 190 0 0 + 200 0 0 + 220 0 0 + 230 0 0 + 240 0 0 + 260 0 0 + 270 0 0 + 280 0 0 + 290 0 0 + 300 0 0 + 300 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 310 0 0 + 178 + 175 + 180 + 177 + 175 + 177 + 175 + 181 + 173 + 172 + 178 + 173 + 178 + 187 + 196 + 208 + 224 + 237 + 247 + 247 + 263 + 266 + 258 + 267 + 266 + 265 + 263 + 266 + 270 + 260 + + + + Overflights + + + diff --git a/examples/markerResize.html b/examples/markerResize.html index 050c5ac3..5941e418 100644 --- a/examples/markerResize.html +++ b/examples/markerResize.html @@ -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)); diff --git a/examples/markers.html b/examples/markers.html index 9a7610b1..172f22fe 100644 --- a/examples/markers.html +++ b/examples/markers.html @@ -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(); diff --git a/examples/mm.html b/examples/mm.html index 305d3c22..ed907d1f 100644 --- a/examples/mm.html +++ b/examples/mm.html @@ -24,7 +24,7 @@ function init(){ map = new OpenLayers.Map( 'map' , - {controls:[new OpenLayers.Control.MouseDefaults()]}); + {controls:[new OpenLayers.Control.Navigation()]}); mmlayer = new OpenLayers.Layer.MultiMap( "MultiMap"); map.addLayer(mmlayer); diff --git a/examples/multimap-mercator.html b/examples/multimap-mercator.html index 32d35d16..11310040 100644 --- a/examples/multimap-mercator.html +++ b/examples/multimap-mercator.html @@ -12,7 +12,8 @@ - + + - - - -

Untiled Example

-

- Create an untiled WMS layer using the singleTile: true, option or the deprecated - WMS.Untiled layer. -

-
-

The first layer is an old OpenLayers.Layer.WMS.Untiled layer, using - a default ratio value of 1.5. -

The second layer is an OpenLayers.Layer.WMS layer with singleTile set - to true, and with a ratio of 1. - - diff --git a/examples/osm-google.html b/examples/osm-google.html new file mode 100644 index 00000000..19738642 --- /dev/null +++ b/examples/osm-google.html @@ -0,0 +1,27 @@ + + + + OpenLayers OSM and Google Example + + + + + + + + +

OSM and Google Together

+

+ Demonstrate use of an OSM layer and a Google layer as base layers. +

+
+
+

+ 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 + osm-google.js source to see how this is done. +

+
+ + diff --git a/examples/osm-google.js b/examples/osm-google.js new file mode 100644 index 00000000..77d96d82 --- /dev/null +++ b/examples/osm-google.js @@ -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 + ); +} diff --git a/examples/osm-layer.html b/examples/osm-layer.html index cd16e757..0dd03b47 100644 --- a/examples/osm-layer.html +++ b/examples/osm-layer.html @@ -17,10 +17,10 @@ function export_vectors() { var x = new OpenLayers.Format.XML(); var content = x.write(gml.renderer.rendererRoot); - $("vectors").value = content; - $("vectors").style.display = "block"; - $("vectorlink").href = "data:image/svg+xml," + escape(content); - $("vectorlink").style.display="block"; + OpenLayers.Util.getElement("vectors").value = content; + OpenLayers.Util.getElement("vectors").style.display = "block"; + OpenLayers.Util.getElement("vectorlink").href = "data:image/svg+xml," + escape(content); + OpenLayers.Util.getElement("vectorlink").style.display="block"; } function on_feature_hover(feature) { var text ="
    "; @@ -33,7 +33,7 @@ text += "
  • " + key + ": " + feature.attributes[key] + "
  • "; } text += "
"; - $("status").innerHTML = text; + OpenLayers.Util.getElement("status").innerHTML = text; } function clear_data() { gml.destroyFeatures(); @@ -43,7 +43,7 @@ clear_data(); gml.loaded = false; gml.url = "http://www.openstreetmap.org/api/0.5/map?bbox=" + map.getExtent().toBBOX(); - $("status").innerHTML = "Loading more data..."; + OpenLayers.Util.getElement("status").innerHTML = "Loading more data..."; gml.loadGML(); } function style_osm_feature(feature) { @@ -63,7 +63,7 @@ var zoom = map.getZoom(); if (zoom >= 11) { return true; } if (zoom >= 9) { return confirm("Loading this amount of data may slow your browser. Are you sure you want to do this?"); } - $("status").innerHTML = "Area too large. Zoom in to load data. (Current zoom level: "+ zoom + ". Must be at zoom 9+.)"; + OpenLayers.Util.getElement("status").innerHTML = "Area too large. Zoom in to load data. (Current zoom level: "+ zoom + ". Must be at zoom 9+.)"; return false; } function init(){ @@ -92,8 +92,8 @@ gml = new OpenLayers.Layer.GML("OSM", "xml/cambridgeport.osm", {format: OpenLayers.Format.OSM}); } } - gml.events.register("loadstart", null, function() { $("status").innerHTML = "Loading..."; }) - gml.events.register("loadend", null, function() { $("status").innerHTML = ""; }) + gml.events.register("loadstart", null, function() { OpenLayers.Util.getElement("status").innerHTML = "Loading..."; }) + gml.events.register("loadend", null, function() { OpenLayers.Util.getElement("status").innerHTML = ""; }) map.addLayer(gml); gml.preFeatureInsert = style_osm_feature; var sf = new OpenLayers.Control.SelectFeature(gml, {'onSelect': on_feature_hover}); diff --git a/examples/osm.html b/examples/osm.html index 94f73a3b..d14a1bb0 100644 --- a/examples/osm.html +++ b/examples/osm.html @@ -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 + ); } diff --git a/examples/overviewmap.html b/examples/overviewmap.html index 01961650..69210cfc 100644 --- a/examples/overviewmap.html +++ b/examples/overviewmap.html @@ -75,15 +75,13 @@

Overview Map

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 @@

Overview Map

// 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 @@

Overview Map

map2.setCenter(new OpenLayers.LonLat(-8233165.3575055, 4980298.21113769), 3); - // expand the overview map control - overview2.maximizeControl(); - diff --git a/examples/panel.html b/examples/panel.html index dcc82753..119a7b92 100644 --- a/examples/panel.html +++ b/examples/panel.html @@ -7,38 +7,34 @@ .olControlPanel div { display:block; width: 24px; - height: 24px; + height: 22px; margin: 5px; - background-color:red; + background-color:white; } - .olControlPanel .olControlMouseDefaultsItemActive { + .olControlPanel .olControlNavigationItemActive { background-color: blue; background-image: url("../theme/default/img/pan_on.png"); } - .olControlPanel .olControlMouseDefaultsItemInactive { + .olControlPanel .olControlNavigationItemInactive { background-color: orange; background-image: url("../theme/default/img/pan_off.png"); } .olControlPanel .olControlDrawFeatureItemActive { - width: 22px; - height: 22px; background-image: url("../theme/default/img/draw_line_on.png"); } .olControlPanel .olControlDrawFeatureItemInactive { - width: 22px; - height: 22px; background-image: url("../theme/default/img/draw_line_off.png"); } .olControlPanel .olControlZoomBoxItemInactive { - width: 22px; - height: 22px; + width: 27px; + height: 27px; background-color: orange; background-image: url("../img/drag-rectangle-off.png"); } .olControlPanel .olControlZoomBoxItemActive { - width: 22px; - height: 22px; + width: 27px; + height: 27px; background-color: blue; background-image: url("../img/drag-rectangle-on.png"); } @@ -71,13 +67,19 @@ {title:"Zoom box: Selecting it you can zoom on an area by clicking and dragging."}); var panel = new OpenLayers.Control.Panel({defaultControl: zb}); panel.addControls([ - new OpenLayers.Control.MouseDefaults( + new OpenLayers.Control.Navigation( {title:'You can use the default mouse configuration'}), zb, new OpenLayers.Control.DrawFeature(vlayer, OpenLayers.Handler.Path, {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); diff --git a/examples/select-feature.html b/examples/select-feature.html index f50b2ed9..ef1590ee 100644 --- a/examples/select-feature.html +++ b/examples/select-feature.html @@ -23,10 +23,10 @@ var vectors = new OpenLayers.Layer.Vector("Vector Layer"); vectors.events.on({ 'featureselected': function(feature) { - $('counter').innerHTML = this.selectedFeatures.length; + OpenLayers.Util.getElement('counter').innerHTML = this.selectedFeatures.length; }, 'featureunselected': function(feature) { - $('counter').innerHTML = this.selectedFeatures.length; + OpenLayers.Util.getElement('counter').innerHTML = this.selectedFeatures.length; }, }); diff --git a/examples/sld-parser.html b/examples/sld-parser.html new file mode 100644 index 00000000..56a6c83f --- /dev/null +++ b/examples/sld-parser.html @@ -0,0 +1,65 @@ + + + + OpenLayers SLD Parser + + + + + + +

SLD Parser

+ +
Parsing Styled Layer Descriptor (SLD) documents with the SLD format.
+ +
+
+
+ + +
+ 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. +
+ + + + + + + diff --git a/examples/snap-split.html b/examples/snap-split.html index ca3e6579..f06db285 100644 --- a/examples/snap-split.html +++ b/examples/snap-split.html @@ -173,15 +173,15 @@ */ function initUI() { // add behavior to snap elements - var snapCheck = $("snap_toggle"); + var snapCheck = OpenLayers.Util.getElement("snap_toggle"); snapCheck.checked = true; snapCheck.onclick = function() { if(snapCheck.checked) { snap.activate(); - $("snap_options").style.display = "block"; + OpenLayers.Util.getElement("snap_options").style.display = "block"; } else { snap.deactivate(); - $("snap_options").style.display = "none"; + OpenLayers.Util.getElement("snap_options").style.display = "none"; } }; var target, type, tog, tol; @@ -189,12 +189,12 @@ var target = snap.targets[0]; for(var j=0; j var map, layer; function init(){ - map = new OpenLayers.Map( $('map'), { + map = new OpenLayers.Map('map'), { resolutions: [0.087890625, 0.0439453125, 0.02197265625, 0.010986328125] }); layer = new OpenLayers.Layer.TileCache("TileCache Layer", diff --git a/examples/ve.html b/examples/ve.html index 0dad53a4..0d451c54 100644 --- a/examples/ve.html +++ b/examples/ve.html @@ -15,7 +15,7 @@ function init(){ map = new OpenLayers.Map( 'map' , - {controls:[new OpenLayers.Control.MouseDefaults()]}); + {controls:[new OpenLayers.Control.Navigation()]}); velayer = new OpenLayers.Layer.VirtualEarth( "VE", { // turn off animated zooming diff --git a/examples/wfs-filter.html b/examples/wfs-filter.html new file mode 100644 index 00000000..2c6466d6 --- /dev/null +++ b/examples/wfs-filter.html @@ -0,0 +1,29 @@ + + + + OpenLayers WFS Protocol with Filter + + + + + + + +

WFS Protocol and Filter

+

+ Demonstrates the use of a filter in making GetFeature requests using the WFS protocol. +

+
+
+

+ 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 TYPE "highway" or "road". +

+ See the wfs-filter source + for details on how this is done. +

+
+ + diff --git a/examples/wfs-filter.js b/examples/wfs-filter.js new file mode 100644 index 00000000..18d517cb --- /dev/null +++ b/examples/wfs-filter.js @@ -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 + }); + +} diff --git a/examples/wms-untiled.html b/examples/wms-untiled.html index 92e45b7a..c83ab523 100644 --- a/examples/wms-untiled.html +++ b/examples/wms-untiled.html @@ -30,14 +30,12 @@

WMS Untiled Example

- Shows an example of an "untiled" WMS layer, which requests a single - image for the entire map view. + Shows an example of an "untiled" or "single tile" WMS layer, which + requests a single image for the entire map view.

An untiled layer will only request a single image at a time. - This is equivalent to using the deprecated - OpenLayers.Layer.WMS.Untiled class, which will be removed at 3.0.
diff --git a/examples/wmts-capabilities.js b/examples/wmts-capabilities.js index 9ed04ec3..7f138b4d 100644 --- a/examples/wmts-capabilities.js +++ b/examples/wmts-capabilities.js @@ -4,7 +4,19 @@ var map, format; function init() { - format = new OpenLayers.Format.WMTSCapabilities(); + 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: { @@ -18,7 +30,7 @@ function init() { doc = request.responseText; } var capabilities = format.read(doc); - var layer = createLayer(capabilities, { + var layer = format.createLayer(capabilities, { layer: "medford:buildings", matrixSet: "EPSG:900913", format: "image/png", @@ -50,39 +62,3 @@ function init() { map.setCenter(new OpenLayers.LonLat(-13677832, 5213272), 13); } - -function createLayer(capabilities, config) { - - var contents = capabilities.contents; - var matrixSet = contents.tileMatrixSets[config.matrixSet]; - - // find the layer definition with the given identifier - var layers = contents.layers; - var layer; - for (var i=0, ii=layers.length; i + + + OpenLayers WMTS GetFeatureInfo Example + + + + + + + + +

WMTS GetFeatureInfo Control

+ +

+ The WMTSGetFeatureInfo control allows retrieval of information about + features displayed in a WMTS layer. +

+ +
+ + +
+

+ 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. +

+ See the + wmts-getfeatureinfo.js source to see how this is done. +

+
+ + diff --git a/examples/wmts-getfeatureinfo.js b/examples/wmts-getfeatureinfo.js new file mode 100644 index 00000000..6882c44e --- /dev/null +++ b/examples/wmts-getfeatureinfo.js @@ -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(/]*>([\s\S]*)<\/body>/); + if (match && !match[1].match(/^\s*$/)) { + text = match[1]; + } else { + text = "No " + evt.layer.name + " features in that area.
"; + } + 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); diff --git a/examples/xyz-offset.html b/examples/xyz-offset.html new file mode 100644 index 00000000..8ba464e8 --- /dev/null +++ b/examples/xyz-offset.html @@ -0,0 +1,33 @@ + + + + OpenLayers XYZ with Offset + + + + + + +

XYZ Layer with Offset

+ +
Using a limited set of levels from an XYZ layer with zoomOffset.
+ +
+ +
+

+ 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. +

+

+ See the + xyz-offset.js source to see how this is done. +

+
+ + diff --git a/examples/xyz-offset.js b/examples/xyz-offset.js new file mode 100644 index 00000000..6e7fa947 --- /dev/null +++ b/examples/xyz-offset.js @@ -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); + +} diff --git a/examples/zoomify.html b/examples/zoomify.html index d3fb305c..3e2f05ac 100644 --- a/examples/zoomify.html +++ b/examples/zoomify.html @@ -31,7 +31,7 @@ map.addControl(new OpenLayers.Control.MousePosition()); map.addControl(new OpenLayers.Control.PanZoomBar()); - map.addControl(new OpenLayers.Control.MouseDefaults()); + map.addControl(new OpenLayers.Control.Navigation()); map.addControl(new OpenLayers.Control.KeyboardDefaults()); map.setBaseLayer(zoomify); diff --git a/img/cloud-popup-relative.png b/img/cloud-popup-relative.png index 9db138ab..1215a361 100755 Binary files a/img/cloud-popup-relative.png and b/img/cloud-popup-relative.png differ diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index 9d53295c..46ed30a9 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -92,6 +92,7 @@ "OpenLayers/Request.js", "OpenLayers/Request/XMLHttpRequest.js", "OpenLayers/Projection.js", + "OpenLayers/Location.js", "OpenLayers/Map.js", "OpenLayers/Layer.js", "OpenLayers/Icon.js", @@ -107,13 +108,13 @@ "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", "OpenLayers/Layer/Grid.js", "OpenLayers/Layer/MapGuide.js", "OpenLayers/Layer/MapServer.js", - "OpenLayers/Layer/MapServer/Untiled.js", "OpenLayers/Layer/KaMap.js", "OpenLayers/Layer/KaMapCache.js", "OpenLayers/Layer/MultiMap.js", @@ -122,7 +123,6 @@ "OpenLayers/Layer/WorldWind.js", "OpenLayers/Layer/ArcGIS93Rest.js", "OpenLayers/Layer/WMS.js", - "OpenLayers/Layer/WMS/Untiled.js", "OpenLayers/Layer/WMS/Post.js", "OpenLayers/Layer/WMTS.js", "OpenLayers/Layer/ArcIMS.js", @@ -158,7 +158,6 @@ "OpenLayers/Control/ZoomToMaxExtent.js", "OpenLayers/Control/DragPan.js", "OpenLayers/Control/Navigation.js", - "OpenLayers/Control/MouseDefaults.js", "OpenLayers/Control/MousePosition.js", "OpenLayers/Control/OverviewMap.js", "OpenLayers/Control/KeyboardDefaults.js", @@ -179,6 +178,7 @@ "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", @@ -202,6 +202,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", @@ -226,6 +227,7 @@ "OpenLayers/Layer/PointTrack.js", "OpenLayers/Layer/GML.js", "OpenLayers/Style.js", + "OpenLayers/Style2.js", "OpenLayers/StyleMap.js", "OpenLayers/Rule.js", "OpenLayers/Format.js", @@ -292,9 +294,7 @@ "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", "OpenLayers/Control/NavToolbar.js", "OpenLayers/Control/PanPanel.js", "OpenLayers/Control/Pan.js", @@ -302,6 +302,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. diff --git a/lib/OpenLayers/BaseTypes.js b/lib/OpenLayers/BaseTypes.js index 61b14e3e..d3bdb823 100644 --- a/lib/OpenLayers/BaseTypes.js +++ b/lib/OpenLayers/BaseTypes.js @@ -391,7 +391,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. @@ -431,3 +431,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; + } + +}; diff --git a/lib/OpenLayers/BaseTypes/Bounds.js b/lib/OpenLayers/BaseTypes/Bounds.js index f4bbad11..5a9b83ea 100644 --- a/lib/OpenLayers/BaseTypes/Bounds.js +++ b/lib/OpenLayers/BaseTypes/Bounds.js @@ -477,7 +477,7 @@ OpenLayers.Bounds = OpenLayers.Class({ * * 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. diff --git a/lib/OpenLayers/BaseTypes/Class.js b/lib/OpenLayers/BaseTypes/Class.js index 0f21c37a..c807f1bb 100644 --- a/lib/OpenLayers/BaseTypes/Class.js +++ b/lib/OpenLayers/BaseTypes/Class.js @@ -6,10 +6,6 @@ * Constructor: OpenLayers.Class * Base class used to construct all other classes. Includes support for * multiple inheritance. - * - * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old - * syntax for creating classes and dealing with inheritance - * will be removed. * * To create a new OpenLayers-style class, use the following syntax: * > var MyClass = OpenLayers.Class(prototype); @@ -23,92 +19,37 @@ */ OpenLayers.Class = function() { var Class = function() { - /** - * This following condition can be removed at 3.0 - this is only for - * backwards compatibility while the Class.inherit method is still - * in use. So at 3.0, the following three lines would be replaced with - * simply: - * this.initialize.apply(this, arguments); - */ - if (arguments && arguments[0] != OpenLayers.Class.isPrototype) { - this.initialize.apply(this, arguments); - } + this.initialize.apply(this, arguments); }; var extended = {}; - var parent, initialize; + var parent, initialize, Type; for(var i=0, len=arguments.length; i 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); } Class.prototype = extended; return Class; }; - -/** - * Property: isPrototype - * *Deprecated*. This is no longer needed and will be removed at 3.0. - */ -OpenLayers.Class.isPrototype = function () {}; - -/** - * APIFunction: OpenLayers.create - * *Deprecated*. Old method to create an OpenLayers style class. Use the - * constructor instead. - * - * Returns: - * An OpenLayers class - */ -OpenLayers.Class.create = function() { - return function() { - if (arguments && arguments[0] != OpenLayers.Class.isPrototype) { - this.initialize.apply(this, arguments); - } - }; -}; - - -/** - * APIFunction: inherit - * *Deprecated*. Old method to inherit from one or more OpenLayers style - * classes. Use the constructor instead. - * - * Parameters: - * class - One or more classes can be provided as arguments - * - * Returns: - * An object prototype - */ -OpenLayers.Class.inherit = function () { - var superClass = arguments[0]; - var proto = new superClass(OpenLayers.Class.isPrototype); - for (var i=1, len=arguments.length; i var map = new OpenLayers.Map('map', { controls: [] }); * > * > map.addControl(new OpenLayers.Control.PanZoomBar()); - * > map.addControl(new OpenLayers.Control.MouseToolbar()); * > map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false})); * > map.addControl(new OpenLayers.Control.Permalink()); * > map.addControl(new OpenLayers.Control.Permalink('permalink')); @@ -39,7 +38,7 @@ * > OpenLayers.Util.extend(control, { * > draw: function () { * > // this Handler.Box will intercept the shift-mousedown - * > // before Control.MouseDefault gets to see it + * > // before Control.Navigation gets to see it * > this.box = new OpenLayers.Handler.Box( control, * > {"done": this.notice}, * > {keyMask: OpenLayers.Handler.MOD_SHIFT}); @@ -76,9 +75,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 + * . */ type: null, @@ -351,6 +350,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; diff --git a/lib/OpenLayers/Control/Graticule.js b/lib/OpenLayers/Control/Graticule.js index 1020bce5..d2cdd449 100644 --- a/lib/OpenLayers/Control/Graticule.js +++ b/lib/OpenLayers/Control/Graticule.js @@ -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 {}. */ - 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 * diff --git a/lib/OpenLayers/Control/MouseDefaults.js b/lib/OpenLayers/Control/MouseDefaults.js deleted file mode 100644 index e25360ce..00000000 --- a/lib/OpenLayers/Control/MouseDefaults.js +++ /dev/null @@ -1,367 +0,0 @@ -/* 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 - */ - -/** - * Class: OpenLayers.Control.MouseDefaults - * This class is DEPRECATED in 2.4 and will be removed by 3.0. - * If you need this functionality, use - * instead!!! - * - * This class is DEPRECATED in 2.4 and will be removed by 3.0. - * If you need this functionality, use Control.Navigation instead!!! - * - * Inherits from: - * - - */ -OpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, { - - /** WARNING WARNING WARNING!!! - This class is DEPRECATED in 2.4 and will be removed by 3.0. - If you need this functionality, use Control.Navigation instead!!! */ - - /** - * Property: performedDrag - * {Boolean} - */ - performedDrag: false, - - /** - * Property: wheelObserver - * {Function} - */ - wheelObserver: null, - - /** - * Constructor: OpenLayers.Control.MouseDefaults - */ - initialize: function() { - OpenLayers.Control.prototype.initialize.apply(this, arguments); - }, - - /** - * APIMethod: destroy - */ - destroy: function() { - - if (this.handler) { - this.handler.destroy(); - } - this.handler = null; - - this.map.events.un({ - "click": this.defaultClick, - "dblclick": this.defaultDblClick, - "mousedown": this.defaultMouseDown, - "mouseup": this.defaultMouseUp, - "mousemove": this.defaultMouseMove, - "mouseout": this.defaultMouseOut, - scope: this - }); - - //unregister mousewheel events specifically on the window and document - OpenLayers.Event.stopObserving(window, "DOMMouseScroll", - this.wheelObserver); - OpenLayers.Event.stopObserving(window, "mousewheel", - this.wheelObserver); - OpenLayers.Event.stopObserving(document, "mousewheel", - this.wheelObserver); - this.wheelObserver = null; - - OpenLayers.Control.prototype.destroy.apply(this, arguments); - }, - - /** - * Method: draw - */ - draw: function() { - this.map.events.on({ - "click": this.defaultClick, - "dblclick": this.defaultDblClick, - "mousedown": this.defaultMouseDown, - "mouseup": this.defaultMouseUp, - "mousemove": this.defaultMouseMove, - "mouseout": this.defaultMouseOut, - scope: this - }); - - this.registerWheelEvents(); - - }, - - /** - * Method: registerWheelEvents - */ - registerWheelEvents: function() { - - this.wheelObserver = OpenLayers.Function.bindAsEventListener( - this.onWheelEvent, this - ); - - //register mousewheel events specifically on the window and document - OpenLayers.Event.observe(window, "DOMMouseScroll", this.wheelObserver); - OpenLayers.Event.observe(window, "mousewheel", this.wheelObserver); - OpenLayers.Event.observe(document, "mousewheel", this.wheelObserver); - }, - - /** - * Method: defaultClick - * - * Parameters: - * evt - {Event} - * - * Returns: - * {Boolean} - */ - defaultClick: function (evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - var notAfterDrag = !this.performedDrag; - this.performedDrag = false; - return notAfterDrag; - }, - - /** - * Method: defaultDblClick - * - * Parameters: - * evt - {Event} - */ - defaultDblClick: function (evt) { - var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); - this.map.setCenter(newCenter, this.map.zoom + 1); - OpenLayers.Event.stop(evt); - return false; - }, - - /** - * Method: defaultMouseDown - * - * Parameters: - * evt - {Event} - */ - defaultMouseDown: function (evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - this.mouseDragStart = evt.xy.clone(); - this.performedDrag = false; - if (evt.shiftKey) { - this.map.div.style.cursor = "crosshair"; - this.zoomBox = OpenLayers.Util.createDiv('zoomBox', - this.mouseDragStart, - null, - null, - "absolute", - "2px solid red"); - this.zoomBox.style.backgroundColor = "white"; - this.zoomBox.style.filter = "alpha(opacity=50)"; // IE - this.zoomBox.style.opacity = "0.50"; - this.zoomBox.style.fontSize = "1px"; - this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.viewPortDiv.appendChild(this.zoomBox); - } - document.onselectstart = OpenLayers.Function.False; - OpenLayers.Event.stop(evt); - }, - - /** - * Method: defaultMouseMove - * - * Parameters: - * evt - {Event} - */ - defaultMouseMove: function (evt) { - // record the mouse position, used in onWheelEvent - this.mousePosition = evt.xy.clone(); - - if (this.mouseDragStart != null) { - if (this.zoomBox) { - var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x); - var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y); - this.zoomBox.style.width = Math.max(1, deltaX) + "px"; - this.zoomBox.style.height = Math.max(1, deltaY) + "px"; - if (evt.xy.x < this.mouseDragStart.x) { - this.zoomBox.style.left = evt.xy.x+"px"; - } - if (evt.xy.y < this.mouseDragStart.y) { - this.zoomBox.style.top = evt.xy.y+"px"; - } - } else { - var deltaX = this.mouseDragStart.x - evt.xy.x; - var deltaY = this.mouseDragStart.y - evt.xy.y; - var size = this.map.getSize(); - var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX, - size.h / 2 + deltaY); - var newCenter = this.map.getLonLatFromViewPortPx( newXY ); - this.map.setCenter(newCenter, null, true); - this.mouseDragStart = evt.xy.clone(); - this.map.div.style.cursor = "move"; - } - this.performedDrag = true; - } - }, - - /** - * Method: defaultMouseUp - * - * Parameters: - * evt - {} - */ - defaultMouseUp: function (evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - if (this.zoomBox) { - this.zoomBoxEnd(evt); - } else { - if (this.performedDrag) { - this.map.setCenter(this.map.center); - } - } - document.onselectstart=null; - this.mouseDragStart = null; - this.map.div.style.cursor = ""; - }, - - /** - * Method: defaultMouseOut - * - * Parameters: - * evt - {Event} - */ - defaultMouseOut: function (evt) { - if (this.mouseDragStart != null && - OpenLayers.Util.mouseLeft(evt, this.map.div)) { - if (this.zoomBox) { - this.removeZoomBox(); - } - this.mouseDragStart = null; - } - }, - - - /** - * Method: defaultWheelUp - * User spun scroll wheel up - * - */ - defaultWheelUp: function(evt) { - if (this.map.getZoom() <= this.map.getNumZoomLevels()) { - this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), - this.map.getZoom() + 1); - } - }, - - /** - * Method: defaultWheelDown - * User spun scroll wheel down - */ - defaultWheelDown: function(evt) { - if (this.map.getZoom() > 0) { - this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), - this.map.getZoom() - 1); - } - }, - - /** - * Method: zoomBoxEnd - * Zoombox function. - */ - zoomBoxEnd: function(evt) { - if (this.mouseDragStart != null) { - if (Math.abs(this.mouseDragStart.x - evt.xy.x) > 5 || - Math.abs(this.mouseDragStart.y - evt.xy.y) > 5) { - var start = this.map.getLonLatFromViewPortPx( this.mouseDragStart ); - var end = this.map.getLonLatFromViewPortPx( evt.xy ); - var top = Math.max(start.lat, end.lat); - var bottom = Math.min(start.lat, end.lat); - var left = Math.min(start.lon, end.lon); - var right = Math.max(start.lon, end.lon); - var bounds = new OpenLayers.Bounds(left, bottom, right, top); - this.map.zoomToExtent(bounds); - } else { - var end = this.map.getLonLatFromViewPortPx( evt.xy ); - this.map.setCenter(new OpenLayers.LonLat( - (end.lon), - (end.lat) - ), this.map.getZoom() + 1); - } - this.removeZoomBox(); - } - }, - - /** - * Method: removeZoomBox - * Remove the zoombox from the screen and nullify our reference to it. - */ - removeZoomBox: function() { - this.map.viewPortDiv.removeChild(this.zoomBox); - this.zoomBox = null; - }, - - -/** - * Mouse ScrollWheel code thanks to http://adomas.org/javascript-mouse-wheel/ - */ - - - /** - * Method: onWheelEvent - * Catch the wheel event and handle it xbrowserly - * - * Parameters: - * e - {Event} - */ - onWheelEvent: function(e){ - - // first determine whether or not the wheeling was inside the map - var inMap = false; - var elem = OpenLayers.Event.element(e); - while(elem != null) { - if (this.map && elem == this.map.div) { - inMap = true; - break; - } - elem = elem.parentNode; - } - - if (inMap) { - - var delta = 0; - if (!e) { - e = window.event; - } - if (e.wheelDelta) { - delta = e.wheelDelta/120; - if (window.opera && window.opera.version() < 9.2) { - delta = -delta; - } - } else if (e.detail) { - delta = -e.detail / 3; - } - if (delta) { - // add the mouse position to the event because mozilla has a bug - // with clientX and clientY (see https://bugzilla.mozilla.org/show_bug.cgi?id=352179) - // getLonLatFromViewPortPx(e) returns wrong values - e.xy = this.mousePosition; - - if (delta < 0) { - this.defaultWheelDown(e); - } else { - this.defaultWheelUp(e); - } - } - - //only wheel the map, not the window - OpenLayers.Event.stop(e); - } - }, - - CLASS_NAME: "OpenLayers.Control.MouseDefaults" -}); diff --git a/lib/OpenLayers/Control/MousePosition.js b/lib/OpenLayers/Control/MousePosition.js index a764b8da..387a98dc 100644 --- a/lib/OpenLayers/Control/MousePosition.js +++ b/lib/OpenLayers/Control/MousePosition.js @@ -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" }); diff --git a/lib/OpenLayers/Control/MouseToolbar.js b/lib/OpenLayers/Control/MouseToolbar.js deleted file mode 100644 index c960608d..00000000 --- a/lib/OpenLayers/Control/MouseToolbar.js +++ /dev/null @@ -1,405 +0,0 @@ -/* 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/Control/MouseDefaults.js - */ - -/** - * Class: OpenLayers.Control.MouseToolbar - * This class is DEPRECATED in 2.4 and will be removed by 3.0. - * If you need this functionality, use - * instead!!! - */ -OpenLayers.Control.MouseToolbar = OpenLayers.Class( - OpenLayers.Control.MouseDefaults, { - - /** - * Property: mode - */ - mode: null, - /** - * Property: buttons - */ - buttons: null, - - /** - * APIProperty: direction - * {String} 'vertical' or 'horizontal' - */ - direction: "vertical", - - /** - * Property: buttonClicked - * {String} - */ - buttonClicked: null, - - /** - * Constructor: OpenLayers.Control.MouseToolbar - * - * Parameters: - * position - {} - * direction - {String} - */ - initialize: function(position, direction) { - OpenLayers.Control.prototype.initialize.apply(this, arguments); - this.position = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X, - OpenLayers.Control.MouseToolbar.Y); - if (position) { - this.position = position; - } - if (direction) { - this.direction = direction; - } - this.measureDivs = []; - }, - - /** - * APIMethod: destroy - */ - destroy: function() { - for( var btnId in this.buttons) { - var btn = this.buttons[btnId]; - btn.map = null; - btn.events.destroy(); - } - OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this, - arguments); - }, - - /** - * Method: draw - */ - draw: function() { - OpenLayers.Control.prototype.draw.apply(this, arguments); - OpenLayers.Control.MouseDefaults.prototype.draw.apply(this, arguments); - this.buttons = {}; - var sz = new OpenLayers.Size(28,28); - var centered = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0); - this._addButton("zoombox", "drag-rectangle-off.png", "drag-rectangle-on.png", centered, sz, "Shift->Drag to zoom to area"); - centered = centered.add((this.direction == "vertical" ? 0 : sz.w), (this.direction == "vertical" ? sz.h : 0)); - this._addButton("pan", "panning-hand-off.png", "panning-hand-on.png", centered, sz, "Drag the map to pan."); - centered = centered.add((this.direction == "vertical" ? 0 : sz.w), (this.direction == "vertical" ? sz.h : 0)); - this.switchModeTo("pan"); - - return this.div; - }, - - /** - * Method: _addButton - */ - _addButton:function(id, img, activeImg, xy, sz, title) { - var imgLocation = OpenLayers.Util.getImagesLocation() + img; - var activeImgLocation = OpenLayers.Util.getImagesLocation() + activeImg; - // var btn = new ol.AlphaImage("_"+id, imgLocation, xy, sz); - var btn = OpenLayers.Util.createAlphaImageDiv( - "OpenLayers_Control_MouseToolbar_" + id, - xy, sz, imgLocation, "absolute"); - - //we want to add the outer div - this.div.appendChild(btn); - btn.imgLocation = imgLocation; - btn.activeImgLocation = activeImgLocation; - - btn.events = new OpenLayers.Events(this, btn, null, true); - btn.events.on({ - "mousedown": this.buttonDown, - "mouseup": this.buttonUp, - "dblclick": OpenLayers.Event.stop, - scope: this - }); - btn.action = id; - btn.title = title; - btn.alt = title; - btn.map = this.map; - - //we want to remember/reference the outer div - this.buttons[id] = btn; - return btn; - }, - - /** - * Method: buttonDown - * - * Parameters: - * evt - {Event} - */ - buttonDown: function(evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - this.buttonClicked = evt.element.action; - OpenLayers.Event.stop(evt); - }, - - /** - * Method: buttonUp - * - * Parameters: - * evt - {Event} - */ - buttonUp: function(evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - if (this.buttonClicked != null) { - if (this.buttonClicked == evt.element.action) { - this.switchModeTo(evt.element.action); - } - OpenLayers.Event.stop(evt); - this.buttonClicked = null; - } - }, - - /** - * Method: defaultDblClick - * - * Parameters: - * evt - {Event} - */ - defaultDblClick: function (evt) { - this.switchModeTo("pan"); - this.performedDrag = false; - var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); - this.map.setCenter(newCenter, this.map.zoom + 1); - OpenLayers.Event.stop(evt); - return false; - }, - - /** - * Method: defaultMouseDown - * - * Parameters: - * evt - {Event} - */ - defaultMouseDown: function (evt) { - if (!OpenLayers.Event.isLeftClick(evt)) { - return; - } - this.mouseDragStart = evt.xy.clone(); - this.performedDrag = false; - this.startViaKeyboard = false; - if (evt.shiftKey && this.mode !="zoombox") { - this.switchModeTo("zoombox"); - this.startViaKeyboard = true; - } else if (evt.altKey && this.mode !="measure") { - this.switchModeTo("measure"); - } else if (!this.mode) { - this.switchModeTo("pan"); - } - - switch (this.mode) { - case "zoombox": - this.map.div.style.cursor = "crosshair"; - this.zoomBox = OpenLayers.Util.createDiv('zoomBox', - this.mouseDragStart, - null, - null, - "absolute", - "2px solid red"); - this.zoomBox.style.backgroundColor = "white"; - this.zoomBox.style.filter = "alpha(opacity=50)"; // IE - this.zoomBox.style.opacity = "0.50"; - this.zoomBox.style.fontSize = "1px"; - this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.viewPortDiv.appendChild(this.zoomBox); - this.performedDrag = true; - break; - case "measure": - var distance = ""; - if (this.measureStart) { - var measureEnd = this.map.getLonLatFromViewPortPx(this.mouseDragStart); - distance = OpenLayers.Util.distVincenty(this.measureStart, measureEnd); - distance = Math.round(distance * 100) / 100; - distance = distance + "km"; - this.measureStartBox = this.measureBox; - } - this.measureStart = this.map.getLonLatFromViewPortPx(this.mouseDragStart);; - this.measureBox = OpenLayers.Util.createDiv(null, - this.mouseDragStart.add( - -2-parseInt(this.map.layerContainerDiv.style.left), - -2-parseInt(this.map.layerContainerDiv.style.top)), - null, - null, - "absolute"); - this.measureBox.style.width="4px"; - this.measureBox.style.height="4px"; - this.measureBox.style.fontSize = "1px"; - this.measureBox.style.backgroundColor="red"; - this.measureBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.layerContainerDiv.appendChild(this.measureBox); - if (distance) { - this.measureBoxDistance = OpenLayers.Util.createDiv(null, - this.mouseDragStart.add( - -2-parseInt(this.map.layerContainerDiv.style.left), - 2-parseInt(this.map.layerContainerDiv.style.top)), - null, - null, - "absolute"); - - this.measureBoxDistance.innerHTML = distance; - this.measureBoxDistance.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.layerContainerDiv.appendChild(this.measureBoxDistance); - this.measureDivs.push(this.measureBoxDistance); - } - this.measureBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; - this.map.layerContainerDiv.appendChild(this.measureBox); - this.measureDivs.push(this.measureBox); - break; - default: - this.map.div.style.cursor = "move"; - break; - } - document.onselectstart = OpenLayers.Function.False; - OpenLayers.Event.stop(evt); - }, - - /** - * Method: switchModeTo - * - * Parameters: - * mode - {String} - */ - switchModeTo: function(mode) { - if (mode != this.mode) { - - - if (this.mode && this.buttons[this.mode]) { - OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode], null, null, null, this.buttons[this.mode].imgLocation); - } - if (this.mode == "measure" && mode != "measure") { - for(var i=0, len=this.measureDivs.length; i} The control which is activated when the control is * activated (turned on), which also happens at instantiation. + * If is true, 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 method is called. + * + * Specific properties for controls on a panel: + * type - {Number} One of , + * , . + * If not provided, is assumed. + * title - {string} Text displayed when mouse is over the icon that + * represents the control. + * + * The of a control determines the behavior when + * clicking its icon: + * - The control is activated and other + * controls of this type in the same panel are deactivated. This is + * the default type. + * - The active state of the control is + * toggled. + * - The + * method of the control is called, + * but its active state is not changed. + * + * If a control is , 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; i0) { + 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} */ @@ -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} + * controls - {} 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)} Controls to add into map. + */ + addControlsToMap: function (controls) { + var control; + for (var i=0, len=controls.length; i 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", @@ -499,7 +499,7 @@ OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { }, onComplete: function(feature, pixel) { control.events.triggerEvent("transformcomplete", - {feature: feature}); + {feature: control.feature}); } }); }, diff --git a/lib/OpenLayers/Control/WMSGetFeatureInfo.js b/lib/OpenLayers/Control/WMSGetFeatureInfo.js index 0080ea2d..078e75f5 100644 --- a/lib/OpenLayers/Control/WMSGetFeatureInfo.js +++ b/lib/OpenLayers/Control/WMSGetFeatureInfo.js @@ -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: @@ -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; diff --git a/lib/OpenLayers/Control/WMTSGetFeatureInfo.js b/lib/OpenLayers/Control/WMTSGetFeatureInfo.js new file mode 100644 index 00000000..37cc527e --- /dev/null +++ b/lib/OpenLayers/Control/WMTSGetFeatureInfo.js @@ -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.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 + * {} object created when the hover + * option is set to false. Default is "click". + */ + clickCallback: "click", + + /** + * Property: layers + * {Array()} 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 + * {} A format for parsing GetFeatureInfo responses. + * Default is . + */ + format: null, + + /** + * Property: formatOptions + * {Object} Optional properties to set on the format (if one is not provided + * in the 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 for this control + */ + handler: null, + + /** + * Property: hoverRequest + * {} contains the currently running hover request + * (if any). + */ + hoverRequest: null, + + /** + * Constant: EVENT_TYPES + * + * Supported event types (in addition to those from ): + * 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: + * + * 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 - {} + */ + 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 - {} A WMTS layer. + * xy - {} 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 - {} 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 0) { + OpenLayers.Element.addClass(this.map.viewPortDiv, "olCursorWait"); + } + } + }, + + /** + * Method: handleResponse + * Handler for the GetFeatureInfo response. + * + * Parameters: + * xy - {} The position on the map where the mouse event + * occurred. + * request - {XMLHttpRequest} The request object. + * layer - {} 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 - {} + */ + setMap: function(map) { + this.handler.setMap(map); + OpenLayers.Control.prototype.setMap.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Control.WMTSGetFeatureInfo" +}); diff --git a/lib/OpenLayers/Feature/Vector.js b/lib/OpenLayers/Feature/Vector.js index 0a1b7695..5b871c6e 100644 --- a/lib/OpenLayers/Feature/Vector.js +++ b/lib/OpenLayers/Feature/Vector.js @@ -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, diff --git a/lib/OpenLayers/Filter.js b/lib/OpenLayers/Filter.js index 31cbcd36..55f966ca 100644 --- a/lib/OpenLayers/Filter.js +++ b/lib/OpenLayers/Filter.js @@ -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. diff --git a/lib/OpenLayers/Filter/Comparison.js b/lib/OpenLayers/Filter/Comparison.js index b8d4e92a..5c6edc65 100644 --- a/lib/OpenLayers/Filter/Comparison.js +++ b/lib/OpenLayers/Filter/Comparison.js @@ -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; diff --git a/lib/OpenLayers/Filter/Logical.js b/lib/OpenLayers/Filter/Logical.js index a438af45..fd0f9cbc 100644 --- a/lib/OpenLayers/Filter/Logical.js +++ b/lib/OpenLayers/Filter/Logical.js @@ -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. diff --git a/lib/OpenLayers/Format/Context.js b/lib/OpenLayers/Format/Context.js index 61dc9205..72002aee 100644 --- a/lib/OpenLayers/Format/Context.js +++ b/lib/OpenLayers/Format/Context.js @@ -128,6 +128,11 @@ OpenLayers.Format.Context = OpenLayers.Class({ 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 }; diff --git a/lib/OpenLayers/Format/GML.js b/lib/OpenLayers/Format/GML.js index e454c848..7ee6afb4 100644 --- a/lib/OpenLayers/Format/GML.js +++ b/lib/OpenLayers/Format/GML.js @@ -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 0) { - var coords = OpenLayers.String.trim(this.concatChildValues(line[0])).split(/\s+/); + var coords = OpenLayers.String.trim(this.getChildValues(line[0])).split(/\s+/); var components = []; var point; for (var i=0, len=coords.length; i 0) { - var coords = OpenLayers.String.trim(this.concatChildValues(polygon[0])).split(/\s+/); + var coords = OpenLayers.String.trim(this.getChildValues(polygon[0])).split(/\s+/); var components = []; var point; for (var i=0, len=coords.length; i 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: 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 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 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 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. diff --git a/lib/OpenLayers/Format/OWSCommon/v1_1_0.js b/lib/OpenLayers/Format/OWSCommon/v1_1_0.js index 35397351..3cc55d71 100644 --- a/lib/OpenLayers/Format/OWSCommon/v1_1_0.js +++ b/lib/OpenLayers/Format/OWSCommon/v1_1_0.js @@ -51,6 +51,9 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.OWSCommo }, "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"]) }, diff --git a/lib/OpenLayers/Format/SLD/v1.js b/lib/OpenLayers/Format/SLD/v1.js index 78b8a066..08c231a1 100644 --- a/lib/OpenLayers/Format/SLD/v1.js +++ b/lib/OpenLayers/Format/SLD/v1.js @@ -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 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 @@ -211,11 +249,18 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, { } }, "RasterSymbolizer": function(node, rule) { - // OpenLayers doesn't do painter's order, instead we extend - var symbolizer = rule.symbolizer["Raster"] || {}; - this.readChildNodes(node, symbolizer); - // in case it didn't exist before - rule.symbolizer["Raster"] = symbolizer; + 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 = {}; @@ -236,32 +281,55 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, { }); }, "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"] || { + var config = { fill: false, stroke: false }; - this.readChildNodes(node, symbolizer); - // in case it didn't exist before - rule.symbolizer["Polygon"] = symbolizer; + 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"] || { + var config = { fill: false, stroke: false, graphic: false }; - this.readChildNodes(node, symbolizer); - // in case it didn't exist before - rule.symbolizer["Point"] = symbolizer; + 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; @@ -566,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 0) { + clone = style.clone(); + clone.rules = rulesByZ[zValues[i]]; + this.writeNode("FeatureTypeStyle", clone, node); + } + } + } else { + this.writeNode("FeatureTypeStyle", style, node); + } return node; }, @@ -626,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} A cached versioned format used for reading. */ - parser: null, + 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 @@ -70,9 +83,77 @@ OpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML, { if (!constr) { throw new Error("Can't find a WMTS capabilities parser for version " + version); } - var parser = new constr(this.options); + 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 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: + * {} 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 prototype. + */ + yx: null, + /** * Property: defaultPrefix * {String} The default namespace alias for creating element nodes. @@ -50,6 +59,10 @@ OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class( 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); }, /** @@ -106,7 +119,7 @@ OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class( }, "Style": function(node, obj) { var style = {}; - style.isDefault = node.getAttribute("isDefault"); + style.isDefault = (node.getAttribute("isDefault") === "true"); this.readChildNodes(node, style); obj.styles.push(style); }, @@ -123,8 +136,9 @@ OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class( // duck type wmts:Contents by looking for layers if (obj.layers) { // TileMatrixSet as object type in schema - var tileMatrixSet = {}; - tileMatrixSet.matrixIds = []; + var tileMatrixSet = { + matrixIds: [] + }; this.readChildNodes(node, tileMatrixSet); obj.tileMatrixSets[tileMatrixSet.identifier] = tileMatrixSet; } else { @@ -133,7 +147,9 @@ OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class( } }, "TileMatrix": function(node, obj) { - var tileMatrix = {}; + var tileMatrix = { + supportedCRS: obj.supportedCRS + }; this.readChildNodes(node, tileMatrix); obj.matrixIds.push(tileMatrix); }, @@ -143,7 +159,25 @@ OpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class( "TopLeftCorner": function(node, obj) { var topLeftCorner = this.getChildValue(node); var coords = topLeftCorner.split(" "); - obj.topLeftCorner = new OpenLayers.LonLat(parseFloat(coords[1]), parseFloat(coords[0])); + // 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)); diff --git a/lib/OpenLayers/Format/XML.js b/lib/OpenLayers/Format/XML.js index 0c0a2cbc..4ccb3ccf 100644 --- a/lib/OpenLayers/Format/XML.js +++ b/lib/OpenLayers/Format/XML.js @@ -243,6 +243,9 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, { */ createTextNode: function(text) { var node; + if (typeof text !== "string") { + text = String(text); + } if(this.xmldom) { node = this.xmldom.createTextNode(text); } else { @@ -375,40 +378,6 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, { return value; }, - /** - * APIMethod: concatChildValues - * *Deprecated*. Use instead. - * - * Concatenate the value of all child nodes if any exist, or return an - * optional default string. Returns an empty string if no children - * exist and no default value is supplied. Not optimized for large - * numbers of child nodes. - * - * Parameters: - * node - {DOMElement} The element used to look for child values. - * def - {String} Optional string to return in the event that no - * child exist. - * - * Returns: - * {String} The concatenated value of all child nodes of the given node. - */ - concatChildValues: function(node, def) { - var value = ""; - var child = node.firstChild; - var childValue; - while(child) { - childValue = child.nodeValue; - if(childValue) { - value += childValue; - } - child = child.nextSibling; - } - if(value == "" && def != undefined) { - value = def; - } - return value; - }, - /** * APIMethod: isSimpleContent * Test if the given node has only simple content (i.e. no child element @@ -568,9 +537,6 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, { } var value = options.value; if(value != null) { - if(typeof value == "boolean") { - value = String(value); - } node.appendChild(this.createTextNode(value)); } return node; diff --git a/lib/OpenLayers/Geometry/Collection.js b/lib/OpenLayers/Geometry/Collection.js index 3780dcb0..1fe7ad93 100644 --- a/lib/OpenLayers/Geometry/Collection.js +++ b/lib/OpenLayers/Geometry/Collection.js @@ -261,22 +261,67 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, { /** * APIMethod: getCentroid * + * Compute the centroid for this geometry collection. + * + * Parameters: + * weighted - {Boolean} Perform the getCentroid computation recursively, + * returning an area weighted average of all geometries in this collection. + * * Returns: * {} The centroid of the collection */ - getCentroid: function() { - return this.components.length && this.components[0].getCentroid(); - /* - var centroid; - for (var i=0, len=this.components.length; i 0) ? area : minArea; + centroids.push(centroid); } - return centroid; - */ + len = areas.length; + if (areaSum === 0) { + // all the components in this collection have 0 area + // probably a collection of points -- weight all the points the same + for (var i=0; i= 0) { + + this.initResolutions(); + break; + } + } + } }, - + /** * APIMethod: onMapResize * This function can be implemented by subclasses @@ -542,12 +570,12 @@ OpenLayers.Layer = OpenLayers.Class({ // been set this.maxExtent = this.maxExtent || this.map.maxExtent; this.minExtent = this.minExtent || this.map.minExtent; + this.projection = this.projection || this.map.projection; - - if (this.projection && typeof this.projection == "string") { + if (typeof this.projection == "string") { this.projection = new OpenLayers.Projection(this.projection); } - + // Check the projection to see if we can get units -- if not, refer // to properties. this.units = this.projection.getUnits() || @@ -770,7 +798,7 @@ OpenLayers.Layer = OpenLayers.Class({ // get resolution data from layer config // (we also set alwaysInRange in the layer as appropriate) for(i=0, len=this.RESOLUTION_PROPERTIES.length; i} An exact clone of this layer + */ + clone: function (obj) { + + if (obj == null) { + obj = new OpenLayers.Layer.ArcIMS(this.name, + this.url, + this.getOptions()); + } + + //get all additions from superclasses + obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]); + + // copy/set any non-init, non-simple values here + + return obj; + }, /** * Method: addTile diff --git a/lib/OpenLayers/Layer/GeoRSS.js b/lib/OpenLayers/Layer/GeoRSS.js index 7c7cbc78..0d8ba471 100644 --- a/lib/OpenLayers/Layer/GeoRSS.js +++ b/lib/OpenLayers/Layer/GeoRSS.js @@ -210,7 +210,7 @@ OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, { contentHTML += '
'; contentHTML += description; contentHTML += '
'; - data['popupContentHTML'] = contentHTML; + data.popupContentHTML = contentHTML; } var feature = new OpenLayers.Feature(this, location, data); this.features.push(feature); diff --git a/lib/OpenLayers/Layer/Google.js b/lib/OpenLayers/Layer/Google.js index 71bcdcc2..1d84ceff 100644 --- a/lib/OpenLayers/Layer/Google.js +++ b/lib/OpenLayers/Layer/Google.js @@ -7,7 +7,6 @@ * @requires OpenLayers/Layer/SphericalMercator.js * @requires OpenLayers/Layer/EventPane.js * @requires OpenLayers/Layer/FixedZoomLevels.js - * @requires OpenLayers/Console.js */ /** @@ -70,6 +69,14 @@ OpenLayers.Layer.Google = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will @@ -80,23 +87,10 @@ OpenLayers.Layer.Google = OpenLayers.Class( sphericalMercator: false, /** - * Property: dragObject - * {GDraggableObject} Since 2.93, Google has exposed the ability to get - * the maps GDraggableObject. We can now use this for smooth panning - */ - dragObject: null, - - /** - * Property: termsOfUse - * {DOMElement} Div for Google's copyright and terms of use link - */ - termsOfUse: null, - - /** - * Property: poweredBy - * {DOMElement} Div for Google's powered by logo and link + * Property: version + * {Number} The version of the Google Maps API */ - poweredBy: null, + version: null, /** * Constructor: OpenLayers.Layer.Google @@ -107,16 +101,34 @@ OpenLayers.Layer.Google = OpenLayers.Class( * on the layer. */ initialize: function(name, options) { - OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments); + options = options || {}; + if(!options.version) { + options.version = typeof GMap2 === "function" ? "2" : "3"; + } + var mixin = OpenLayers.Layer.Google["v" + + options.version.replace(/\./g, "_")]; + if (mixin) { + OpenLayers.Util.applyDefaults(options, mixin); + } else { + throw "Unsupported Google Maps API version: " + options.version; + } + + OpenLayers.Util.applyDefaults(options, mixin.DEFAULTS); + if (options.maxExtent) { + options.maxExtent = options.maxExtent.clone(); + } + + OpenLayers.Layer.EventPane.prototype.initialize.apply(this, + [name, options]); OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, - arguments); - this.addContainerPxFunction(); + [name, options]); + if (this.sphericalMercator) { OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator); this.initMercatorParameters(); } }, - + /** * Method: clone * Create a clone of this layer @@ -135,116 +147,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( this.name, this.getOptions() ); }, - - /** - * Method: loadMapObject - * Load the GMap and register appropriate event listeners. If we can't - * load GMap2, then display a warning message. - */ - loadMapObject:function() { - if (!this.type) { - this.type = G_NORMAL_MAP; - } - var mapObject, termsOfUse, poweredBy; - var cache = OpenLayers.Layer.Google.cache[this.map.id]; - if (cache) { - // there are already Google layers added to this map - mapObject = cache.mapObject; - termsOfUse = cache.termsOfUse; - poweredBy = cache.poweredBy; - // increment the layer count - ++cache.count; - } else { - // this is the first Google layer for this map - - var container = this.map.viewPortDiv; - var div = document.createElement("div"); - div.id = this.map.id + "_GMap2Container"; - div.style.position = "absolute"; - div.style.width = "100%"; - div.style.height = "100%"; - container.appendChild(div); - - // create GMap and shuffle elements - try { - mapObject = new GMap2(div); - - // move the ToS and branding stuff up to the container div - termsOfUse = div.lastChild; - container.appendChild(termsOfUse); - termsOfUse.style.zIndex = "1100"; - termsOfUse.style.right = ""; - termsOfUse.style.bottom = ""; - termsOfUse.className = "olLayerGoogleCopyright"; - - poweredBy = div.lastChild; - container.appendChild(poweredBy); - poweredBy.style.zIndex = "1100"; - poweredBy.style.right = ""; - poweredBy.style.bottom = ""; - poweredBy.className = "olLayerGooglePoweredBy gmnoprint"; - - } catch (e) { - OpenLayers.Console.error(e); - return; - } - // cache elements for use by any other google layers added to - // this same map - OpenLayers.Layer.Google.cache[this.map.id] = { - mapObject: mapObject, - termsOfUse: termsOfUse, - poweredBy: poweredBy, - count: 1 - }; - } - - this.mapObject = mapObject; - this.termsOfUse = termsOfUse; - this.poweredBy = poweredBy; - - // ensure this layer type is one of the mapObject types - if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(), - this.type) === -1) { - this.mapObject.addMapType(this.type); - } - - //since v 2.93 getDragObject is now available. - if(typeof mapObject.getDragObject == "function") { - this.dragObject = mapObject.getDragObject(); - } else { - this.dragPanMapObject = null; - } - - if(this.isBaseLayer === false) { - this.setGMapVisibility(this.div.style.display !== "none"); - } - - }, - - /** - * APIMethod: onMapResize - */ - onMapResize: function() { - // workaround for resizing of invisible or not yet fully loaded layers - // where GMap2.checkResize() does not work. We need to load the GMap - // for the old div size, then checkResize(), and then call - // layer.moveTo() to trigger GMap.setCenter() (which will finish - // the GMap initialization). - if(this.visibility && this.mapObject.isLoaded()) { - this.mapObject.checkResize(); - } else { - if(!this._resized) { - var layer = this; - var handle = GEvent.addListener(this.mapObject, "load", function() { - GEvent.removeListener(handle); - delete layer._resized; - layer.mapObject.checkResize(); - layer.moveTo(layer.map.getCenter(), layer.map.getZoom()); - }); - } - this._resized = true; - } - }, /** * APIMethod: setVisibility @@ -262,48 +164,39 @@ OpenLayers.Layer.Google = OpenLayers.Class( * visible - {Boolean} Display the layer (if in range) */ setVisibility: function(visible) { - this.setGMapVisibility(visible); // sharing a map container, opacity has to be set per layer var opacity = this.opacity == null ? 1 : this.opacity; OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this, arguments); this.setOpacity(opacity); }, - /** - * Method: setGMapVisibility - * Display the GMap container and associated elements. + /** + * APIMethod: display + * Hide or show the Layer * * Parameters: - * visible - {Boolean} Display the GMap elements. + * display - {Boolean} */ - setGMapVisibility: function(visible) { - var cache = OpenLayers.Layer.Google.cache[this.map.id]; - if (cache) { - var container = this.mapObject.getContainer(); - if (visible === true) { - this.mapObject.setMapType(this.type); - container.style.display = ""; - this.termsOfUse.style.left = ""; - this.termsOfUse.style.display = ""; - this.poweredBy.style.display = ""; - cache.displayed = this.id; - } else { - if (cache.displayed === this.id) { - delete cache.displayed; - } - if (!cache.displayed) { - container.style.display = "none"; - this.termsOfUse.style.display = "none"; - // move ToU far to the left in addition to setting display - // to "none", because at the end of the GMap2 load - // sequence, display: none will be unset and ToU would be - // visible after loading a map with a google layer that is - // initially hidden. - this.termsOfUse.style.left = "-9999px"; - this.poweredBy.style.display = "none"; - } - } + display: function(visible) { + if (!this._dragging) { + this.setGMapVisibility(visible); } + OpenLayers.Layer.EventPane.prototype.display.apply(this, arguments); + }, + + /** + * Method: moveTo + * + * Parameters: + * bound - {} + * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to + * do some init work in that case. + * dragging - {Boolean} + */ + moveTo: function(bounds, zoomChanged, dragging) { + this._dragging = dragging; + OpenLayers.Layer.EventPane.prototype.moveTo.apply(this, arguments); + delete this._dragging; }, /** @@ -326,7 +219,7 @@ OpenLayers.Layer.Google = OpenLayers.Class( // Though this layer's opacity may not change, we're sharing a container // and need to update the opacity for the entire container. if (this.getVisibility()) { - var container = this.mapObject.getContainer(); + var container = this.getMapContainer(); OpenLayers.Util.modifyDOMElement( container, null, null, null, null, null, null, opacity ); @@ -347,7 +240,7 @@ OpenLayers.Layer.Google = OpenLayers.Class( this.setGMapVisibility(false); var cache = OpenLayers.Layer.Google.cache[this.map.id]; if (cache && cache.count <= 1) { - this.removeGMapElements(false); + this.removeGMapElements(); } } OpenLayers.Layer.EventPane.prototype.destroy.apply(this, arguments); @@ -362,7 +255,7 @@ OpenLayers.Layer.Google = OpenLayers.Class( var cache = OpenLayers.Layer.Google.cache[this.map.id]; if (cache) { // remove shared elements from dom - var container = this.mapObject && this.mapObject.getContainer(); + var container = this.mapObject && this.getMapContainer(); if (container && container.parentNode) { container.parentNode.removeChild(container); } @@ -408,33 +301,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( OpenLayers.Layer.EventPane.prototype.removeMap.apply(this, arguments); }, - /** - * APIMethod: getZoomForExtent - * - * Parameters: - * bounds - {} - * - * Returns: - * {Integer} Corresponding zoom level for a specified Bounds. - * If mapObject is not loaded or not centered, returns null - * - getZoomForExtent: function (bounds) { - var zoom = null; - if (this.mapObject != null) { - var moBounds = this.getMapObjectBoundsFromOLBounds(bounds); - var moZoom = this.getMapObjectZoomFromMapObjectBounds(moBounds); - - //make sure zoom is within bounds - var moZoom = Math.min(Math.max(moZoom, this.minZoomLevel), - this.maxZoomLevel); - - zoom = this.getOLZoomFromMapObjectZoom(moZoom); - } - return zoom; - }, - - */ - // // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds // @@ -470,62 +336,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( return olBounds; }, - /** - * APIMethod: getMapObjectBoundsFromOLBounds - * - * Parameters: - * olBounds - {} - * - * Returns: - * {Object} A MapObject Bounds, translated from olBounds - * Returns null if null value is passed in - */ - getMapObjectBoundsFromOLBounds: function(olBounds) { - var moBounds = null; - if (olBounds != null) { - var sw = this.sphericalMercator ? - this.inverseMercator(olBounds.bottom, olBounds.left) : - new OpenLayers.LonLat(olBounds.bottom, olBounds.left); - var ne = this.sphericalMercator ? - this.inverseMercator(olBounds.top, olBounds.right) : - new OpenLayers.LonLat(olBounds.top, olBounds.right); - moBounds = new GLatLngBounds(new GLatLng(sw.lat, sw.lon), - new GLatLng(ne.lat, ne.lon)); - } - return moBounds; - }, - - /** - * Method: addContainerPxFunction - * Hack-on function because GMAPS does not give it to us - * - * Parameters: - * gLatLng - {GLatLng} - * - * Returns: - * {GPoint} A GPoint specifying gLatLng translated into "Container" coords - */ - addContainerPxFunction: function() { - if ( (typeof GMap2 != "undefined") && - !GMap2.prototype.fromLatLngToContainerPixel) { - - GMap2.prototype.fromLatLngToContainerPixel = function(gLatLng) { - - // first we translate into "DivPixel" - var gPoint = this.fromLatLngToDivPixel(gLatLng); - - // locate the sliding "Div" div - var div = this.getContainer().firstChild.firstChild; - - // adjust by the offset of "Div" and voila! - gPoint.x += div.offsetLeft; - gPoint.y += div.offsetTop; - - return gPoint; - }; - } - }, - /** * APIMethod: getWarningHTML * @@ -547,29 +357,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( // Get&Set Center, Zoom - /** - * APIMethod: setMapObjectCenter - * Set the mapObject to the specified center and zoom - * - * Parameters: - * center - {Object} MapObject LonLat format - * zoom - {int} MapObject zoom format - */ - setMapObjectCenter: function(center, zoom) { - this.mapObject.setCenter(center, zoom); - }, - - /** - * APIMethod: dragPanMapObject - * - * Parameters: - * dX - {Integer} - * dY - {Integer} - */ - dragPanMapObject: function(dX, dY) { - this.dragObject.moveBy(new GSize(-dX, dY)); - }, - /** * APIMethod: getMapObjectCenter * @@ -590,11 +377,334 @@ OpenLayers.Layer.Google = OpenLayers.Class( return this.mapObject.getZoom(); }, - - // LonLat - Pixel Translation + /************************************ + * * + * MapObject Primitives * + * * + ************************************/ + + + // LonLat + /** - * APIMethod: getMapObjectLonLatFromMapObjectPixel + * APIMethod: getLongitudeFromMapObjectLonLat + * + * Parameters: + * moLonLat - {Object} MapObject LonLat format + * + * Returns: + * {Float} Longitude of the given MapObject LonLat + */ + getLongitudeFromMapObjectLonLat: function(moLonLat) { + return this.sphericalMercator ? + this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon : + moLonLat.lng(); + }, + + /** + * APIMethod: getLatitudeFromMapObjectLonLat + * + * Parameters: + * moLonLat - {Object} MapObject LonLat format + * + * Returns: + * {Float} Latitude of the given MapObject LonLat + */ + getLatitudeFromMapObjectLonLat: function(moLonLat) { + var lat = this.sphericalMercator ? + this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat : + moLonLat.lat(); + return lat; + }, + + // Pixel + + /** + * APIMethod: getXFromMapObjectPixel + * + * Parameters: + * moPixel - {Object} MapObject Pixel format + * + * Returns: + * {Integer} X value of the MapObject Pixel + */ + getXFromMapObjectPixel: function(moPixel) { + return moPixel.x; + }, + + /** + * APIMethod: getYFromMapObjectPixel + * + * Parameters: + * moPixel - {Object} MapObject Pixel format + * + * Returns: + * {Integer} Y value of the MapObject Pixel + */ + getYFromMapObjectPixel: function(moPixel) { + return moPixel.y; + }, + + CLASS_NAME: "OpenLayers.Layer.Google" +}); + +/** + * Property: OpenLayers.Layer.Google.cache + * {Object} Cache for elements that should only be created once per map. + */ +OpenLayers.Layer.Google.cache = {}; + + +/** + * Constant: OpenLayers.Layer.Google.v2 + * + * Mixin providing functionality specific to the Google Maps API v2. + */ +OpenLayers.Layer.Google.v2 = { + + /** + * Property: termsOfUse + * {DOMElement} Div for Google's copyright and terms of use link + */ + termsOfUse: null, + + /** + * Property: poweredBy + * {DOMElement} Div for Google's powered by logo and link + */ + poweredBy: null, + + /** + * Property: dragObject + * {GDraggableObject} Since 2.93, Google has exposed the ability to get + * the maps GDraggableObject. We can now use this for smooth panning + */ + dragObject: null, + + /** + * Method: loadMapObject + * Load the GMap and register appropriate event listeners. If we can't + * load GMap2, then display a warning message. + */ + loadMapObject:function() { + if (!this.type) { + this.type = G_NORMAL_MAP; + } + var mapObject, termsOfUse, poweredBy; + var cache = OpenLayers.Layer.Google.cache[this.map.id]; + if (cache) { + // there are already Google layers added to this map + mapObject = cache.mapObject; + termsOfUse = cache.termsOfUse; + poweredBy = cache.poweredBy; + // increment the layer count + ++cache.count; + } else { + // this is the first Google layer for this map + + var container = this.map.viewPortDiv; + var div = document.createElement("div"); + div.id = this.map.id + "_GMap2Container"; + div.style.position = "absolute"; + div.style.width = "100%"; + div.style.height = "100%"; + container.appendChild(div); + + // create GMap and shuffle elements + try { + mapObject = new GMap2(div); + + // move the ToS and branding stuff up to the container div + termsOfUse = div.lastChild; + container.appendChild(termsOfUse); + termsOfUse.style.zIndex = "1100"; + termsOfUse.style.right = ""; + termsOfUse.style.bottom = ""; + termsOfUse.className = "olLayerGoogleCopyright"; + + poweredBy = div.lastChild; + container.appendChild(poweredBy); + poweredBy.style.zIndex = "1100"; + poweredBy.style.right = ""; + poweredBy.style.bottom = ""; + poweredBy.className = "olLayerGooglePoweredBy gmnoprint"; + + } catch (e) { + throw(e); + } + // cache elements for use by any other google layers added to + // this same map + OpenLayers.Layer.Google.cache[this.map.id] = { + mapObject: mapObject, + termsOfUse: termsOfUse, + poweredBy: poweredBy, + count: 1 + }; + } + + this.mapObject = mapObject; + this.termsOfUse = termsOfUse; + this.poweredBy = poweredBy; + + // ensure this layer type is one of the mapObject types + if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(), + this.type) === -1) { + this.mapObject.addMapType(this.type); + } + + //since v 2.93 getDragObject is now available. + if(typeof mapObject.getDragObject == "function") { + this.dragObject = mapObject.getDragObject(); + } else { + this.dragPanMapObject = null; + } + + if(this.isBaseLayer === false) { + this.setGMapVisibility(this.div.style.display !== "none"); + } + + }, + + /** + * APIMethod: onMapResize + */ + onMapResize: function() { + // workaround for resizing of invisible or not yet fully loaded layers + // where GMap2.checkResize() does not work. We need to load the GMap + // for the old div size, then checkResize(), and then call + // layer.moveTo() to trigger GMap.setCenter() (which will finish + // the GMap initialization). + if(this.visibility && this.mapObject.isLoaded()) { + this.mapObject.checkResize(); + } else { + if(!this._resized) { + var layer = this; + var handle = GEvent.addListener(this.mapObject, "load", function() { + GEvent.removeListener(handle); + delete layer._resized; + layer.mapObject.checkResize(); + layer.moveTo(layer.map.getCenter(), layer.map.getZoom()); + }); + } + this._resized = true; + } + }, + + /** + * Method: setGMapVisibility + * Display the GMap container and associated elements. + * + * Parameters: + * visible - {Boolean} Display the GMap elements. + */ + setGMapVisibility: function(visible) { + var cache = OpenLayers.Layer.Google.cache[this.map.id]; + if (cache) { + var container = this.mapObject.getContainer(); + if (visible === true) { + this.mapObject.setMapType(this.type); + container.style.display = ""; + this.termsOfUse.style.left = ""; + this.termsOfUse.style.display = ""; + this.poweredBy.style.display = ""; + cache.displayed = this.id; + } else { + if (cache.displayed === this.id) { + delete cache.displayed; + } + if (!cache.displayed) { + container.style.display = "none"; + this.termsOfUse.style.display = "none"; + // move ToU far to the left in addition to setting display + // to "none", because at the end of the GMap2 load + // sequence, display: none will be unset and ToU would be + // visible after loading a map with a google layer that is + // initially hidden. + this.termsOfUse.style.left = "-9999px"; + this.poweredBy.style.display = "none"; + } + } + } + }, + + /** + * Method: getMapContainer + * + * Returns: + * {DOMElement} the GMap container's div + */ + getMapContainer: function() { + return this.mapObject.getContainer(); + }, + + // + // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds + // + + /** + * APIMethod: getMapObjectBoundsFromOLBounds + * + * Parameters: + * olBounds - {} + * + * Returns: + * {Object} A MapObject Bounds, translated from olBounds + * Returns null if null value is passed in + */ + getMapObjectBoundsFromOLBounds: function(olBounds) { + var moBounds = null; + if (olBounds != null) { + var sw = this.sphericalMercator ? + this.inverseMercator(olBounds.bottom, olBounds.left) : + new OpenLayers.LonLat(olBounds.bottom, olBounds.left); + var ne = this.sphericalMercator ? + this.inverseMercator(olBounds.top, olBounds.right) : + new OpenLayers.LonLat(olBounds.top, olBounds.right); + moBounds = new GLatLngBounds(new GLatLng(sw.lat, sw.lon), + new GLatLng(ne.lat, ne.lon)); + } + return moBounds; + }, + + + /************************************ + * * + * MapObject Interface Controls * + * * + ************************************/ + + + // Get&Set Center, Zoom + + /** + * APIMethod: setMapObjectCenter + * Set the mapObject to the specified center and zoom + * + * Parameters: + * center - {Object} MapObject LonLat format + * zoom - {int} MapObject zoom format + */ + setMapObjectCenter: function(center, zoom) { + this.mapObject.setCenter(center, zoom); + }, + + /** + * APIMethod: dragPanMapObject + * + * Parameters: + * dX - {Integer} + * dY - {Integer} + */ + dragPanMapObject: function(dX, dY) { + this.dragObject.moveBy(new GSize(-dX, dY)); + }, + + + // LonLat - Pixel Translation + + /** + * APIMethod: getMapObjectLonLatFromMapObjectPixel * * Parameters: * moPixel - {Object} MapObject Pixel format @@ -644,37 +754,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( // LonLat - /** - * APIMethod: getLongitudeFromMapObjectLonLat - * - * Parameters: - * moLonLat - {Object} MapObject LonLat format - * - * Returns: - * {Float} Longitude of the given MapObject LonLat - */ - getLongitudeFromMapObjectLonLat: function(moLonLat) { - return this.sphericalMercator ? - this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon : - moLonLat.lng(); - }, - - /** - * APIMethod: getLatitudeFromMapObjectLonLat - * - * Parameters: - * moLonLat - {Object} MapObject LonLat format - * - * Returns: - * {Float} Latitude of the given MapObject LonLat - */ - getLatitudeFromMapObjectLonLat: function(moLonLat) { - var lat = this.sphericalMercator ? - this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat : - moLonLat.lat(); - return lat; - }, - /** * APIMethod: getMapObjectLonLatFromLonLat * @@ -698,32 +777,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( // Pixel - /** - * APIMethod: getXFromMapObjectPixel - * - * Parameters: - * moPixel - {Object} MapObject Pixel format - * - * Returns: - * {Integer} X value of the MapObject Pixel - */ - getXFromMapObjectPixel: function(moPixel) { - return moPixel.x; - }, - - /** - * APIMethod: getYFromMapObjectPixel - * - * Parameters: - * moPixel - {Object} MapObject Pixel format - * - * Returns: - * {Integer} Y value of the MapObject Pixel - */ - getYFromMapObjectPixel: function(moPixel) { - return moPixel.y; - }, - /** * APIMethod: getMapObjectPixelFromXY * @@ -736,13 +789,6 @@ OpenLayers.Layer.Google = OpenLayers.Class( */ getMapObjectPixelFromXY: function(x, y) { return new GPoint(x, y); - }, - - CLASS_NAME: "OpenLayers.Layer.Google" -}); - -/** - * Property: OpenLayers.Layer.Google.cache - * {Object} Cache for elements that should only be created once per map. - */ -OpenLayers.Layer.Google.cache = {}; + } + +}; diff --git a/lib/OpenLayers/Layer/Google/v3.js b/lib/OpenLayers/Layer/Google/v3.js new file mode 100644 index 00000000..fa9d64f9 --- /dev/null +++ b/lib/OpenLayers/Layer/Google/v3.js @@ -0,0 +1,418 @@ +/* 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/Layer/Google.js + */ + +/** + * Constant: OpenLayers.Layer.Google.v3 + * + * Mixin providing functionality specific to the Google Maps API v3. Note that + * this layer configures the google.maps.map object with the "disableDefaultUI" + * option set to true. Using UI controls that the Google Maps API provides is + * not supported by the OpenLayers API. + */ +OpenLayers.Layer.Google.v3 = { + + /** + * Constant: DEFAULTS + * {Object} It is not recommended to change the properties set here. Note + * that Google.v3 layers only work when sphericalMercator is set to true. + * + * (code) + * { + * maxExtent: new OpenLayers.Bounds( + * -128 * 156543.0339, + * -128 * 156543.0339, + * 128 * 156543.0339, + * 128 * 156543.0339 + * ), + * sphericalMercator: true, + * maxResolution: 156543.0339, + * units: "m", + * projection: "EPSG:900913" + * } + * (end) + */ + DEFAULTS: { + maxExtent: new OpenLayers.Bounds( + -128 * 156543.0339, + -128 * 156543.0339, + 128 * 156543.0339, + 128 * 156543.0339 + ), + sphericalMercator: true, + maxResolution: 156543.0339, + units: "m", + projection: "EPSG:900913" + }, + + /** + * Method: loadMapObject + * Load the GMap and register appropriate event listeners. If we can't + * load GMap2, then display a warning message. + */ + loadMapObject:function() { + if (!this.type) { + this.type = google.maps.MapTypeId.ROADMAP; + } + var mapObject; + var cache = OpenLayers.Layer.Google.cache[this.map.id]; + if (cache) { + // there are already Google layers added to this map + mapObject = cache.mapObject; + // increment the layer count + ++cache.count; + } else { + // this is the first Google layer for this map + + var container = this.map.viewPortDiv; + var div = document.createElement("div"); + div.id = this.map.id + "_GMapContainer"; + div.style.position = "absolute"; + div.style.width = "100%"; + div.style.height = "100%"; + container.appendChild(div); + + // create GMap and shuffle elements + var center = this.map.getCenter(); + mapObject = new google.maps.Map(div, { + center: center ? + new google.maps.LatLng(center.lat, center.lon) : + new google.maps.LatLng(0, 0), + zoom: this.map.getZoom() || 0, + mapTypeId: this.type, + disableDefaultUI: true, + keyboardShortcuts: false, + draggable: false, + disableDoubleClickZoom: true, + scrollwheel: false + }); + + // cache elements for use by any other google layers added to + // this same map + cache = { + mapObject: mapObject, + count: 1 + }; + OpenLayers.Layer.Google.cache[this.map.id] = cache; + this.repositionListener = google.maps.event.addListenerOnce( + mapObject, + "center_changed", + OpenLayers.Function.bind(this.repositionMapElements, this) + ); + } + this.mapObject = mapObject; + this.setGMapVisibility(this.visibility); + }, + + /** + * Method: repositionMapElements + * + * Waits until powered by and terms of use elements are available and then + * moves them so they are clickable. + */ + repositionMapElements: function() { + + // This is the first time any Google layer in this mapObject has been + // made visible. The mapObject needs to know the container size. + google.maps.event.trigger(this.mapObject, "resize"); + + var div = this.mapObject.getDiv().firstChild; + if (!div || div.childNodes.length < 3) { + this.repositionTimer = window.setTimeout( + OpenLayers.Function.bind(this.repositionMapElements, this), + 250 + ); + return false; + } + + var cache = OpenLayers.Layer.Google.cache[this.map.id]; + var container = this.map.viewPortDiv; + + // move the ToS and branding stuff up to the container div + var termsOfUse = div.lastChild; + container.appendChild(termsOfUse); + termsOfUse.style.zIndex = "1100"; + termsOfUse.style.bottom = ""; + termsOfUse.className = "olLayerGoogleCopyright olLayerGoogleV3"; + termsOfUse.style.display = ""; + cache.termsOfUse = termsOfUse; + + var poweredBy = div.lastChild; + container.appendChild(poweredBy); + poweredBy.style.zIndex = "1100"; + poweredBy.style.bottom = ""; + poweredBy.className = "olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint"; + poweredBy.style.display = ""; + cache.poweredBy = poweredBy; + + this.setGMapVisibility(this.visibility); + + }, + + /** + * APIMethod: onMapResize + */ + onMapResize: function() { + if (this.visibility) { + google.maps.event.trigger(this.mapObject, "resize"); + } else { + if (!this._resized) { + var layer = this; + google.maps.event.addListenerOnce(this.mapObject, "tilesloaded", function() { + delete layer._resized; + google.maps.event.trigger(layer.mapObject, "resize"); + layer.moveTo(layer.map.getCenter(), layer.map.getZoom()); + }); + } + this._resized = true; + } + }, + + /** + * Method: setGMapVisibility + * Display the GMap container and associated elements. + * + * Parameters: + * visible - {Boolean} Display the GMap elements. + */ + setGMapVisibility: function(visible) { + var cache = OpenLayers.Layer.Google.cache[this.map.id]; + if (cache) { + var type = this.type; + var layers = this.map.layers; + var layer; + for (var i=layers.length-1; i>=0; --i) { + layer = layers[i]; + if (layer instanceof OpenLayers.Layer.Google && + layer.visibility === true && layer.inRange === true) { + type = layer.type; + visible = true; + break; + } + } + var container = this.mapObject.getDiv(); + if (visible === true) { + this.mapObject.setMapTypeId(type); + container.style.left = ""; + if (cache.termsOfUse && cache.termsOfUse.style) { + cache.termsOfUse.style.left = ""; + cache.termsOfUse.style.display = ""; + cache.poweredBy.style.display = ""; + } + cache.displayed = this.id; + } else { + delete cache.displayed; + container.style.left = "-9999px"; + if (cache.termsOfUse && cache.termsOfUse.style) { + cache.termsOfUse.style.display = "none"; + // move ToU far to the left in addition to setting + // display to "none", because at the end of the GMap + // load sequence, display: none will be unset and ToU + // would be visible after loading a map with a google + // layer that is initially hidden. + cache.termsOfUse.style.left = "-9999px"; + cache.poweredBy.style.display = "none"; + } + } + } + }, + + /** + * Method: getMapContainer + * + * Returns: + * {DOMElement} the GMap container's div + */ + getMapContainer: function() { + return this.mapObject.getDiv(); + }, + + // + // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds + // + + /** + * APIMethod: getMapObjectBoundsFromOLBounds + * + * Parameters: + * olBounds - {} + * + * Returns: + * {Object} A MapObject Bounds, translated from olBounds + * Returns null if null value is passed in + */ + getMapObjectBoundsFromOLBounds: function(olBounds) { + var moBounds = null; + if (olBounds != null) { + var sw = this.sphericalMercator ? + this.inverseMercator(olBounds.bottom, olBounds.left) : + new OpenLayers.LonLat(olBounds.bottom, olBounds.left); + var ne = this.sphericalMercator ? + this.inverseMercator(olBounds.top, olBounds.right) : + new OpenLayers.LonLat(olBounds.top, olBounds.right); + moBounds = new google.maps.LatLngBounds( + new google.maps.LatLng(sw.lat, sw.lon), + new google.maps.LatLng(ne.lat, ne.lon) + ); + } + return moBounds; + }, + + + /************************************ + * * + * MapObject Interface Controls * + * * + ************************************/ + + + // LonLat - Pixel Translation + + /** + * APIMethod: getMapObjectLonLatFromMapObjectPixel + * + * Parameters: + * moPixel - {Object} MapObject Pixel format + * + * Returns: + * {Object} MapObject LonLat translated from MapObject Pixel + */ + getMapObjectLonLatFromMapObjectPixel: function(moPixel) { + var size = this.map.getSize(); + var lon = this.getLongitudeFromMapObjectLonLat(this.mapObject.center); + var lat = this.getLatitudeFromMapObjectLonLat(this.mapObject.center); + var res = this.map.getResolution(); + + var delta_x = moPixel.x - (size.w / 2); + var delta_y = moPixel.y - (size.h / 2); + + var lonlat = new OpenLayers.LonLat( + lon + delta_x * res, + lat - delta_y * res + ); + + if (this.wrapDateLine) { + lonlat = lonlat.wrapDateLine(this.maxExtent); + } + return this.getMapObjectLonLatFromLonLat(lonlat.lon, lonlat.lat); + }, + + /** + * APIMethod: getMapObjectPixelFromMapObjectLonLat + * + * Parameters: + * moLonLat - {Object} MapObject LonLat format + * + * Returns: + * {Object} MapObject Pixel transtlated from MapObject LonLat + */ + getMapObjectPixelFromMapObjectLonLat: function(moLonLat) { + var lon = this.getLongitudeFromMapObjectLonLat(moLonLat); + var lat = this.getLatitudeFromMapObjectLonLat(moLonLat); + var res = this.map.getResolution(); + var extent = this.map.getExtent(); + var px = new OpenLayers.Pixel( + (1/res * (lon - extent.left)), + (1/res * (extent.top - lat)) + ); + return this.getMapObjectPixelFromXY(px.x, px.y); + }, + + + /** + * APIMethod: setMapObjectCenter + * Set the mapObject to the specified center and zoom + * + * Parameters: + * center - {Object} MapObject LonLat format + * zoom - {int} MapObject zoom format + */ + setMapObjectCenter: function(center, zoom) { + this.mapObject.setOptions({ + center: center, + zoom: zoom + }); + }, + + + // Bounds + + /** + * APIMethod: getMapObjectZoomFromMapObjectBounds + * + * Parameters: + * moBounds - {Object} MapObject Bounds format + * + * Returns: + * {Object} MapObject Zoom for specified MapObject Bounds + */ + getMapObjectZoomFromMapObjectBounds: function(moBounds) { + return this.mapObject.getBoundsZoomLevel(moBounds); + }, + + /************************************ + * * + * MapObject Primitives * + * * + ************************************/ + + + // LonLat + + /** + * APIMethod: getMapObjectLonLatFromLonLat + * + * Parameters: + * lon - {Float} + * lat - {Float} + * + * Returns: + * {Object} MapObject LonLat built from lon and lat params + */ + getMapObjectLonLatFromLonLat: function(lon, lat) { + var gLatLng; + if(this.sphericalMercator) { + var lonlat = this.inverseMercator(lon, lat); + gLatLng = new google.maps.LatLng(lonlat.lat, lonlat.lon); + } else { + gLatLng = new google.maps.LatLng(lat, lon); + } + return gLatLng; + }, + + // Pixel + + /** + * APIMethod: getMapObjectPixelFromXY + * + * Parameters: + * x - {Integer} + * y - {Integer} + * + * Returns: + * {Object} MapObject Pixel from x and y parameters + */ + getMapObjectPixelFromXY: function(x, y) { + return new google.maps.Point(x, y); + }, + + /** + * APIMethod: destroy + * Clean up this layer. + */ + destroy: function() { + if (this.repositionListener) { + google.maps.event.removeListener(this.repositionListener); + } + if (this.repositionTimer) { + window.clearTimeout(this.repositionTimer); + } + OpenLayers.Layer.Google.prototype.destroy.apply(this, arguments); + } + +}; diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 2799bcea..c44c8ef5 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -214,23 +214,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this, [size]); }, - /** - * Method: getGridBounds - * Deprecated. This function will be removed in 3.0. Please use - * getTilesBounds() instead. - * - * Returns: - * {} A Bounds object representing the bounds of all the - * currently loaded tiles (including those partially or not at all seen - * onscreen) - */ - getGridBounds: function() { - var msg = "The getGridBounds() function is deprecated. It will be " + - "removed in 3.0. Please use getTilesBounds() instead."; - OpenLayers.Console.warn(msg); - return this.getTilesBounds(); - }, - /** * APIMethod: getTilesBounds * Return the bounds of the tile grid. @@ -354,7 +337,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { var minCols = Math.ceil(viewSize.w/this.tileSize.w) + Math.max(1, 2 * this.buffer); - var extent = this.maxExtent; + var extent = this.getMaxExtent(); var resolution = this.map.getResolution(); var tileLayout = this.calculateGridLayout(bounds, extent, resolution); @@ -429,6 +412,18 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { //now actually draw the tiles this.spiralTileLoad(); }, + + /** + * Method: getMaxExtent + * Get this layer's maximum extent. (Implemented as a getter for + * potential specific implementations in sub-classes.) + * + * Returns: + * {OpenLayers.Bounds} + */ + getMaxExtent: function() { + return this.maxExtent; + }, /** * Method: spiralTileLoad diff --git a/lib/OpenLayers/Layer/MapGuide.js b/lib/OpenLayers/Layer/MapGuide.js index 3588c98b..ac318a44 100644 --- a/lib/OpenLayers/Layer/MapGuide.js +++ b/lib/OpenLayers/Layer/MapGuide.js @@ -353,7 +353,7 @@ OpenLayers.Layer.MapGuide = OpenLayers.Class(OpenLayers.Layer.Grid, { allParams = OpenLayers.Util.extend(allParams, newParams); // ignore parameters that are already in the url search string var urlParams = OpenLayers.Util.upperCaseObject( - OpenLayers.Util.getArgs(url)); + OpenLayers.Util.getParameters(url)); for(var key in allParams) { if(key.toUpperCase() in urlParams) { delete allParams[key]; diff --git a/lib/OpenLayers/Layer/MapServer/Untiled.js b/lib/OpenLayers/Layer/MapServer/Untiled.js deleted file mode 100644 index d8b2cc0f..00000000 --- a/lib/OpenLayers/Layer/MapServer/Untiled.js +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright 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/Layer/MapServer.js - * @requires OpenLayers/Console.js - */ - -/** - * Class: OpenLayers.Layer.MapServer.Untiled - * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.MapServer - * and pass the option 'singleTile' as true. - * - * Inherits from: - * - - */ -OpenLayers.Layer.MapServer.Untiled = OpenLayers.Class(OpenLayers.Layer.MapServer, { - - /** - * APIProperty: singleTile - * {singleTile} Always true for untiled. - */ - singleTile: true, - - /** - * Constructor: OpenLayers.Layer.MapServer.Untiled - * - * Parameters: - * name - {String} - * url - {String} - * params - {Object} - * options - {Object} - */ - initialize: function(name, url, params, options) { - OpenLayers.Layer.MapServer.prototype.initialize.apply(this, arguments); - - var msg = "The OpenLayers.Layer.MapServer.Untiled class is deprecated and " + - "will be removed in 3.0. Instead, you should use the " + - "normal OpenLayers.Layer.MapServer class, passing it the option " + - "'singleTile' as true."; - OpenLayers.Console.warn(msg); - }, - - /** - * Method: clone - * Create a clone of this layer - * - * Returns: - * {} An exact clone of this layer - */ - clone: function (obj) { - - if (obj == null) { - obj = new OpenLayers.Layer.MapServer.Untiled(this.name, - this.url, - this.params, - this.getOptions()); - } - - //get all additions from superclasses - obj = OpenLayers.Layer.MapServer.prototype.clone.apply(this, [obj]); - - // copy/set any non-init, non-simple values here - - return obj; - }, - - CLASS_NAME: "OpenLayers.Layer.MapServer.Untiled" -}); diff --git a/lib/OpenLayers/Layer/SphericalMercator.js b/lib/OpenLayers/Layer/SphericalMercator.js index 730d8305..fddf11d3 100644 --- a/lib/OpenLayers/Layer/SphericalMercator.js +++ b/lib/OpenLayers/Layer/SphericalMercator.js @@ -50,6 +50,38 @@ OpenLayers.Layer.SphericalMercator = { return extent; }, + /** + * Method: getLonLatFromViewPortPx + * Get a map location from a pixel location + * + * Parameters: + * viewPortPx - {} + * + * Returns: + * {} An OpenLayers.LonLat which is the passed-in view + * port OpenLayers.Pixel, translated into lon/lat by map lib + * If the map lib is not loaded or not centered, returns null + */ + getLonLatFromViewPortPx: function (viewPortPx) { + return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this, arguments); + }, + + /** + * Method: getViewPortPxFromLonLat + * Get a pixel location from a map location + * + * Parameters: + * lonlat - {} + * + * Returns: + * {} An OpenLayers.Pixel which is the passed-in + * OpenLayers.LonLat, translated into view port pixels by map lib + * If map lib is not loaded or not centered, returns null + */ + getViewPortPxFromLonLat: function (lonlat) { + return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this, arguments); + }, + /** * Method: initMercatorParameters * Set up the mercator parameters on the layer: resolutions, diff --git a/lib/OpenLayers/Layer/TMS.js b/lib/OpenLayers/Layer/TMS.js index 6d4d1488..089d9e48 100644 --- a/lib/OpenLayers/Layer/TMS.js +++ b/lib/OpenLayers/Layer/TMS.js @@ -41,6 +41,20 @@ OpenLayers.Layer.TMS = OpenLayers.Class(OpenLayers.Layer.Grid, { */ serverResolutions: null, + /** + * APIProperty: zoomOffset + * {Number} If your cache has more zoom levels than you want to provide + * access to with this layer, supply a zoomOffset. This zoom offset + * is added to the current map zoom level to determine the level + * for a requested tile. For example, if you supply a zoomOffset + * of 3, when the map is at the zoom 0, tiles will be requested from + * level 3 of your cache. Default is 0 (assumes cache level and map + * zoom are equivalent). Using is an alternative to + * setting if you only want to expose a subset + * of the server resolutions. + */ + zoomOffset: 0, + /** * Constructor: OpenLayers.Layer.TMS * @@ -107,7 +121,7 @@ OpenLayers.Layer.TMS = OpenLayers.Class(OpenLayers.Layer.Grid, { var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h)); var z = this.serverResolutions != null ? OpenLayers.Util.indexOf(this.serverResolutions, res) : - this.map.getZoom(); + this.map.getZoom() + this.zoomOffset; var path = this.serviceVersion + "/" + this.layername + "/" + z + "/" + x + "/" + y + "." + this.type; var url = this.url; if (url instanceof Array) { diff --git a/lib/OpenLayers/Layer/Text.js b/lib/OpenLayers/Layer/Text.js index 7b79890c..7a9245e6 100644 --- a/lib/OpenLayers/Layer/Text.js +++ b/lib/OpenLayers/Layer/Text.js @@ -209,12 +209,12 @@ OpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, { if ((feature.attributes.title != null) && (feature.attributes.description != null)) { - data['popupContentHTML'] = + data.popupContentHTML = '

'+feature.attributes.title+'

' + '

'+feature.attributes.description+'

'; } - data['overflow'] = feature.attributes.overflow || "auto"; + data.overflow = feature.attributes.overflow || "auto"; var markerFeature = new OpenLayers.Feature(this, location, data); this.features.push(markerFeature); diff --git a/lib/OpenLayers/Layer/Vector.js b/lib/OpenLayers/Layer/Vector.js index 8a3d826d..7bcc1297 100644 --- a/lib/OpenLayers/Layer/Vector.js +++ b/lib/OpenLayers/Layer/Vector.js @@ -54,6 +54,9 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { * beforefeatureremoved - Triggered before a feature is removed. Listeners * will receive an object with a *feature* property referencing the * feature to be removed. + * beforefeaturesremoved - Triggered before multiple features are removed. + * Listeners will receive an object with a *features* property + * referencing the features to be removed. * featureremoved - Triggerd after a feature is removed. The event * object passed to listeners will have a *feature* property with a * reference to the removed feature. @@ -97,8 +100,8 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { * for a new set of features. */ EVENT_TYPES: ["beforefeatureadded", "beforefeaturesadded", - "featureadded", "featuresadded", - "beforefeatureremoved", "featureremoved", "featuresremoved", + "featureadded", "featuresadded", "beforefeatureremoved", + "beforefeaturesremoved", "featureremoved", "featuresremoved", "beforefeatureselected", "featureselected", "featureunselected", "beforefeaturemodified", "featuremodified", "afterfeaturemodified", "vertexmodified", "sketchstarted", "sketchmodified", @@ -613,14 +616,23 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { if(!features || features.length === 0) { return; } + if (features === this.features) { + return this.removeAllFeatures(options); + } if (!(features instanceof Array)) { features = [features]; } - if (features === this.features || features === this.selectedFeatures) { + if (features === this.selectedFeatures) { features = features.slice(); } var notify = !options || !options.silent; + + if (notify) { + this.events.triggerEvent( + "beforefeaturesremoved", {features: features} + ); + } for (var i = features.length - 1; i >= 0; i--) { // We remain locked so long as we're not at 0 @@ -671,6 +683,49 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { this.events.triggerEvent("featuresremoved", {features: features}); } }, + + /** + * APIMethod: removeAllFeatures + * Remove all features from the layer. + * + * Parameters: + * options - {Object} Optional properties for changing behavior of the + * removal. + * + * Valid options: + * silent - {Boolean} Supress event triggering. Default is false. + */ + removeAllFeatures: function(options) { + var notify = !options || !options.silent; + var features = this.features; + if (notify) { + this.events.triggerEvent( + "beforefeaturesremoved", {features: features} + ); + } + var feature; + for (var i = features.length-1; i >= 0; i--) { + feature = features[i]; + if (notify) { + this.events.triggerEvent("beforefeatureremoved", { + feature: feature + }); + } + feature.layer = null; + if (notify) { + this.events.triggerEvent("featureremoved", { + feature: feature + }); + } + } + this.renderer.clear(); + this.features = []; + this.unrenderedFeatures = {}; + this.selectedFeatures = []; + if (notify) { + this.events.triggerEvent("featuresremoved", {features: features}); + } + }, /** * APIMethod: destroyFeatures @@ -768,30 +823,61 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { var featureId = this.renderer.getFeatureIdFromEvent(evt); return this.getFeatureById(featureId); }, - + /** - * APIMethod: getFeatureById - * Given a feature id, return the feature if it exists in the features array + * APIMethod: getFeatureBy + * Given a property value, return the feature if it exists in the features array * * Parameters: - * featureId - {String} + * property - {String} + * value - {String} * * Returns: * {} A feature corresponding to the given - * featureId + * property value or null if there is no such feature. */ - getFeatureById: function(featureId) { + getFeatureBy: function(property, value) { //TBD - would it be more efficient to use a hash for this.features? var feature = null; for(var i=0, len=this.features.length; i} A feature corresponding to the given + * featureId or null if there is no such feature. + */ + getFeatureById: function(featureId) { + return this.getFeatureBy('id', featureId); + }, + + /** + * APIMethod: getFeatureByFid + * Given a feature fid, return the feature if it exists in the features array + * + * Parameters: + * featureFid - {String} + * + * Returns: + * {} A feature corresponding to the given + * featureFid or null if there is no such feature. + */ + getFeatureByFid: function(featureFid) { + return this.getFeatureBy('fid', featureFid); + }, + /** * Unselect the selected features * i.e. clears the featureSelection array diff --git a/lib/OpenLayers/Layer/VirtualEarth.js b/lib/OpenLayers/Layer/VirtualEarth.js index ebccc68a..c4a63e0f 100644 --- a/lib/OpenLayers/Layer/VirtualEarth.js +++ b/lib/OpenLayers/Layer/VirtualEarth.js @@ -65,6 +65,14 @@ OpenLayers.Layer.VirtualEarth = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will diff --git a/lib/OpenLayers/Layer/WFS.js b/lib/OpenLayers/Layer/WFS.js deleted file mode 100644 index 1f029ab8..00000000 --- a/lib/OpenLayers/Layer/WFS.js +++ /dev/null @@ -1,608 +0,0 @@ -/* 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/Tile/WFS.js - * @requires OpenLayers/Layer/Vector.js - * @requires OpenLayers/Layer/Markers.js - * @requires OpenLayers/Console.js - */ - -/** - * Class: OpenLayers.Layer.WFS - * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.Vector - * with a Protocol.WFS and one or more Strategies. - * - * Inherits from: - * - - * - - */ -OpenLayers.Layer.WFS = OpenLayers.Class( - OpenLayers.Layer.Vector, OpenLayers.Layer.Markers, { - - /** - * APIProperty: isBaseLayer - * {Boolean} WFS layer is not a base layer by default. - */ - isBaseLayer: false, - - /** - * Property: tile - * {} - */ - tile: null, - - /** - * APIProperty: ratio - * {Float} The ratio property determines the size of the serverside query - * relative to the map viewport size. By default, we load an area twice - * as big as the map, to allow for panning without immediately reload. - * Setting this to 1 will cause the area of the WFS request to match - * the map area exactly. It is recommended to set this to some number - * at least slightly larger than 1, otherwise accidental clicks can - * cause a data reload, by moving the map only 1 pixel. - */ - ratio: 2, - - /** - * Property: DEFAULT_PARAMS - * {Object} Hashtable of default key/value parameters - */ - DEFAULT_PARAMS: { service: "WFS", - version: "1.0.0", - request: "GetFeature" - }, - - /** - * APIProperty: featureClass - * {} If featureClass is defined, an old-style markers - * based WFS layer is created instead of a new-style vector layer. If - * sent, this should be a subclass of OpenLayers.Feature - */ - featureClass: null, - - /** - * APIProperty: format - * {} The format you want the data to be parsed with. - * Must be passed in the constructor. Should be a class, not an instance. - * This option can only be used if no featureClass is passed / vectorMode - * is false: if a featureClass is passed, then this parameter is ignored. - */ - format: null, - - /** - * Property: formatObject - * {} Internally created/managed format object, used by - * the Tile to parse data. - */ - formatObject: null, - - /** - * APIProperty: formatOptions - * {Object} Hash of options which should be passed to the format when it is - * created. Must be passed in the constructor. - */ - formatOptions: null, - - /** - * Property: vectorMode - * {Boolean} Should be calculated automatically. Determines whether the - * layer is in vector mode or marker mode. - */ - vectorMode: true, - - /** - * APIProperty: encodeBBOX - * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no', - * but some services want it that way. Default false. - */ - encodeBBOX: false, - - /** - * APIProperty: extractAttributes - * {Boolean} Should the WFS layer parse attributes from the retrieved - * GML? Defaults to false. If enabled, parsing is slower, but - * attributes are available in the attributes property of - * layer features. - */ - extractAttributes: false, - - /** - * Constructor: OpenLayers.Layer.WFS - * - * Parameters: - * name - {String} - * url - {String} - * params - {Object} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, url, params, options) { - if (options == undefined) { options = {}; } - - if (options.featureClass || - !OpenLayers.Layer.Vector || - !OpenLayers.Feature.Vector) { - this.vectorMode = false; - } - - // Uppercase params - params = OpenLayers.Util.upperCaseObject(params); - - // Turn off error reporting, browsers like Safari may work - // depending on the setup, and we don't want an unneccesary alert. - OpenLayers.Util.extend(options, {'reportError': false}); - var newArguments = []; - newArguments.push(name, options); - OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments); - if (!this.renderer || !this.vectorMode) { - this.vectorMode = false; - if (!options.featureClass) { - options.featureClass = OpenLayers.Feature.WFS; - } - OpenLayers.Layer.Markers.prototype.initialize.apply(this, - newArguments); - } - - if (this.params && this.params.typename && !this.options.typename) { - this.options.typename = this.params.typename; - } - - if (!this.options.geometry_column) { - this.options.geometry_column = "the_geom"; - } - - this.params = OpenLayers.Util.applyDefaults( - params, - OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS) - ); - this.url = url; - }, - - - /** - * APIMethod: destroy - */ - destroy: function() { - if (this.vectorMode) { - OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments); - } else { - OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments); - } - if (this.tile) { - this.tile.destroy(); - } - this.tile = null; - - this.ratio = null; - this.featureClass = null; - this.format = null; - - if (this.formatObject && this.formatObject.destroy) { - this.formatObject.destroy(); - } - this.formatObject = null; - - this.formatOptions = null; - this.vectorMode = null; - this.encodeBBOX = null; - this.extractAttributes = null; - }, - - /** - * Method: setMap - * - * Parameters: - * map - {} - */ - setMap: function(map) { - if (this.vectorMode) { - OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments); - - var options = { - 'extractAttributes': this.extractAttributes - }; - - OpenLayers.Util.extend(options, this.formatOptions); - if (this.map && !this.projection.equals(this.map.getProjectionObject())) { - options.externalProjection = this.projection; - options.internalProjection = this.map.getProjectionObject(); - } - - this.formatObject = this.format ? new this.format(options) : new OpenLayers.Format.GML(options); - } else { - OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments); - } - }, - - /** - * Method: moveTo - * - * Parameters: - * bounds - {} - * zoomChanged - {Boolean} - * dragging - {Boolean} - */ - moveTo:function(bounds, zoomChanged, dragging) { - if (this.vectorMode) { - OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments); - } else { - OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments); - } - - // don't load wfs features while dragging, wait for drag end - if (dragging) { - // TBD try to hide the vector layer while dragging - // this.setVisibility(false); - // this will probably help for panning performances - return false; - } - - if ( zoomChanged ) { - if (this.vectorMode) { - this.renderer.clear(); - } - } - - //DEPRECATED - REMOVE IN 3.0 - // don't load data if current zoom level doesn't match - if (this.options.minZoomLevel) { - OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError')); - - if (this.map.getZoom() < this.options.minZoomLevel) { - return null; - } - } - - if (bounds == null) { - bounds = this.map.getExtent(); - } - - var firstRendering = (this.tile == null); - - //does the new bounds to which we need to move fall outside of the - // current tile's bounds? - var outOfBounds = (!firstRendering && - !this.tile.bounds.containsBounds(bounds)); - - if (zoomChanged || firstRendering || (!dragging && outOfBounds)) { - //determine new tile bounds - var center = bounds.getCenterLonLat(); - var tileWidth = bounds.getWidth() * this.ratio; - var tileHeight = bounds.getHeight() * this.ratio; - var tileBounds = - new OpenLayers.Bounds(center.lon - (tileWidth / 2), - center.lat - (tileHeight / 2), - center.lon + (tileWidth / 2), - center.lat + (tileHeight / 2)); - - //determine new tile size - var tileSize = this.map.getSize(); - tileSize.w = tileSize.w * this.ratio; - tileSize.h = tileSize.h * this.ratio; - - //determine new position (upper left corner of new bounds) - var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top); - var pos = this.map.getLayerPxFromLonLat(ul); - - //formulate request url string - var url = this.getFullRequestString(); - - var params = null; - - // Cant combine "filter" and "BBOX". This is a cheap hack to help - // people out who can't migrate to the WFS protocol immediately. - var filter = this.params.filter || this.params.FILTER; - if (filter) { - params = {FILTER: filter}; - } - else { - params = {BBOX: this.encodeBBOX ? tileBounds.toBBOX() - : tileBounds.toArray()}; - } - - if (this.map && !this.projection.equals(this.map.getProjectionObject())) { - var projectedBounds = tileBounds.clone(); - projectedBounds.transform(this.map.getProjectionObject(), - this.projection); - if (!filter){ - params.BBOX = this.encodeBBOX ? projectedBounds.toBBOX() - : projectedBounds.toArray(); - } - } - - url += "&" + OpenLayers.Util.getParameterString(params); - - if (!this.tile) { - this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds, - url, tileSize); - this.addTileMonitoringHooks(this.tile); - this.tile.draw(); - } else { - if (this.vectorMode) { - this.destroyFeatures(); - this.renderer.clear(); - } else { - this.clearMarkers(); - } - this.removeTileMonitoringHooks(this.tile); - this.tile.destroy(); - - this.tile = null; - this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds, - url, tileSize); - this.addTileMonitoringHooks(this.tile); - this.tile.draw(); - } - } - }, - - /** - * Method: addTileMonitoringHooks - * This function takes a tile as input and adds the appropriate hooks to - * the tile so that the layer can keep track of the loading tile - * (making sure to check that the tile is always the layer's current - * tile before taking any action). - * - * Parameters: - * tile - {} - */ - addTileMonitoringHooks: function(tile) { - tile.onLoadStart = function() { - //if this is the the layer's current tile, then trigger - // a 'loadstart' - if (this == this.layer.tile) { - this.layer.events.triggerEvent("loadstart"); - } - }; - tile.events.register("loadstart", tile, tile.onLoadStart); - - tile.onLoadEnd = function() { - //if this is the the layer's current tile, then trigger - // a 'tileloaded' and 'loadend' - if (this == this.layer.tile) { - this.layer.events.triggerEvent("tileloaded"); - this.layer.events.triggerEvent("loadend"); - } - }; - tile.events.register("loadend", tile, tile.onLoadEnd); - tile.events.register("unload", tile, tile.onLoadEnd); - }, - - /** - * Method: removeTileMonitoringHooks - * This function takes a tile as input and removes the tile hooks - * that were added in addTileMonitoringHooks() - * - * Parameters: - * tile - {} - */ - removeTileMonitoringHooks: function(tile) { - tile.unload(); - tile.events.un({ - "loadstart": tile.onLoadStart, - "loadend": tile.onLoadEnd, - "unload": tile.onLoadEnd, - scope: tile - }); - }, - - /** - * Method: onMapResize - * Call the onMapResize method of the appropriate parent class. - */ - onMapResize: function() { - if(this.vectorMode) { - OpenLayers.Layer.Vector.prototype.onMapResize.apply(this, - arguments); - } else { - OpenLayers.Layer.Markers.prototype.onMapResize.apply(this, - arguments); - } - }, - - /** - * Method: display - * Call the display method of the appropriate parent class. - */ - display: function() { - if(this.vectorMode) { - OpenLayers.Layer.Vector.prototype.display.apply(this, - arguments); - } else { - OpenLayers.Layer.Markers.prototype.display.apply(this, - arguments); - } - }, - - /** - * APIMethod: mergeNewParams - * Modify parameters for the layer and redraw. - * - * Parameters: - * newParams - {Object} - */ - mergeNewParams:function(newParams) { - var upperParams = OpenLayers.Util.upperCaseObject(newParams); - var newArguments = [upperParams]; - return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this, - newArguments); - }, - - /** - * APIMethod: clone - * - * Parameters: - * obj - {Object} - * - * Returns: - * {} An exact clone of this OpenLayers.Layer.WFS - */ - clone: function (obj) { - - if (obj == null) { - obj = new OpenLayers.Layer.WFS(this.name, - this.url, - this.params, - this.getOptions()); - } - - //get all additions from superclasses - if (this.vectorMode) { - obj = OpenLayers.Layer.Vector.prototype.clone.apply(this, [obj]); - } else { - obj = OpenLayers.Layer.Markers.prototype.clone.apply(this, [obj]); - } - - // copy/set any non-init, non-simple values here - - return obj; - }, - - /** - * APIMethod: getFullRequestString - * combine the layer's url with its params and these newParams. - * - * Add the SRS parameter from 'projection' -- this is probably - * more eloquently done via a setProjection() method, but this - * works for now and always. - * - * Parameters: - * newParams - {Object} - * altUrl - {String} Use this as the url instead of the layer's url - */ - getFullRequestString:function(newParams, altUrl) { - var projectionCode = this.projection.getCode() || this.map.getProjection(); - this.params.SRS = (projectionCode == "none") ? null : projectionCode; - - return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply( - this, arguments); - }, - - /** - * APIMethod: commit - * Write out the data to a WFS server. - */ - commit: function() { - if (!this.writer) { - var options = {}; - if (this.map && !this.projection.equals(this.map.getProjectionObject())) { - options.externalProjection = this.projection; - options.internalProjection = this.map.getProjectionObject(); - } - - this.writer = new OpenLayers.Format.WFS(options,this); - } - - var data = this.writer.write(this.features); - - OpenLayers.Request.POST({ - url: this.url, - data: data, - success: this.commitSuccess, - failure: this.commitFailure, - scope: this - }); - }, - - /** - * Method: commitSuccess - * Called when the Ajax request returns a response - * - * Parameters: - * response - {XmlNode} from server - */ - commitSuccess: function(request) { - var response = request.responseText; - if (response.indexOf('SUCCESS') != -1) { - this.commitReport(OpenLayers.i18n("commitSuccess", {'response':response})); - - for(var i = 0; i < this.features.length; i++) { - this.features[i].state = null; - } - // TBD redraw the layer or reset the state of features - // foreach features: set state to null - } else if (response.indexOf('FAILED') != -1 || - response.indexOf('Exception') != -1) { - this.commitReport(OpenLayers.i18n("commitFailed", {'response':response})); - } - }, - - /** - * Method: commitFailure - * Called when the Ajax request fails - * - * Parameters: - * response - {XmlNode} from server - */ - commitFailure: function(request) {}, - - /** - * APIMethod: commitReport - * Called with a 'success' message if the commit succeeded, otherwise - * a failure message, and the full request text as a second parameter. - * Override this function to provide custom transaction reporting. - * - * string - {String} reporting string - * response - {String} full XML response - */ - commitReport: function(string, response) { - OpenLayers.Console.userError(string); - }, - - - /** - * APIMethod: refresh - * Refreshes all the features of the layer - */ - refresh: function() { - if (this.tile) { - if (this.vectorMode) { - this.renderer.clear(); - this.features.length = 0; - } else { - this.clearMarkers(); - this.markers.length = 0; - } - this.tile.draw(); - } - }, - - /** - * APIMethod: getDataExtent - * Calculates the max extent which includes all of the layer data. - * - * Returns: - * {} - */ - getDataExtent: function () { - var extent; - //get all additions from superclasses - if (this.vectorMode) { - extent = OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this); - } else { - extent = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this); - } - - return extent; - }, - - /** - * APIMethod: setOpacity - * Call the setOpacity method of the appropriate parent class to set the - * opacity. - * - * Parameter: - * opacity - {Float} - */ - setOpacity: function (opacity) { - if (this.vectorMode) { - OpenLayers.Layer.Vector.prototype.setOpacity.apply(this, [opacity]); - } else { - OpenLayers.Layer.Markers.prototype.setOpacity.apply(this, [opacity]); - } - }, - - CLASS_NAME: "OpenLayers.Layer.WFS" -}); diff --git a/lib/OpenLayers/Layer/WMS.js b/lib/OpenLayers/Layer/WMS.js index 80ce2223..ca1c2249 100644 --- a/lib/OpenLayers/Layer/WMS.js +++ b/lib/OpenLayers/Layer/WMS.js @@ -66,11 +66,11 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, { /** * Property: yx - * {Array} Array of strings with the EPSG codes for which the axis order - * is to be reversed (yx instead of xy, LatLon instead of LonLat). This - * is only relevant for WMS versions >= 1.3.0. + * {Object} Keys in this object are EPSG codes for which the axis order + * is to be reversed (yx instead of xy, LatLon instead of LonLat), with + * true as value. This is only relevant for WMS versions >= 1.3.0. */ - yx: ['EPSG:4326'], + yx: {'EPSG:4326': true}, /** * Constructor: OpenLayers.Layer.WMS @@ -95,6 +95,9 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, { var newArguments = []; //uppercase params params = OpenLayers.Util.upperCaseObject(params); + if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) { + params.EXCEPTIONS = "INIMAGE"; + } newArguments.push(name, url, params, options); OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments); OpenLayers.Util.applyDefaults( @@ -166,8 +169,7 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, { */ reverseAxisOrder: function() { return (parseFloat(this.params.VERSION) >= 1.3 && - OpenLayers.Util.indexOf(this.yx, - this.map.getProjectionObject().getCode()) !== -1) + !!this.yx[this.map.getProjectionObject().getCode()]); }, /** diff --git a/lib/OpenLayers/Layer/WMS/Untiled.js b/lib/OpenLayers/Layer/WMS/Untiled.js deleted file mode 100644 index f5c858e6..00000000 --- a/lib/OpenLayers/Layer/WMS/Untiled.js +++ /dev/null @@ -1,71 +0,0 @@ -/* 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/Layer/WMS.js - * @requires OpenLayers/Console.js - */ - -/** - * Class: OpenLayers.Layer.WMS.Untiled - * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.WMS and - * pass the option 'singleTile' as true. - * - * Inherits from: - * - - */ -OpenLayers.Layer.WMS.Untiled = OpenLayers.Class(OpenLayers.Layer.WMS, { - - /** - * APIProperty: singleTile - * {singleTile} Always true for untiled. - */ - singleTile: true, - - /** - * Constructor: OpenLayers.Layer.WMS.Untiled - * - * Parameters: - * name - {String} - * url - {String} - * params - {Object} - * options - {Object} - */ - initialize: function(name, url, params, options) { - OpenLayers.Layer.WMS.prototype.initialize.apply(this, arguments); - - var msg = "The OpenLayers.Layer.WMS.Untiled class is deprecated and " + - "will be removed in 3.0. Instead, you should use the " + - "normal OpenLayers.Layer.WMS class, passing it the option " + - "'singleTile' as true."; - OpenLayers.Console.warn(msg); - }, - - /** - * Method: clone - * Create a clone of this layer - * - * Returns: - * {} An exact clone of this layer - */ - clone: function (obj) { - - if (obj == null) { - obj = new OpenLayers.Layer.WMS.Untiled(this.name, - this.url, - this.params, - this.getOptions()); - } - - //get all additions from superclasses - obj = OpenLayers.Layer.WMS.prototype.clone.apply(this, [obj]); - - // copy/set any non-init, non-simple values here - - return obj; - }, - - CLASS_NAME: "OpenLayers.Layer.WMS.Untiled" -}); diff --git a/lib/OpenLayers/Layer/WMTS.js b/lib/OpenLayers/Layer/WMTS.js index 5431bc55..52397821 100644 --- a/lib/OpenLayers/Layer/WMTS.js +++ b/lib/OpenLayers/Layer/WMTS.js @@ -129,7 +129,26 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { * become part of the request path, with order determined by the * list. */ - params: null, + params: null, + + /** + * APIProperty: zoomOffset + * {Number} If your cache has more levels than you want to provide + * access to with this layer, supply a zoomOffset. This zoom offset + * is added to the current map zoom level to determine the level + * for a requested tile. For example, if you supply a zoomOffset + * of 3, when the map is at the zoom 0, tiles will be requested from + * level 3 of your cache. Default is 0 (assumes cache level and map + * zoom are equivalent). Additionally, if this layer is to be used + * as an overlay and the cache has fewer zoom levels than the base + * layer, you can supply a negative zoomOffset. For example, if a + * map zoom level of 1 corresponds to your cache level zero, you would + * supply a -1 zoomOffset (and set the maxResolution of the layer + * appropriately). The zoomOffset value has no effect if complete + * matrix definitions (including scaleDenominator) are supplied in + * the property. Defaults to 0 (no zoom offset). + */ + zoomOffset: 0, /** * Property: formatSuffixMap @@ -147,6 +166,13 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { "jpg": "jpg" }, + /** + * Property: matrix + * {Object} Matrix definition for the current map resolution. Updated by + * the method. + */ + matrix: null, + /** * Constructor: OpenLayers.Layer.WMTS * Create a new WMTS layer. @@ -175,10 +201,7 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { * Any other documented layer properties can be provided in the config object. */ initialize: function(config) { - config.params = OpenLayers.Util.upperCaseObject(config.params); - var args = [config.name, config.url, config.params, config]; - OpenLayers.Layer.Grid.prototype.initialize.apply(this, args); - + // confirm required properties are supplied var required = { url: true, @@ -187,11 +210,16 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { matrixSet: true }; for (var prop in required) { - if (!(prop in this)) { + if (!(prop in config)) { throw new Error("Missing property '" + prop + "' in layer configuration."); } } + config.params = OpenLayers.Util.upperCaseObject(config.params); + var args = [config.name, config.url, config.params, config]; + OpenLayers.Layer.Grid.prototype.initialize.apply(this, args); + + // determine format suffix (for REST) if (!this.formatSuffix) { this.formatSuffix = this.formatSuffixMap[this.format] || this.format.split("/").pop(); @@ -211,60 +239,54 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { }, + /** + * Method: setMap + */ + setMap: function() { + OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments); + this.updateMatrixProperties(); + }, + /** * Method: updateMatrixProperties - * Set as a listener for zoom end to update tile matrix related properties. + * Called when map resolution changes to update matrix related properties. */ updateMatrixProperties: function() { - if (this.matrixIds && this.matrixIds.length) { - var zoom = this.map.getZoom(); - var matrix = this.matrixIds[zoom]; - if (matrix) { - if (matrix.topLeftCorner) { - this.tileOrigin = matrix.topLeftCorner; - } - if (matrix.tileWidth && matrix.tileHeight) { - this.tileSize = new OpenLayers.Size( - matrix.tileWidth, matrix.tileHeight - ); - } + this.matrix = this.getMatrix(); + if (this.matrix) { + if (this.matrix.topLeftCorner) { + this.tileOrigin = this.matrix.topLeftCorner; + } + if (this.matrix.tileWidth && this.matrix.tileHeight) { + this.tileSize = new OpenLayers.Size( + this.matrix.tileWidth, this.matrix.tileHeight + ); + } + if (!this.tileOrigin) { + this.tileOrigin = new OpenLayers.LonLat( + this.maxExtent.left, this.maxExtent.top + ); + } + if (!this.tileFullExtent) { + this.tileFullExtent = this.maxExtent; } } }, /** - * Method: setMap - * Overwrite default from Layer - * + * Method: moveTo + * * Parameters: - * map - {} + * bound - {} + * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to + * do some init work in that case. + * dragging - {Boolean} */ - setMap: function(map) { - OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments); - this.map.events.on({ - zoomend: this.updateMatrixProperties, - scope: this - }); - this.updateMatrixProperties(); - if (!this.tileOrigin) { - this.tileOrigin = new OpenLayers.LonLat(this.maxExtent.left, this.maxExtent.top); - } - if (!this.tileFullExtent) { - this.tileFullExtent = this.maxExtent; + moveTo:function(bounds, zoomChanged, dragging) { + if (zoomChanged || !this.matrix) { + this.updateMatrixProperties(); } - }, - - /** - * Method: removeMap - */ - removeMap: function() { - if (this.map) { - this.map.events.un({ - zoomend: this.updateMatrixProperties, - scope: this - }); - } - OpenLayers.Layer.Grid.prototype.removeMap.apply(this, arguments); + return OpenLayers.Layer.Grid.prototype.moveTo.apply(this, arguments); }, /** @@ -287,19 +309,66 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, { }, /** - * Method: getMatrixId - * Determine the appropriate matrix id for the given map resolution. + * Method: getMatrix + * Get the appropriate matrix definition for the current map resolution. */ - getMatrixId: function() { - var id; - var zoom = this.map.getZoom(); + getMatrix: function() { + var matrix; if (!this.matrixIds || this.matrixIds.length === 0) { - id = zoom; + matrix = {identifier: this.map.getZoom() + this.zoomOffset}; } else { - // TODO: get appropriate matrix id given the map resolution - id = this.matrixIds[zoom].identifier; + // get appropriate matrix given the map scale if possible + if ("scaleDenominator" in this.matrixIds[0]) { + // scale denominator calculation based on WMTS spec + var denom = + OpenLayers.METERS_PER_INCH * + OpenLayers.INCHES_PER_UNIT[this.units] * + this.map.getResolution() / 0.28E-3; + var diff = Number.POSITIVE_INFINITY; + var delta; + for (var i=0, ii=this.matrixIds.length; i */ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { @@ -28,6 +31,18 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { */ sphericalMercator: false, + /** + * APIProperty: zoomOffset + * {Number} If your cache has more zoom levels than you want to provide + * access to with this layer, supply a zoomOffset. This zoom offset + * is added to the current map zoom level to determine the level + * for a requested tile. For example, if you supply a zoomOffset + * of 3, when the map is at the zoom 0, tiles will be requested from + * level 3 of your cache. Default is 0 (assumes cache level and map + * zoom are equivalent). + */ + zoomOffset: 0, + /** * Constructor: OpenLayers.Layer.XYZ * @@ -65,7 +80,7 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { * obj - {Object} Is this ever used? * * Returns: - * {} An exact clone of this OpenLayers.Layer.Grid + * {} An exact clone of this OpenLayers.Layer.XYZ */ clone: function (obj) { @@ -76,15 +91,7 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { } //get all additions from superclasses - obj = OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this, [obj]); - - // copy/set any non-init, non-simple values here - if (this.tileSize != null) { - obj.tileSize = this.tileSize.clone(); - } - - // we do not want to copy reference to grid, so we make a new array - obj.grid = []; + obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]); return obj; }, @@ -106,7 +113,7 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { / (res * this.tileSize.w)); var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h)); - var z = this.map.getZoom(); + var z = this.map.getZoom() + this.zoomOffset; var url = this.url; var s = '' + x + y + z; @@ -167,12 +174,22 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { * (end) * * This layer defaults to Spherical Mercator. + * + * Inherits from: + * - */ - OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { name: "OpenStreetMap", attribution: "Data CC-By-SA by OpenStreetMap", sphericalMercator: true, url: 'http://tile.openstreetmap.org/${z}/${x}/${y}.png', + clone: function(obj) { + if (obj == null) { + obj = new OpenLayers.Layer.OSM( + this.name, this.url, this.getOptions()); + } + obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]); + return obj; + }, CLASS_NAME: "OpenLayers.Layer.OSM" }); diff --git a/lib/OpenLayers/Layer/Yahoo.js b/lib/OpenLayers/Layer/Yahoo.js index 4bbcef67..bde68903 100644 --- a/lib/OpenLayers/Layer/Yahoo.js +++ b/lib/OpenLayers/Layer/Yahoo.js @@ -63,6 +63,14 @@ OpenLayers.Layer.Yahoo = OpenLayers.Class( */ type: null, + /** + * APIProperty: wrapDateLine + * {Boolean} Allow user to pan forever east/west. Default is true. + * Setting this to false only restricts panning if + * is true. + */ + wrapDateLine: true, + /** * APIProperty: sphericalMercator * {Boolean} Should the map act as a mercator-projected map? This will diff --git a/lib/OpenLayers/Layer/Zoomify.js b/lib/OpenLayers/Layer/Zoomify.js index dba37bdb..770bb19e 100644 --- a/lib/OpenLayers/Layer/Zoomify.js +++ b/lib/OpenLayers/Layer/Zoomify.js @@ -3,7 +3,7 @@ * full text of the license. */ /* * Development supported by a R&D grant DC08P02OUK006 - Old Maps Online - * (www.oldmapsonline.org) from Ministry of Culture of the Czech Republic. + * (www.oldmapsonline.org) from Ministry of Culture of the Czech Republic. */ @@ -13,7 +13,7 @@ /** * Class: OpenLayers.Layer.Zoomify - * + * * Inherits from: * - */ @@ -46,34 +46,34 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { /** * Property: numberOfTiers * {Integer} Depth of the Zoomify pyramid, number of tiers (zoom levels) - * - filled during Zoomify pyramid initialization. + * - filled during Zoomify pyramid initialization. */ - numberOfTiers: 0, + numberOfTiers: 0, /** * Property: tileCountUpToTier * {Array(Integer)} Number of tiles up to the given tier of pyramid. - * - filled during Zoomify pyramid initialization. + * - filled during Zoomify pyramid initialization. */ - tileCountUpToTier: new Array(), + tileCountUpToTier: new Array(), /** * Property: tierSizeInTiles * {Array()} Size (in tiles) for each tier of pyramid. - * - filled during Zoomify pyramid initialization. + * - filled during Zoomify pyramid initialization. */ - tierSizeInTiles: new Array(), + tierSizeInTiles: new Array(), /** * Property: tierImageSize * {Array()} Image size in pixels for each pyramid tier. - * - filled during Zoomify pyramid initialization. + * - filled during Zoomify pyramid initialization. */ - tierImageSize: new Array(), + tierImageSize: new Array(), /** * Constructor: OpenLayers.Layer.Zoomify - * + * * Parameters: * name - {String} A name for the layer. * url - {String} - Relative or absolute path to the image or more @@ -83,93 +83,93 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { * options - {Object} Hashtable of extra options to tag onto the layer */ initialize: function(name, url, size, options) { - - // initilize the Zoomify pyramid for given size - this.initializeZoomify( size ); + + // initilize the Zoomify pyramid for given size + this.initializeZoomify( size ); var newArguments = []; newArguments.push(name, url, size, {}, options); OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments); - }, + }, /** * Method: initializeZoomify * It generates constants for all tiers of the Zoomify pyramid - * + * * Parameters: * size - {} The size of the image in pixels - * + * */ - initializeZoomify: function( size ) { - - var imageSize = size.clone() - var tiles = new OpenLayers.Size( - Math.ceil( imageSize.w / this.standardTileSize ), - Math.ceil( imageSize.h / this.standardTileSize ) - ); - - this.tierSizeInTiles.push( tiles ); - this.tierImageSize.push( imageSize ); - - while (imageSize.w > this.standardTileSize || - imageSize.h > this.standardTileSize ) { - - imageSize = new OpenLayers.Size( - Math.floor( imageSize.w / 2 ), - Math.floor( imageSize.h / 2 ) - ); - tiles = new OpenLayers.Size( - Math.ceil( imageSize.w / this.standardTileSize ), - Math.ceil( imageSize.h / this.standardTileSize ) - ); - this.tierSizeInTiles.push( tiles ); - this.tierImageSize.push( imageSize ); - } - - this.tierSizeInTiles.reverse(); - this.tierImageSize.reverse(); - - this.numberOfTiers = this.tierSizeInTiles.length; - - this.tileCountUpToTier[0] = 0; - for (var i = 1; i < this.numberOfTiers; i++) { - this.tileCountUpToTier.push( - this.tierSizeInTiles[i-1].w * this.tierSizeInTiles[i-1].h + - this.tileCountUpToTier[i-1] - ); - } - }, + initializeZoomify: function( size ) { + + var imageSize = size.clone() + var tiles = new OpenLayers.Size( + Math.ceil( imageSize.w / this.standardTileSize ), + Math.ceil( imageSize.h / this.standardTileSize ) + ); + + this.tierSizeInTiles.push( tiles ); + this.tierImageSize.push( imageSize ); + + while (imageSize.w > this.standardTileSize || + imageSize.h > this.standardTileSize ) { + + imageSize = new OpenLayers.Size( + Math.floor( imageSize.w / 2 ), + Math.floor( imageSize.h / 2 ) + ); + tiles = new OpenLayers.Size( + Math.ceil( imageSize.w / this.standardTileSize ), + Math.ceil( imageSize.h / this.standardTileSize ) + ); + this.tierSizeInTiles.push( tiles ); + this.tierImageSize.push( imageSize ); + } + + this.tierSizeInTiles.reverse(); + this.tierImageSize.reverse(); + + this.numberOfTiers = this.tierSizeInTiles.length; + + this.tileCountUpToTier[0] = 0; + for (var i = 1; i < this.numberOfTiers; i++) { + this.tileCountUpToTier.push( + this.tierSizeInTiles[i-1].w * this.tierSizeInTiles[i-1].h + + this.tileCountUpToTier[i-1] + ); + } + }, /** * APIMethod:destroy */ destroy: function() { - // for now, nothing special to do here. + // for now, nothing special to do here. OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments); - // Remove from memory the Zoomify pyramid - is that enough? - this.tileCountUpToTier.length = 0 - this.tierSizeInTiles.length = 0 - this.tierImageSize.length = 0 + // Remove from memory the Zoomify pyramid - is that enough? + this.tileCountUpToTier.length = 0 + this.tierSizeInTiles.length = 0 + this.tierImageSize.length = 0 }, - + /** * APIMethod: clone - * + * * Parameters: * obj - {Object} - * + * * Returns: * {} An exact clone of this */ clone: function (obj) { - + if (obj == null) { obj = new OpenLayers.Layer.Zoomify(this.name, this.url, - this.size, + this.size, this.options); } @@ -179,17 +179,17 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { // copy/set any non-init, non-simple values here return obj; - }, - + }, + /** * Method: getURL - * + * * Parameters: * bounds - {} - * + * * Returns: - * {String} A string with the layer's url and parameters and also the - * passed-in bounds and appropriate tile size specified as + * {String} A string with the layer's url and parameters and also the + * passed-in bounds and appropriate tile size specified as * parameters */ getURL: function (bounds) { @@ -199,9 +199,9 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h)); var z = this.map.getZoom(); - var tileIndex = x + y * this.tierSizeInTiles[z].w + this.tileCountUpToTier[z]; - var path = "TileGroup" + Math.floor( (tileIndex) / 256 ) + - "/" + z + "-" + x + "-" + y + ".jpg"; + var tileIndex = x + y * this.tierSizeInTiles[z].w + this.tileCountUpToTier[z]; + var path = "TileGroup" + Math.floor( (tileIndex) / 256 ) + + "/" + z + "-" + x + "-" + y + ".jpg"; var url = this.url; if (url instanceof Array) { url = this.selectUrl(path, url); @@ -213,50 +213,50 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { * Method: getImageSize * getImageSize returns size for a particular tile. If bounds are given as * first argument, size is calculated (bottom-right tiles are non square). - * + * */ getImageSize: function() { - if (arguments.length > 0) { - bounds = this.adjustBounds(arguments[0]); - var res = this.map.getResolution(); - var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w)); - var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h)); - var z = this.map.getZoom(); - var w = this.standardTileSize; - var h = this.standardTileSize; - if (x == this.tierSizeInTiles[z].w -1 ) { - var w = this.tierImageSize[z].w % this.standardTileSize; - }; - if (y == this.tierSizeInTiles[z].h -1 ) { - var h = this.tierImageSize[z].h % this.standardTileSize; - }; - return (new OpenLayers.Size(w, h)); - } else { - return this.tileSize; - } + if (arguments.length > 0) { + bounds = this.adjustBounds(arguments[0]); + var res = this.map.getResolution(); + var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w)); + var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h)); + var z = this.map.getZoom(); + var w = this.standardTileSize; + var h = this.standardTileSize; + if (x == this.tierSizeInTiles[z].w -1 ) { + var w = this.tierImageSize[z].w % this.standardTileSize; + }; + if (y == this.tierSizeInTiles[z].h -1 ) { + var h = this.tierImageSize[z].h % this.standardTileSize; + }; + return (new OpenLayers.Size(w, h)); + } else { + return this.tileSize; + } }, /** * Method: addTile - * addTile creates a tile, initializes it, and adds it to the layer div. - * + * addTile creates a tile, initializes it, and adds it to the layer div. + * * Parameters: * bounds - {} * position - {} - * + * * Returns: * {} The added OpenLayers.Tile.Image */ addTile:function(bounds,position) { - return new OpenLayers.Tile.Image(this, position, bounds, + return new OpenLayers.Tile.Image(this, position, bounds, null, this.tileSize); }, - /** + /** * APIMethod: setMap - * When the layer is added to a map, then we can fetch our origin - * (if we don't have one.) - * + * When the layer is added to a map, then we can fetch our origin + * (if we don't have one.) + * * Parameters: * map - {} */ @@ -266,9 +266,9 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { this.map.maxExtent.top); }, - /** + /** * Method: calculateGridLayout - * Generate parameters for the grid layout. This + * Generate parameters for the grid layout. This * * Parameters: * bounds - {} @@ -282,25 +282,25 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, { calculateGridLayout: function(bounds, extent, resolution) { var tilelon = resolution * this.tileSize.w; var tilelat = resolution * this.tileSize.h; - + var offsetlon = bounds.left - extent.left; var tilecol = Math.floor(offsetlon/tilelon) - this.buffer; var tilecolremain = offsetlon/tilelon - tilecol; var tileoffsetx = -tilecolremain * this.tileSize.w; var tileoffsetlon = extent.left + tilecol * tilelon; - - var offsetlat = extent.top - bounds.top + tilelat; + + var offsetlat = extent.top - bounds.top + tilelat; var tilerow = Math.floor(offsetlat/tilelat) - this.buffer; var tilerowremain = tilerow - offsetlat/tilelat; var tileoffsety = tilerowremain * this.tileSize.h; var tileoffsetlat = extent.top - tilelat*tilerow; - - return { + + return { tilelon: tilelon, tilelat: tilelat, tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat, tileoffsetx: tileoffsetx, tileoffsety: tileoffsety }; - }, + }, CLASS_NAME: "OpenLayers.Layer.Zoomify" }); diff --git a/lib/OpenLayers/Location.js b/lib/OpenLayers/Location.js new file mode 100644 index 00000000..9dfa6241 --- /dev/null +++ b/lib/OpenLayers/Location.js @@ -0,0 +1,96 @@ +/** + * Class: OpenLayers.Location + * Representation of a point location on a 2-dimensional plane. + */ +OpenLayers.Location = OpenLayers.Class({ + + /** + * APIProperty: x + * {Number} The coordinate value in the x-axis direction (read-only). + */ + + /** + * APIProperty: y + * {Number} The coordinate value in the y-axis direction (read-only). + */ + + /** + * APIProperty: projection + * {} Optional projection for the point (read-only). + * No default projection is assumed. + */ + + /** + * Constructor: OpenLayers.Location + * Create a new point location. + * + * Parameters: + * config - {Object} + */ + initialize: function(config) { + config = config || {}; + if (config instanceof Array) { + config = { + x: config[0], + y: config[1] + }; + } + var projection = config.projection; + if (projection) { + if (!(projection instanceof OpenLayers.Projection)) { + projection = new OpenLayers.Projection(projection); + } + this.projection = projection; + } + this.x = parseFloat(config.x); + this.y = parseFloat(config.y); + }, + + /** + * APIMethod: transform + * Transform this location to a new projection. Returns a new location + * instead of modifying this one. Throws an error if this location + * doesn't have a set. + * + * Parameters: + * projection - { | String} A projection or + * identifier for a projection. + * + * Returns: + * {} A new location that represents this location + * transformed to the given projection. + */ + transform: function(projection) { + if (!this.projection) { + throw new Error("Location must have projection set before it can be transformed"); + } + if (!(projection instanceof OpenLayers.Projection)) { + projection = new OpenLayers.Projection(projection); + } + var config = OpenLayers.Projection.transform(this, this.projection, projection); + config.projection = projection; + return new OpenLayers.Location(config); + }, + + /** + * APIMethod: clone + * Create a clone of this location. + * + * Parameters: + * config - {Object} Optional configuration object with properties to be + * set on the clone. + * + * Returns: + * {} A location with the same properties as this one. + */ + clone: function(config) { + return new OpenLayers.Location( + OpenLayers.Util.extend( + {x: this.x, y: this.y, projection: this.projection}, + config + ) + ); + }, + + CLASS_NAME: "OpenLayers.Location" +}); diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 18e980de..b5921aab 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -7,6 +7,7 @@ * @requires OpenLayers/Events.js * @requires OpenLayers/Tween.js * @requires OpenLayers/Console.js + * @requires OpenLayers/Projection.js */ /** @@ -72,23 +73,16 @@ OpenLayers.Map = OpenLayers.Class({ * - *move* triggered after each drag, pan, or zoom * - *moveend* triggered after a drag, pan, or zoom completes * - *zoomend* triggered after a zoom completes - * - *addmarker* triggered after a marker has been added - * - *removemarker* triggered after a marker has been removed - * - *clearmarkers* triggered after markers have been cleared * - *mouseover* triggered after mouseover the map * - *mouseout* triggered after mouseout the map * - *mousemove* triggered after mousemove the map - * - *dragstart* Does not work. Register for movestart instead. - * - *drag* Does not work. Register for move instead. - * - *dragend* Does not work. Register for moveend instead. * - *changebaselayer* triggered after the base layer changes */ EVENT_TYPES: [ - "preaddlayer", "addlayer", "removelayer", "changelayer", "movestart", - "move", "moveend", "zoomend", "popupopen", "popupclose", - "addmarker", "removemarker", "clearmarkers", "mouseover", - "mouseout", "mousemove", "dragstart", "drag", "dragend", - "changebaselayer"], + "preaddlayer", "addlayer", "removelayer", "changelayer", "changebaselayer", + "movestart", "move", "moveend", "zoomend", + "mouseover", "mouseout", "mousemove" + ], /** * Property: id @@ -96,6 +90,12 @@ OpenLayers.Map = OpenLayers.Class({ */ id: null, + /** + * APIProperty: userProjection + * {} + */ + userProjection: "EPSG:4326", + /** * Property: fractionalZoom * {Boolean} For a base layer that supports it, allow the map resolution @@ -352,15 +352,6 @@ OpenLayers.Map = OpenLayers.Class({ * different value in the map options if needed. */ numZoomLevels: 16, - - /** - * APIProperty: theme - * {String} Relative path to a CSS file from which to load theme styles. - * Specify null in the map options (e.g. {theme: null}) if you - * want to get cascading style declarations - by putting links to - * stylesheets or style declarations directly in your page. - */ - theme: null, /** * APIProperty: displayProjection @@ -470,7 +461,7 @@ OpenLayers.Map = OpenLayers.Class({ options = div; div = options && options.div; } - + // Simple-type defaults are set in class definition. // Now set complex-type defaults this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH, @@ -480,11 +471,12 @@ OpenLayers.Map = OpenLayers.Class({ this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15); - this.theme = OpenLayers._getScriptLocation() + - 'theme/default/style.css'; - // now override default options OpenLayers.Util.extend(this, options); + + if (!(this.userProjection instanceof OpenLayers.Projection)) { + this.userProjection = new OpenLayers.Projection(this.userProjection); + } // initialize layers array this.layers = []; @@ -545,29 +537,6 @@ OpenLayers.Map = OpenLayers.Class({ this.updateSizeDestroy); } - // only append link stylesheet if the theme property is set - if(this.theme) { - // check existing links for equivalent url - var addNode = true; - var nodes = document.getElementsByTagName('link'); - for(var i=0, len=nodes.length; i} This map. + */ + set: function(properties) { + var center = properties.center; + if (center && !(center instanceof OpenLayers.Location)) { + center = new OpenLayers.Location(center); + } + return this.setCenter(center, properties.zoom); + }, /** * APIMethod: setCenter * Set the map center (and optionally, the zoom level). * * Parameters: - * lonlat - {} The new center location. + * center - { | } The pixel to get the geodesic length for. If + * not provided, the center pixel of the map viewport will be used. + * + * Returns: + * {} The geodesic size of the pixel in kilometers. + */ + getGeodesicPixelSize: function(px) { + var lonlat = px ? this.getLonLatFromPixel(px) : (this.getCenter() || + new OpenLayers.LonLat(0, 0)); + var res = this.getResolution(); + var left = lonlat.add(-res / 2, 0); + var right = lonlat.add(res / 2, 0); + var bottom = lonlat.add(0, -res / 2); + var top = lonlat.add(0, res / 2); + var dest = new OpenLayers.Projection("EPSG:4326"); + var source = this.getProjectionObject() || dest; + if(!source.equals(dest)) { + left.transform(source, dest); + right.transform(source, dest); + bottom.transform(source, dest); + top.transform(source, dest); + } + + return new OpenLayers.Size( + OpenLayers.Util.distVincenty(left, right), + OpenLayers.Util.distVincenty(bottom, top) + ); + }, diff --git a/lib/OpenLayers/Marker.js b/lib/OpenLayers/Marker.js index 3e0845eb..d03460b1 100644 --- a/lib/OpenLayers/Marker.js +++ b/lib/OpenLayers/Marker.js @@ -21,9 +21,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)); * markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon.clone())); * diff --git a/lib/OpenLayers/Popup/Anchored.js b/lib/OpenLayers/Popup/Anchored.js index c0cd89da..c7851c2d 100644 --- a/lib/OpenLayers/Popup/Anchored.js +++ b/lib/OpenLayers/Popup/Anchored.js @@ -185,10 +185,10 @@ OpenLayers.Popup.Anchored = var size = this.size || this.contentSize; var top = (this.relativePosition.charAt(0) == 't'); - newPx.y += (top) ? -size.h : this.anchor.size.h; + newPx.y += (top) ? -(size.h + this.anchor.size.h) : this.anchor.size.h; var left = (this.relativePosition.charAt(1) == 'l'); - newPx.x += (left) ? -size.w : this.anchor.size.w; + newPx.x += (left) ? -(size.w + this.anchor.size.w) : this.anchor.size.w; return newPx; }, diff --git a/lib/OpenLayers/Popup/FramedCloud.js b/lib/OpenLayers/Popup/FramedCloud.js index 68ee6f2c..c994d97f 100644 --- a/lib/OpenLayers/Popup/FramedCloud.js +++ b/lib/OpenLayers/Popup/FramedCloud.js @@ -38,7 +38,7 @@ OpenLayers.Popup.FramedCloud = * APIProperty: imageSize * {} */ - imageSize: new OpenLayers.Size(676, 736), + imageSize: new OpenLayers.Size(1276, 736), /** * APIProperty: isAlphaImage @@ -71,7 +71,7 @@ OpenLayers.Popup.FramedCloud = { //top-right size: new OpenLayers.Size(22, 'auto'), anchor: new OpenLayers.Bounds(null, 50, 0, 0), - position: new OpenLayers.Pixel(-638, 0) + position: new OpenLayers.Pixel(-1238, 0) }, { //bottom-left size: new OpenLayers.Size('auto', 19), @@ -81,7 +81,7 @@ OpenLayers.Popup.FramedCloud = { //bottom-right size: new OpenLayers.Size(22, 18), anchor: new OpenLayers.Bounds(null, 32, 0, null), - position: new OpenLayers.Pixel(-638, -632) + position: new OpenLayers.Pixel(-1238, -632) }, { // stem size: new OpenLayers.Size(81, 35), @@ -102,7 +102,7 @@ OpenLayers.Popup.FramedCloud = { //top-right size: new OpenLayers.Size(22, 'auto'), anchor: new OpenLayers.Bounds(null, 50, 0, 0), - position: new OpenLayers.Pixel(-638, 0) + position: new OpenLayers.Pixel(-1238, 0) }, { //bottom-left size: new OpenLayers.Size('auto', 19), @@ -112,7 +112,7 @@ OpenLayers.Popup.FramedCloud = { //bottom-right size: new OpenLayers.Size(22, 19), anchor: new OpenLayers.Bounds(null, 32, 0, null), - position: new OpenLayers.Pixel(-638, -631) + position: new OpenLayers.Pixel(-1238, -631) }, { // stem size: new OpenLayers.Size(81, 35), @@ -133,7 +133,7 @@ OpenLayers.Popup.FramedCloud = { //top-right size: new OpenLayers.Size(22, 'auto'), anchor: new OpenLayers.Bounds(null, 21, 0, 32), - position: new OpenLayers.Pixel(-638, 0) + position: new OpenLayers.Pixel(-1238, 0) }, { //bottom-left size: new OpenLayers.Size('auto', 21), @@ -143,7 +143,7 @@ OpenLayers.Popup.FramedCloud = { //bottom-right size: new OpenLayers.Size(22, 21), anchor: new OpenLayers.Bounds(null, 0, 0, null), - position: new OpenLayers.Pixel(-638, -629) + position: new OpenLayers.Pixel(-1238, -629) }, { // stem size: new OpenLayers.Size(81, 33), @@ -164,7 +164,7 @@ OpenLayers.Popup.FramedCloud = { //top-right size: new OpenLayers.Size(22, 'auto'), anchor: new OpenLayers.Bounds(null, 21, 0, 32), - position: new OpenLayers.Pixel(-638, 0) + position: new OpenLayers.Pixel(-1238, 0) }, { //bottom-left size: new OpenLayers.Size('auto', 21), @@ -174,7 +174,7 @@ OpenLayers.Popup.FramedCloud = { //bottom-right size: new OpenLayers.Size(22, 21), anchor: new OpenLayers.Bounds(null, 0, 0, null), - position: new OpenLayers.Pixel(-638, -629) + position: new OpenLayers.Pixel(-1238, -629) }, { // stem size: new OpenLayers.Size(81, 33), @@ -195,7 +195,7 @@ OpenLayers.Popup.FramedCloud = * APIProperty: maxSize * {} */ - maxSize: new OpenLayers.Size(600, 660), + maxSize: new OpenLayers.Size(1200, 660), /** * Constructor: OpenLayers.Popup.FramedCloud diff --git a/lib/OpenLayers/Protocol.js b/lib/OpenLayers/Protocol.js index 7b92df97..30adc05d 100644 --- a/lib/OpenLayers/Protocol.js +++ b/lib/OpenLayers/Protocol.js @@ -57,20 +57,18 @@ OpenLayers.Protocol = OpenLayers.Class({ * filter - {OpenLayers.Filter} */ mergeWithDefaultFilter: function(filter) { - if(filter) { - if(this.defaultFilter) { - filter = new OpenLayers.Filter.Logical({ - type: OpenLayers.Filter.Logical.AND, - filters: [this.defaultFilter, filter] - }); - } + var merged; + if (filter && this.defaultFilter) { + merged = new OpenLayers.Filter.Logical({ + type: OpenLayers.Filter.Logical.AND, + filters: [this.defaultFilter, filter] + }); } else { - filter = this.defaultFilter; + merged = filter || this.defaultFilter || undefined; } - return filter; + return merged; }, - /** * APIMethod: destroy * Clean up the protocol. diff --git a/lib/OpenLayers/Protocol/WFS/v1.js b/lib/OpenLayers/Protocol/WFS/v1.js index d64ac54a..94bf2dcc 100644 --- a/lib/OpenLayers/Protocol/WFS/v1.js +++ b/lib/OpenLayers/Protocol/WFS/v1.js @@ -74,6 +74,12 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { */ readFormat: null, + /** + * Property: readOptions + * {Object} Optional object to pass to format's read. + */ + readOptions: null, + /** * Constructor: OpenLayers.Protocol.WFS * A class for giving layers WFS protocol. @@ -173,7 +179,12 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { var request = response.priv; if(request.status >= 200 && request.status < 300) { // success - response.features = this.parseFeatures(request); + if (this.readOptions && this.readOptions.output == "object") { + OpenLayers.Util.extend(response, + this.parseResponse(request, this.readOptions)); + } else { + response.features = this.parseResponse(request); + } response.code = OpenLayers.Protocol.Response.SUCCESS; } else { // failure @@ -184,17 +195,20 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { }, /** - * Method: parseFeatures + * Method: parseResponse * Read HTTP response body and return features * * Parameters: * request - {XMLHttpRequest} The request object + * options - {Object} Optional object to pass to format's read * * Returns: - * {Array({})} or - * {} Array of features or a single feature. + * {Object} or {Array({})} or + * {} + * An object with a features property, an array of features or a single + * feature. */ - parseFeatures: function(request) { + parseResponse: function(request, options) { var doc = request.responseXML; if(!doc || !doc.documentElement) { doc = request.responseText; @@ -203,7 +217,7 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { return null; } return (this.readFormat !== null) ? this.readFormat.read(doc) : - this.format.read(doc); + this.format.read(doc, options); }, /** @@ -284,9 +298,9 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { }); var root = this.format.createElementNSPlus("wfs:Transaction", { - attributes: { - service: "WFS", - version: this.version + attributes: { + service: "WFS", + version: this.version } }); diff --git a/lib/OpenLayers/Renderer.js b/lib/OpenLayers/Renderer.js index ffcabd3c..7fa249a7 100644 --- a/lib/OpenLayers/Renderer.js +++ b/lib/OpenLayers/Renderer.js @@ -345,7 +345,6 @@ OpenLayers.Renderer = OpenLayers.Class({ * strokeColor: "#000000", * strokeOpacity: 1, * strokeWidth: 1, - * strokeDashstyle: "solid", * pointRadius: 3, * graphicName: "square" * }; @@ -357,7 +356,6 @@ OpenLayers.Renderer.defaultSymbolizer = { strokeWidth: 2, fillOpacity: 1, strokeOpacity: 1, - strokeDashstyle: "solid", pointRadius: 0 }; diff --git a/lib/OpenLayers/Renderer/Canvas.js b/lib/OpenLayers/Renderer/Canvas.js index ed743373..0ad38f60 100644 --- a/lib/OpenLayers/Renderer/Canvas.js +++ b/lib/OpenLayers/Renderer/Canvas.js @@ -166,7 +166,6 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { */ drawExternalGraphic: function(pt, style) { var img = new Image(); - img.src = style.externalGraphic; if(style.graphicTitle) { img.title=style.graphicTitle; @@ -180,19 +179,21 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { style.graphicXOffset : -(0.5 * width); var yOffset = (style.graphicYOffset != undefined) ? style.graphicYOffset : -(0.5 * height); - var opacity = style.graphicOpacity || style.fillOpacity; var context = { img: img, x: (pt[0]+xOffset), y: (pt[1]+yOffset), width: width, height: height, + opacity: style.graphicOpacity || style.fillOpacity, canvas: this.canvas }; img.onload = OpenLayers.Function.bind( function() { + this.canvas.globalAlpha = this.opacity; this.canvas.drawImage(this.img, this.x, this.y, this.width, this.height); - }, context); + }, context); + img.src = style.externalGraphic; }, /** @@ -393,14 +394,14 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { var y = ((extent.top / resolution) - point.y / resolution); return [x, y]; }, - + /** * Method: clear * Clear all vectors from the renderer. - * virtual function. */ clear: function() { this.canvas.clearRect(0, 0, this.root.width, this.root.height); + this.features = {}; }, /** @@ -458,7 +459,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { */ redraw: function() { if (!this.locked) { - this.clear(); + this.canvas.clearRect(0, 0, this.root.width, this.root.height); var labelMap = []; var feature, style; for (var id in this.features) { diff --git a/lib/OpenLayers/Renderer/Elements.js b/lib/OpenLayers/Renderer/Elements.js index a161f7be..87e817dc 100644 --- a/lib/OpenLayers/Renderer/Elements.js +++ b/lib/OpenLayers/Renderer/Elements.js @@ -442,14 +442,17 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, { * Remove all the elements from the root */ clear: function() { - if (this.vectorRoot) { - while (this.vectorRoot.childNodes.length > 0) { - this.vectorRoot.removeChild(this.vectorRoot.firstChild); + var child; + var root = this.vectorRoot; + if (root) { + while (child = root.firstChild) { + root.removeChild(child); } } - if (this.textRoot) { - while (this.textRoot.childNodes.length > 0) { - this.textRoot.removeChild(this.textRoot.firstChild); + root = this.textRoot; + if (root) { + while (child = root.firstChild) { + root.removeChild(child); } } if (this.indexer) { diff --git a/lib/OpenLayers/Renderer/SVG.js b/lib/OpenLayers/Renderer/SVG.js index 38814272..e75e2d60 100644 --- a/lib/OpenLayers/Renderer/SVG.js +++ b/lib/OpenLayers/Renderer/SVG.js @@ -273,7 +273,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { } else if (style.externalGraphic) { pos = this.getPosition(node); - if (style.graphicTitle) { + if (style.graphicTitle) { node.setAttributeNS(null, "title", style.graphicTitle); } if (style.graphicWidth && style.graphicHeight) { @@ -371,8 +371,8 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { // Hard-coded linejoin for now, to make it look the same as in VML. // There is no strokeLinejoin property yet for symbolizers. node.setAttributeNS(null, "stroke-linejoin", "round"); - node.setAttributeNS(null, "stroke-dasharray", this.dashStyle(style, - widthFactor)); + style.strokeDashstyle && node.setAttributeNS(null, + "stroke-dasharray", this.dashStyle(style, widthFactor)); } else { node.setAttributeNS(null, "stroke", "none"); } @@ -380,7 +380,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { if (style.pointerEvents) { node.setAttributeNS(null, "pointer-events", style.pointerEvents); } - + if (style.cursor != null) { node.setAttributeNS(null, "cursor", style.cursor); } @@ -767,7 +767,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { var complete = true; var len = components.length; var strings = []; - var str, component, j; + var str, component; for(var i=0; i + */ +OpenLayers.Strategy.Filter = OpenLayers.Class(OpenLayers.Strategy, { + + /** + * APIProperty: filter + * {} Filter for limiting features sent to the layer. + * Use the method to update this filter after construction. + */ + filter: null, + + /** + * Property: cache + * {Array()} List of currently cached + * features. + */ + cache: null, + + /** + * Property: caching + * {Boolean} The filter is currently caching features. + */ + caching: false, + + /** + * Constructor: OpenLayers.Strategy.Filter + * Create a new filter strategy. + * + * Parameters: + * options - {Object} Optional object whose properties will be set on the + * instance. Strategy must be constructed with at least a + * property. + */ + initialize: function(options) { + OpenLayers.Strategy.prototype.initialize.apply(this, [options]); + if (!this.filter || !(this.filter instanceof OpenLayers.Filter)) { + throw new Error("Filter strategy must be constructed with a filter"); + } + }, + + /** + * APIMethod: activate + * Activate the strategy. Register any listeners, do appropriate setup. + * By default, this strategy automatically activates itself when a layer + * is added to a map. + * + * Returns: + * {Boolean} True if the strategy was successfully activated or false if + * the strategy was already active. + */ + activate: function() { + var activated = OpenLayers.Strategy.prototype.activate.apply(this, arguments); + if (activated) { + this.cache = []; + this.layer.events.on({ + "beforefeaturesadded": this.handleAdd, + "beforefeaturesremoved": this.handleRemove, + scope: this + }); + } + return activated; + }, + + /** + * APIMethod: deactivate + * Deactivate the strategy. Clear the feature cache. + * + * Returns: + * {Boolean} True if the strategy was successfully deactivated or false if + * the strategy was already inactive. + */ + deactivate: function() { + this.cache = null; + if (this.layer && this.layer.events) { + this.layer.events.un({ + "beforefeaturesadded": this.handleAdd, + "beforefeaturesremoved": this.handleRemove, + scope: this + }); + } + return OpenLayers.Strategy.prototype.deactivate.apply(this, arguments); + }, + + /** + * Method: handleAdd + */ + handleAdd: function(event) { + if (!this.caching) { + var features = event.features; + event.features = []; + var feature; + for (var i=0, ii=features.length; i A filter for evaluating features. + */ + setFilter: function(filter) { + this.filter = filter; + var previousCache = this.cache; + this.cache = []; + // look through layer for features to remove from layer + this.handleAdd({features: this.layer.features}); + // cache now contains features to remove from layer + if (this.cache.length > 0) { + this.caching = true; + this.layer.removeFeatures(this.cache.slice(), {silent: true}); + this.caching = false; + } + // now look through previous cache for features to add to layer + if (previousCache.length > 0) { + var event = {features: previousCache}; + this.handleAdd(event); + // event has features to add to layer + this.caching = true; + this.layer.addFeatures(event.features, {silent: true}); + this.caching = false; + } + }, + + CLASS_NAME: "OpenLayers.Strategy.Filter" + +}); diff --git a/lib/OpenLayers/Strategy/Save.js b/lib/OpenLayers/Strategy/Save.js index 2fb7e397..fa2039ea 100644 --- a/lib/OpenLayers/Strategy/Save.js +++ b/lib/OpenLayers/Strategy/Save.js @@ -83,7 +83,7 @@ OpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, { this.timer = window.setInterval( OpenLayers.Function.bind(this.save, this), this.auto * 1000 - ) + ); } else { this.layer.events.on({ "featureadded": this.triggerSave, @@ -115,7 +115,7 @@ OpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, { "featureadded": this.triggerSave, "afterfeaturemodified": this.triggerSave, scope: this - }) + }); } } } diff --git a/lib/OpenLayers/Style2.js b/lib/OpenLayers/Style2.js new file mode 100644 index 00000000..cc0bf3e6 --- /dev/null +++ b/lib/OpenLayers/Style2.js @@ -0,0 +1,106 @@ +/** + * @requires OpenLayers/Rule.js + * @requires OpenLayers/Symbolizer/Point.js + * @requires OpenLayers/Symbolizer/Line.js + * @requires OpenLayers/Symbolizer/Polygon.js + * @requires OpenLayers/Symbolizer/Text.js + * @requires OpenLayers/Symbolizer/Raster.js + */ + +/** + * Class: OpenLayers.Style2 + * This class represents a collection of rules for rendering features. + */ +OpenLayers.Style2 = OpenLayers.Class({ + + /** + * Property: id + * {String} A unique id for this session. + */ + id: null, + + /** + * APIProperty: name + * {String} Style identifier. + */ + name: null, + + /** + * APIProperty: title + * {String} Title of this style. + */ + title: null, + + /** + * APIProperty: description + * {String} Description of this style. + */ + description: null, + + /** + * APIProperty: layerName + * {} Name of the layer that this style belongs to, usually + * according to the NamedLayer attribute of an SLD document. + */ + layerName: null, + + /** + * APIProperty: isDefault + * {Boolean} + */ + isDefault: false, + + /** + * APIProperty: rules + * {Array()} Collection of rendering rules. + */ + rules: null, + + /** + * Constructor: OpenLayers.Style2 + * Creates a style representing a collection of rendering rules. + * + * Parameters: + * config - {Object} An object containing properties to be set on the + * style. Any documented properties may be set at construction. + * + * Return: + * {} A new style object. + */ + initialize: function(config) { + OpenLayers.Util.extend(this, config); + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); + }, + + /** + * APIMethod: destroy + * nullify references to prevent circular references and memory leaks + */ + destroy: function() { + for (var i=0, len=this.rules.length; i} Clone of this style. + */ + clone: function() { + var config = OpenLayers.Util.extend({}, this); + // clone rules + if (this.rules) { + config.rules = []; + for (var i=0, len=this.rules.length; i and ). + */ + rotation: null, + + /** + * APIProperty: graphicName + * {String} Named graphic to use when rendering points. Supported values + * include "circle", "square", "star", "x", "cross", and "triangle". + */ + graphicName: null, + + /** + * Constructor: OpenLayers.Symbolizer.Point + * Create a symbolizer for rendering points. + * + * Parameters: + * config - {Object} An object containing properties to be set on the + * symbolizer. Any documented symbolizer property can be set at + * construction. + * + * Returns: + * A new point symbolizer. + */ + initialize: function(config) { + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Symbolizer.Point" + +}); + diff --git a/lib/OpenLayers/Symbolizer/Polygon.js b/lib/OpenLayers/Symbolizer/Polygon.js new file mode 100644 index 00000000..044d4f17 --- /dev/null +++ b/lib/OpenLayers/Symbolizer/Polygon.js @@ -0,0 +1,76 @@ +/** + * @requires OpenLayers/Symbolizer.js + */ + +/** + * Class: OpenLayers.Symbolizer.Polygon + * A symbolizer used to render line features. + */ +OpenLayers.Symbolizer.Polygon = OpenLayers.Class(OpenLayers.Symbolizer, { + + /** + * APIProperty: strokeColor + * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000" + * for red). + */ + strokeColor: null, + + /** + * APIProperty: strokeOpacity + * {Number} Stroke opacity (0-1). + */ + strokeOpacity: null, + + /** + * APIProperty: strokeWidth + * {Number} Pixel stroke width. + */ + strokeWidth: null, + + /** + * APIProperty: strokeLinecap + * {String} Stroke cap type ("butt", "round", or "square"). + */ + strokeLinecap: null, + + /** + * Property: strokeDashstyle + * {String} Stroke dash style according to the SLD spec. Note that the + * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot", + * "longdash", "longdashdot", or "solid") will not work in SLD, but + * most SLD patterns will render correctly in OpenLayers. + */ + strokeDashstyle: null, + + /** + * APIProperty: fillColor + * {String} RGB hex fill color (e.g. "#ff0000" for red). + */ + fillColor: null, + + /** + * APIProperty: fillOpacity + * {Number} Fill opacity (0-1). + */ + fillOpacity: null, + + /** + * Constructor: OpenLayers.Symbolizer.Polygon + * Create a symbolizer for rendering polygons. + * + * Parameters: + * config - {Object} An object containing properties to be set on the + * symbolizer. Any documented symbolizer property can be set at + * construction. + * + * Returns: + * A new polygon symbolizer. + */ + initialize: function(config) { + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Symbolizer.Polygon" + +}); + diff --git a/lib/OpenLayers/Symbolizer/Raster.js b/lib/OpenLayers/Symbolizer/Raster.js new file mode 100644 index 00000000..cdd72a88 --- /dev/null +++ b/lib/OpenLayers/Symbolizer/Raster.js @@ -0,0 +1,29 @@ +/** + * @requires OpenLayers/Symbolizer.js + */ + +/** + * Class: OpenLayers.Symbolizer.Raster + * A symbolizer used to render raster images. + */ +OpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, { + + /** + * Constructor: OpenLayers.Symbolizer.Raster + * Create a symbolizer for rendering rasters. + * + * Parameters: + * config - {Object} An object containing properties to be set on the + * symbolizer. Any documented symbolizer property can be set at + * construction. + * + * Returns: + * A new raster symbolizer. + */ + initialize: function(config) { + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Symbolizer.Raster" + +}); diff --git a/lib/OpenLayers/Symbolizer/Text.js b/lib/OpenLayers/Symbolizer/Text.js new file mode 100644 index 00000000..3e97fa5b --- /dev/null +++ b/lib/OpenLayers/Symbolizer/Text.js @@ -0,0 +1,60 @@ +/** + * @requires OpenLayers/Symbolizer.js + */ + +/** + * Class: OpenLayers.Symbolizer.Text + * A symbolizer used to render text labels for features. + */ +OpenLayers.Symbolizer.Text = OpenLayers.Class(OpenLayers.Symbolizer, { + + /** + * APIProperty: label + * {String} The text for the label. + */ + label: null, + + /** + * APIProperty: fontFamily + * {String} The font family for the label. + */ + fontFamily: null, + + /** + * APIProperty: fontSize + * {String} The font size for the label. + */ + fontSize: null, + + /** + * APIProperty: fontWeight + * {String} The font weight for the label. + */ + fontWeight: null, + + /** + * Property: fontStyle + * {String} The font style for the label. + */ + fontStyle: null, + + /** + * Constructor: OpenLayers.Symbolizer.Text + * Create a symbolizer for rendering text labels. + * + * Parameters: + * config - {Object} An object containing properties to be set on the + * symbolizer. Any documented symbolizer property can be set at + * construction. + * + * Returns: + * A new text symbolizer. + */ + initialize: function(config) { + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Symbolizer.Text" + +}); + diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js index c5750c90..126adfa5 100644 --- a/lib/OpenLayers/Tile/Image.js +++ b/lib/OpenLayers/Tile/Image.js @@ -183,7 +183,8 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, { } var drawTile = OpenLayers.Tile.prototype.draw.apply(this, arguments); - if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) { + if ((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) || + this.layer.singleTile) { if (drawTile) { //we use a clone of this tile to create a double buffer for visual //continuity. The backBufferTile is used to create transition @@ -317,9 +318,9 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, { positionImage: function() { // if the this layer doesn't exist at the point the image is // returned, do not attempt to use it for size computation - if ( this.layer == null ) + if (this.layer === null) { return; - + } // position the frame OpenLayers.Util.modifyDOMElement(this.frame, null, this.position, this.size); diff --git a/lib/OpenLayers/Tile/Image/IFrame.js b/lib/OpenLayers/Tile/Image/IFrame.js index 94191672..aca6a8f2 100644 --- a/lib/OpenLayers/Tile/Image/IFrame.js +++ b/lib/OpenLayers/Tile/Image/IFrame.js @@ -104,7 +104,7 @@ OpenLayers.Tile.Image.IFrame = OpenLayers.Class(OpenLayers.Tile.Image, { * Creates the imgDiv property on the tile. */ initImgDiv: function() { - this.imgDiv = this.createImgDiv() + this.imgDiv = this.createImgDiv(); OpenLayers.Util.modifyDOMElement(this.imgDiv, this.id, null, this.layer.getImageSize(), "relative"); diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index 030ad4ae..de7d6061 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -45,13 +45,6 @@ OpenLayers.Util.isElement = function(o) { return !!(o && o.nodeType === 1); }; -/** - * Maintain existing definition of $. - */ -if(typeof window.$ === "undefined") { - window.$ = OpenLayers.Util.getElement; -} - /** * APIFunction: extend * Copy all properties of a source object to a destination object. Modifies @@ -121,23 +114,6 @@ OpenLayers.Util.removeItem = function(array, item) { return array; }; -/** - * Function: clearArray - * *Deprecated*. This function will disappear in 3.0. - * Please use "array.length = 0" instead. - * - * Parameters: - * array - {Array} - */ -OpenLayers.Util.clearArray = function(array) { - OpenLayers.Console.warn( - OpenLayers.i18n( - "methodDeprecated", {'newMethod': 'array = []'} - ) - ); - array.length = 0; -}; - /** * Function: indexOf * Seems to exist already in FF, but not in MOZ. @@ -317,27 +293,6 @@ OpenLayers.Util.createImage = function(id, px, sz, imgURL, position, border, return image; }; -/** - * Function: setOpacity - * *Deprecated*. This function has been deprecated. Instead, please use - * - * or - * - * - * Set the opacity of a DOM Element - * Note that for this function to work in IE, elements must "have layout" - * according to: - * http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp - * - * Parameters: - * element - {DOMElement} Set the opacity on this DOM element - * opacity - {Float} Opacity value (0.0 - 1.0) - */ -OpenLayers.Util.setOpacity = function(element, opacity) { - OpenLayers.Util.modifyDOMElement(element, null, null, null, - null, null, null, opacity); -}; - /** * Function: onImageLoad * Bound to image load events. For all images created with or @@ -1078,27 +1033,6 @@ OpenLayers.Util.getParameters = function(url) { return parameters; }; -/** - * Function: getArgs - * *Deprecated*. Will be removed in 3.0. Please use instead - * - * - * Parameters: - * url - {String} Optional url used to extract the query string. - * If null, query string is taken from page location. - * - * Returns: - * {Object} An object of key/value pairs from the query string. - */ -OpenLayers.Util.getArgs = function(url) { - OpenLayers.Console.warn( - OpenLayers.i18n( - "methodDeprecated", {'newMethod': 'OpenLayers.Util.getParameters'} - ) - ); - return OpenLayers.Util.getParameters(url); -}; - /** * Property: lastSeqID * {Integer} The ever-incrementing count variable. @@ -1303,22 +1237,6 @@ OpenLayers.Util.getScaleFromResolution = function (resolution, units) { return scale; }; -/** - * Function: safeStopPropagation - * *Deprecated*. This function has been deprecated. Please use directly - * passing 'true' as the 2nd - * argument (preventDefault) - * - * Safely stop the propagation of an event *without* preventing - * the default browser action from occurring. - * - * Parameter: - * evt - {Event} - */ -OpenLayers.Util.safeStopPropagation = function(evt) { - OpenLayers.Event.stop(evt, true); -}; - /** * Function: pagePositon * Calculates the position of an element on the page. diff --git a/readme-dev.md b/readme-dev.md index b2afeb55..3bba0694 100644 --- a/readme-dev.md +++ b/readme-dev.md @@ -3,21 +3,27 @@ This document describes the process of cloning the central OpenLayers repository and making changes to it. It is really only relevant to developers who are currently core committers to the OpenLayers subversion repository. If you are -interested in contributing to the future of OpenLayers, please clone the +interested in contributing to the future of OpenLayers, please fork the [central repository][1], make changes, and issue pull requests. We welcome your contributions and appreciate the help! This document doesn't cover the git basics. The [help pages][2] on GitHub are a -good place to start learning git. - -There two type of changes developers will be making to the central OpenLayers +good place to start learning git. In particular, the document on [forking][3] +is a particularly good read for those who wish to contribute to the project but +don't have commit rights on the central repository. The rest of this document +pertains to changes made by developers with access to the central repository +(but those folks are encouraged to use their own forks for pushing changes as +well). + +There are two types of changes developers will be making to the central OpenLayers repository. The first type will be commits that add features toward the OpenLayers v3 API or remove parts of the v2 API. The second type of change -will be merges that come from the remote [OpenLayers subversion][3] repository. +will be merges that come from the remote [OpenLayers subversion][4] repository. [1]: http://github.com/openlayers/openlayers [2]: http://help.github.com/ -[3]: http://svn.openlayers.org/trunk/openlayers +[3]: http://help.github.com/forking/ +[4]: http://svn.openlayers.org/trunk/openlayers ## Pushing Commits to the Central Repository @@ -74,7 +80,7 @@ information or adding a new author from the subversion log. Finally, you need to configure your repo so it knows about the latest commit that the remote git-svn refers to. To do this, run the following: - git show origin/2.x | head -n 1 | sed 's/commit //' > .git/refs/remotes/git-svn + git update-ref refs/remotes/git-svn origin/2.x At this point, your local git repository should be configured to fetch changes from the remote OpenLayers subversion repository. Changes from this repository @@ -91,7 +97,7 @@ You should see something like what you'd expect from `svn info` inside a working copy of a subversion repository. The first time you run it, you'll get a lot of extra output about rebuilding the revision map. -### Fetching changes from svn +### Fetching and merging changes from svn As mentioned above, you can fetch changes into any of your git branches, but by convention, we only apply changes from the subversion repository to the 2.x @@ -109,7 +115,17 @@ never make commits (with `git commit`) directly to this branch. Instead, we always fetch changes from the remote subversion repository. Run the following to fetch changes and apply them as commits to your 2.x branch. - git svn rebase + git svn fetch + git merge git-svn + +The merge won't do anything if there weren't any new changes from svn (so there +is no need to run it if you don't see changes come in from the fetch). If there +were commits to merge, you'll see that your 2.x branch is ahead of origin/2.x by +so many commits (`git status` should report something like "Your branch is ahead +of 'origin/2.x' by 2 commits.") As with any branch, you can see a log of those +commits by with `git log`. For example `git log origin/2.x..HEAD` lists the +commits between my local HEAD and the last commit I have from origin/2.x (the +central 2.x branch). At this point, you can push the commits from your local 2.x branch (the changes that came from svn) to the central git repo: @@ -157,7 +173,7 @@ email addresses. Next, run the following (and substitute the path to the above mentioned authors.txt): - git svn clone -A path/to/authors.txt http://svn.layers.org/trunk/openlayers ol3 + git svn clone -A path/to/authors.txt http://svn.openlayers.org/trunk/openlayers ol3 cd ol3 git remote add origin git@github.com:openlayers/openlayers.git git checkout -b 2.x git-svn diff --git a/readme.md b/readme.md index 66da3d12..561bcb75 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # OpenLayers 3 -This document describes a bit about the working going toward OpenLayers 3.0. +This document describes a bit about the work going toward OpenLayers 3.0. OpenLayers v3 development is taking place in git, with a central repository hosted on [GitHub][1]. To contribute to development, it's important to be @@ -11,8 +11,8 @@ The repository contains a master branch and a 2.x branch. Other branches may come and go as people work on specific features. The master branch should be the closest stable thing to OpenLayers 3.0 (and this readme should get updated before 3.0 is released). However, at any time before the 3.0 release, the -master branch should not be considered stable. The 2.x branch is used to merge -in changes from any ongoing development in the v2 line of development. +master branch should not be considered production ready. The 2.x branch is used +to merge in changes from any ongoing development in the v2 line of development. If you are interested in contributing, please fork the central repository, make changes, and issue a pull request. We may change the process along the way, but diff --git a/tests/BaseTypes.html b/tests/BaseTypes.html index cbb9db73..c17d686c 100644 --- a/tests/BaseTypes.html +++ b/tests/BaseTypes.html @@ -357,7 +357,159 @@ } + function test_Date_toISOString(t) { + t.plan(3); + + var date, str; + + // check valid date + date = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123)); + str = OpenLayers.Date.toISOString(date); + t.eq(str, "2010-11-27T18:19:15.123Z", "valid date"); + + // check zero padding + date = new Date(Date.UTC(2010, 7, 7, 18, 9, 5, 12)); + str = OpenLayers.Date.toISOString(date); + t.eq(str, "2010-08-07T18:09:05.012Z", "zero padding"); + + // check invalid date + date = new Date("foo"); + str = OpenLayers.Date.toISOString(date); + t.eq(str, "Invalid Date", "invalid date"); + + } + + function test_Date_parse(t) { + + t.plan(93); + var cases = { + "2000": { + year: 2000, + month: 0, + date: 1 + }, + "2005-10": { + year: 2005, + month: 9, + date: 1 + }, + "1971-07-23": { + year: 1971, + month: 6, + date: 23 + }, + "1801-11-20T04:30:15Z": { + year: 1801, + month: 10, + date: 20, + hour: 4, + minutes: 30, + seconds: 15 + }, + "1989-06-15T18:30:15.91Z": { + year: 1989, + month: 5, + date: 15, + hour: 18, + minutes: 30, + seconds: 15, + milliseconds: 910 + }, + "1989-06-15T18:30:15.091Z": { + year: 1989, + month: 5, + date: 15, + hour: 18, + minutes: 30, + seconds: 15, + milliseconds: 91 + }, + "1989-06-15T13:30:15.091-05": { + year: 1989, + month: 5, + date: 15, + hour: 18, + minutes: 30, + seconds: 15, + milliseconds: 91 + }, + "2010-08-06T15:21:25-06": { // MDT + year: 2010, + month: 7, + date: 6, + hour: 21, + minutes: 21, + seconds: 25 + }, + "2010-08-07T06:21:25+9": { // JSP + year: 2010, + month: 7, + date: 6, + hour: 21, + minutes: 21, + seconds: 25 + }, + "2010-08-07T02:51:25+05:30": { // IST + year: 2010, + month: 7, + date: 6, + hour: 21, + minutes: 21, + seconds: 25 + }, + "T21:51:25Z": { + hour: 21, + minutes: 51, + seconds: 25 + }, + "T02:51:25+05:30": { // IST + hour: 21, + minutes: 21, + seconds: 25 + }, + "T2:51:25.1234-7": { // lenient + hour: 9, + minutes: 51, + seconds: 25, + milliseconds: 123 + } + }; + + var o, got, exp; + for (var str in cases) { + o = cases[str]; + got = OpenLayers.Date.parse(str); + exp = new Date(Date.UTC(o.year || 0, o.month || 0, o.date || 1, o.hour || 0, o.minutes || 0, o.seconds || 0, o.milliseconds || 0)); + if ("year" in o) { + t.eq(got.getUTCFullYear(), exp.getUTCFullYear(), str + ": correct UTCFullYear"); + t.eq(got.getUTCMonth(), exp.getUTCMonth(), str + ": correct UTCMonth"); + t.eq(got.getUTCDate(), exp.getUTCDate(), str + ": correct UTCDate"); + } else { + t.ok(true, str + ": ECMA doesn't specify how years are handled in time only strings"); + t.ok(true, str + ": ECMA doesn't specify how months are handled in time only strings"); + t.ok(true, str + ": ECMA doesn't specify how days are handled in time only strings"); + } + if ("hour" in o) { + t.eq(got.getUTCHours(), exp.getUTCHours(), str + ": correct UTCHours"); + t.eq(got.getUTCMinutes(), exp.getUTCMinutes(), str + ": correct UTCMinutes"); + t.eq(got.getUTCSeconds(), exp.getUTCSeconds(), str + ": correct UTCSeconds"); + t.eq(got.getUTCMilliseconds(), exp.getUTCMilliseconds(), str + ": correct UTCMilliseconds"); + } else { + t.ok(true, str + ": ECMA doesn't specify how hours are handled in date only strings"); + t.ok(true, str + ": ECMA doesn't specify how minutes are handled in date only strings"); + t.ok(true, str + ": ECMA doesn't specify how seconds are handled in date only strings"); + t.ok(true, str + ": ECMA doesn't specify how milliseconds are handled in date only strings"); + } + } + + // check invalid date parsing + var invalid = OpenLayers.Date.parse("foo"); + t.ok(invalid instanceof Date, "invalid is a date"); + t.ok(isNaN(invalid.getTime()), "invalid has no time"); + + + } diff --git a/tests/BaseTypes/Class.html b/tests/BaseTypes/Class.html index bcf827e8..d2b1e973 100644 --- a/tests/BaseTypes/Class.html +++ b/tests/BaseTypes/Class.html @@ -2,9 +2,6 @@ diff --git a/tests/Control/LayerSwitcher.html b/tests/Control/LayerSwitcher.html index 9c4d2487..e058d6bb 100644 --- a/tests/Control/LayerSwitcher.html +++ b/tests/Control/LayerSwitcher.html @@ -105,7 +105,7 @@ t.ok(true, "redraw called when setting vis"); } map.addControl(control); - var func = myredraw.bind(control); + var func = OpenLayers.Function.bind(myredraw, control); func(); markers.setVisibility(false); t.eq(control.checkRedraw(), true, "check redraw is true after changing layer and not letting redraw happen."); @@ -117,7 +117,7 @@ t.ok(true, "redraw called when setting inRange"); } map.addControl(control); - var func = myredraw.bind(control); + var func = OpenLayers.Function.bind(myredraw, control); func(); markers.inRange = false; t.eq(control.checkRedraw(), true, "check redraw is true after changing layer.inRange and not letting redraw happen."); @@ -130,7 +130,7 @@ } map.addControl(control); - var func = myredraw.bind(control); + var func = OpenLayers.Function.bind(myredraw, control); func(); map.raiseLayer(layer, 1); t.eq(control.checkRedraw(), true, "check redraw is true after changing layer.inRange and not letting redraw happen."); diff --git a/tests/Control/MousePosition.html b/tests/Control/MousePosition.html index 2e895bcc..2858167d 100644 --- a/tests/Control/MousePosition.html +++ b/tests/Control/MousePosition.html @@ -68,6 +68,39 @@ var val = control.formatOutput(lonlat); t.eq(val, 'prefix0.757separator0.374suffix', 'formatOutput correctly formats the mouse position output'); } + function test_deactivate(t) { + t.plan(4); + var map = new OpenLayers.Map('map'); + var layer = new OpenLayers.Layer(null, {isBaseLayer: true}); + map.addLayer(layer); + map.zoomToMaxExtent(); + // Auxiliary function + function trigger(type, x, y) { + map.events.triggerEvent(type, { + xy: new OpenLayers.Pixel(x, y) + }) + }; + + var control = new OpenLayers.Control.MousePosition(); + map.addControl(control); + trigger("mousemove", 0, 0); + + trigger("mousemove", 0, 1); + t.ok(control.div.innerHTML != "", + "Shows the position after add control (with autoActivate) and move"); + control.deactivate(); + t.ok(control.div.innerHTML == "", + "Position is not displayed after deactivate and move"); + trigger("mousemove", 0, 2); + t.ok(control.div.innerHTML == "", + "Position is not displayed after move when deactivate"); + control.activate(); + trigger("mousemove", 0, 3); + t.ok(control.div.innerHTML != "", + "Shows the position after activate and move"); + + map.destroy(); + } diff --git a/tests/Control/MouseToolbar.html b/tests/Control/MouseToolbar.html deleted file mode 100644 index e4799eda..00000000 --- a/tests/Control/MouseToolbar.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - -
- - diff --git a/tests/Control/OverviewMap.html b/tests/Control/OverviewMap.html index e216e79e..3feaa876 100644 --- a/tests/Control/OverviewMap.html +++ b/tests/Control/OverviewMap.html @@ -147,6 +147,32 @@ }); } + function test_initialize_maximized(t) { + t.plan(4); + + control = new OpenLayers.Control.OverviewMap() + map = new OpenLayers.Map('map', { + layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})], + controls: [control] + }); + + t.eq(control.maximized, false, "OverviewMap is not maximized by default"); + t.eq(control.element.style.display, 'none', "OverviewMap.element is not visible"); + map.destroy(); + + control = new OpenLayers.Control.OverviewMap({ + maximized: true + }) + map = new OpenLayers.Map('map', { + layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})], + controls: [control] + }); + t.eq(control.maximized, true, "OverviewMap.maximized is set"); + t.eq(control.element.style.display, '', "OverviewMap.element is visible"); + + map.destroy(); + } + diff --git a/tests/Control/Panel.html b/tests/Control/Panel.html index 88ad431f..59018ae5 100644 --- a/tests/Control/Panel.html +++ b/tests/Control/Panel.html @@ -10,7 +10,7 @@ t.eq( control.displayClass, "olControlPanel", "displayClass is correct" ); } function test_Control_Panel_constructor2 (t) { - t.plan(11); + t.plan(16); var map = new OpenLayers.Map('map'); var toolControl = new OpenLayers.Control.ZoomBox(); var AnotherToolControl = OpenLayers.Class(OpenLayers.Control, { @@ -24,6 +24,11 @@ }); var toggleControl = new ToggleControl(); + var buttonControl = new OpenLayers.Control.Button({ + trigger: function () { + t.ok(true, "trigger function of button is called."); + } + }); var panel = new OpenLayers.Control.Panel( {defaultControl: anotherToolControl}); @@ -36,6 +41,7 @@ panel.addControls([toolControl, anotherToolControl, toggleControl]); t.eq(panel.controls.length, 3, "added three controls to the panel"); + panel.addControls([buttonControl]); panel.redrawsCount = 0; map.addControl(panel); @@ -56,15 +62,23 @@ panel.redrawsCount + " times."); panel.activateControl(toolControl); - t.ok(toolControl.active && !anotherToolControl.active && !toggleControl.active, - "activated one tool control, the other one is inactive and the toggle control also."); + t.ok(toolControl.active && !anotherToolControl.active && !toggleControl.active && !buttonControl.active, + "activated one tool control, the other one is inactive and the toggle & button controls also."); panel.redrawsCount = 0; panel.activateControl(toggleControl); t.ok((panel.redrawsCount > 0),"Redraw called on activated toggle " + panel.redrawsCount + " times."); t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active, - "activated the toggle control, which has no influence on the tool controls."); + "activated the toggle control, which has no influence on the tool & togggle controls."); + panel.activateControl(buttonControl); + t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active, + "activateContol calling for button, which has no influence on the tool & togggle controls."); + t.ok(!buttonControl.active, + "activateContol calling for button, button remains inactive."); + buttonControl.activate(); + t.ok(buttonControl.active && toolControl.active && !anotherToolControl.active && toggleControl.active, + "activated the button control, which has no influence on the tool & togggle controls."); panel.redrawsCount = 0; panel.activateControl(anotherToolControl); @@ -73,6 +87,8 @@ " times."); t.ok(!toolControl.active && anotherToolControl.active && toggleControl.active, "activated the other tool control, the first one is inactive and the toggle control still active."); + t.ok(buttonControl.active, + "activated the other tool control, the button control still active."); } function test_Control_Panel_titles (t) { t.plan(2); @@ -141,6 +157,76 @@ } + + function test_Control_Panel_saveState (t) { + t.plan(11); + var map = new OpenLayers.Map('map'); + + var defaultControl = new OpenLayers.Control(); + var panel = new OpenLayers.Control.Panel({ + defaultControl: defaultControl + }); + panel.addControls([new OpenLayers.Control(), defaultControl]); + map.addControl(panel); + t.eq(defaultControl.active, true, + "After panel activation default control is active."); + t.ok(panel.defaultControl, + "defaultControl not nullified after initial panel activation"); + // activate the 1st control + panel.activateControl(panel.controls[0]); + panel.deactivate(); + t.ok(!panel.controls[0].active && !panel.controls[1].active, + "No controls are active after panel deactivation."); + panel.activate(); + t.eq(panel.controls[0].active, false, + "After panel reactivation first control is inactive."); + t.eq(panel.controls[1].active, true, + "After panel reactivation default control is active again."); + panel.destroy(); + + defaultControl = new OpenLayers.Control(); + panel = new OpenLayers.Control.Panel({ + saveState: true, + defaultControl: defaultControl + }); + panel.addControls([new OpenLayers.Control(), defaultControl]); + map.addControl(panel); + t.eq(defaultControl.active, true, + "After panel activation default control is active."); + t.eq(panel.defaultControl, null, + "defaultControl nullified after initial panel activation"); + // activate the 1st control, which will deactivate the 2nd + panel.activateControl(panel.controls[0]); + t.eq(panel.controls[1].active, false, + "2nd control deactivated with activation of 1st"); + panel.deactivate(); + t.ok(!panel.controls[0].active && !panel.controls[1].active, + "No controls are active after panel deactivation."); + panel.activate(); + t.eq(panel.controls[0].active, true, + "After panel reactivation first control is active."); + t.eq(panel.controls[1].active, false, + "After panel reactivation second control is inactive."); + panel.destroy(); + map.destroy(); + } + + function test_Control_Panel_autoActivate (t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + var controlNoDeactive = new OpenLayers.Control({autoActivate:true}); + var chkDeactivate = function () { + t.ok(false, "Tool control autoActivate:true was deactivated unnecessarily"); + }; + controlNoDeactive.events.on({deactivate: chkDeactivate}); + var panel = new OpenLayers.Control.Panel(); + + map.addControl(panel); + panel.addControls([controlNoDeactive]); + controlNoDeactive.events.un({deactivate: chkDeactivate}); + t.ok(!controlNoDeactive.active, "Tool control autoActivate:true is not active"); + + } diff --git a/tests/Control/SLDSelect.html b/tests/Control/SLDSelect.html index d4d13b0f..2221db79 100644 --- a/tests/Control/SLDSelect.html +++ b/tests/Control/SLDSelect.html @@ -81,7 +81,7 @@ control.events.unregister("selected", this, testEvent); t.eq(map.layers.length, 2, "Selection layer has been created and added to the map"); t.eq(map.layers[1] instanceof OpenLayers.Layer.WMS.Post, true, "A WMS Post layer has been created as the selection layer"); - var expected_sld = 'AAA64defaultdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF00002'; + var expected_sld = 'AAA64defaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF00002'; t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, "SLD generated correctly"); @@ -168,7 +168,7 @@ var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon( new OpenLayers.Geometry.Point(0, 0), 5, 4); control.select(geometry); - var expected_sld = 'KGNAT.VKUNSTWERKdefaultdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF0000KGNAT.LKUNSTWERKdefaultdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF00002KGNAT.PKUNSTWERKdefaultdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327square#FF000010'; + var expected_sld = 'KGNAT.VKUNSTWERKdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF0000KGNAT.LKUNSTWERKdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327#FF00002KGNAT.PKUNSTWERKdefaultgeometry-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327square#FF000010'; t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, "SLD generated correctly"); map.destroy(); diff --git a/tests/Control/WMSGetFeatureInfo.html b/tests/Control/WMSGetFeatureInfo.html index 769b4590..c566f903 100644 --- a/tests/Control/WMSGetFeatureInfo.html +++ b/tests/Control/WMSGetFeatureInfo.html @@ -146,6 +146,26 @@ control.getInfoForHover({xy: xy}); } + function test_nogetfeatureinfo_event(t) { + t.plan(1); + var map = new OpenLayers.Map('map'); + // mock up active control + var control = new OpenLayers.Control.WMSGetFeatureInfo({ + eventListeners: { + nogetfeatureinfo: function(evt) { + t.ok((evt.type == "nogetfeatureinfo"), "nogetfeatureinfo listener gets called when there are no queryable layers"); + } + } + }); + map.addControl(control); + control.activate(); + + // 1 test + mode = "click"; + xy = {x: 50, y: 50}; + control.getInfoForClick({xy: xy}); + } + function test_activate(t) { t.plan(4); var map = new OpenLayers.Map("map"); @@ -350,6 +370,42 @@ map.destroy(); } + + function test_hover(t) { + + t.plan(2); + + var map = new OpenLayers.Map({ + div: "map", + layers: [ + new OpenLayers.Layer.WMS(null, "/dummywms", {layers: "one"}) + ], + center: new OpenLayers.LonLat(0, 0), + zoom: 1 + }); + + var control = new OpenLayers.Control.WMSGetFeatureInfo({ + hover: true + }); + map.addControl(control); + control.activate(); + + // mock up a mousemove + control.getInfoForHover({xy: new OpenLayers.Pixel(10, 10)}); + t.ok(!!control.hoverRequest, "hoverRequest set"); + + // confirm that request is canceled on next move + var called = 0; + control.hoverRequest.abort = function() { + ++called; + }; + control.handler.px = null; + control.handler.mousemove({xy: new OpenLayers.Pixel(20, 20)}); + t.eq(called, 1, "hover request aborted"); + + map.destroy(); + + } function test_drillDown(t) { t.plan(4); diff --git a/tests/Control/WMTSGetFeatureInfo.html b/tests/Control/WMTSGetFeatureInfo.html new file mode 100644 index 00000000..14597d53 --- /dev/null +++ b/tests/Control/WMTSGetFeatureInfo.html @@ -0,0 +1,334 @@ + + + + + + +
+ + diff --git a/tests/Filter/Comparison.html b/tests/Filter/Comparison.html index b7c0cb15..b9505dbb 100644 --- a/tests/Filter/Comparison.html +++ b/tests/Filter/Comparison.html @@ -175,7 +175,117 @@ } } - + + function test_evaluate_feature(t) { + + var cases = [{ + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 999}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 1000}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 4999}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 5000}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 999}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "Foo"}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "foo"}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + matchCase: true, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "foo"}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + property: "prop", + value: "foo" + }), + context: {prop: "FOO"}, + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + matchCase: true, + property: "prop", + value: "foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "FOO"}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + matchCase: false, + property: "prop", + value: "foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "FOO"}), + expect: false + }]; + + t.plan(cases.length); + + var c; + for(var i=0; i143564.081753,6817901.121957 144209.641321,6819104.781451Finistère', + // without boundedBy Box, with Box geometry + '143564.081753,6817901.121957 144209.641321,6819104.781451Finistère', + // without boundedBy, without geometry + 'Finistère', + // with boundedBy Box, with Box geometry + '143564.081753,6817901.121957 144209.641321,6819104.781451143564.081753,6817901.121957 144209.641321,6819104.781451Finistère']; var test_content = ['\n\n \n \n -1254041.389711702250906.9515983529\n -634517.1199908922762236.2940800377\n \n \n \n \n -634517.11999089224,691849.77929356066,0 -653761.64509297756,471181.53429472551,0 -673343.60852865304,250906.9515983529,0 -1088825.734430399,299284.85108220269,0 -1254041.3897117018,324729.27754874947,0 -1235750.4212498858,434167.33911316615,0 -1190777.7803201093,704392.96327195223,0 -1181607.835811228,762236.29408003774,0 -634517.11999089224,691849.77929356066,0\n WY\n \n \n \n\n', ' ' + ' -81.38671875,27.0703125 ' + ' southFlorida ' + - '' + '' ]; var shell_start = ''; diff --git a/tests/Format/KML.html b/tests/Format/KML.html index 8f294e42..018aaeda 100644 --- a/tests/Format/KML.html +++ b/tests/Format/KML.html @@ -217,6 +217,46 @@ }; t.eq(f.read(f.write(feature))[0].attributes.name, feature.style.label, "placemark name from style.label"); } + + function test_extractTracks(t) { + + t.plan(12); + + var xml = new OpenLayers.Format.XML(); + var doc = xml.read(document.getElementById("macnoise.kml").firstChild.nodeValue); + + var format = new OpenLayers.Format.KML({ + extractTracks: true, + trackAttributes: ["speed"] // additional custom attributes + }); + + var features = format.read(doc.documentElement); + t.eq(features.length, 170, "got 170 features"); + + var attr = features[4].attributes; + + // standard track point attributes + t.ok(attr.when instanceof Date, "features have when attribute"); + t.eq(attr.when.getTime(), 1272736815000, "correct time for fifth feature"); + t.eq(attr.altitude, 1006, "altitude parsed"); + t.eq(attr.heading, 230, "heading parsed"); + t.eq(attr.tilt, 0, "tilt parsed"); + t.eq(attr.roll, 0, "roll parsed"); + + // custom track attributes (all features acquire from the placemark) + t.eq(attr.name, "B752", "correct name"); + t.eq(attr.adflag, "A", "correct adflag"); + t.eq(attr.flightid, "DAL2973", "correct flightid"); + + // additional per point attributes (determined by trackAttributes property) + t.eq(attr.speed, "166", "correct speed"); + + var exp = new OpenLayers.Geometry.Point(-93.0753620391713, 44.9879724110872); + exp.z = 1006; + t.geom_eq(features[4].geometry, exp, "correct geometry"); + + } + @@ -299,5 +339,877 @@ + +
+ diff --git a/tests/Format/SLD/v1_0_0.html b/tests/Format/SLD/v1_0_0.html index cfee1720..6cb604b8 100644 --- a/tests/Format/SLD/v1_0_0.html +++ b/tests/Format/SLD/v1_0_0.html @@ -2,6 +2,11 @@ +
+
+
+
+
+
diff --git a/tests/Format/WKT.html b/tests/Format/WKT.html index fdadda8b..a7deee77 100644 --- a/tests/Format/WKT.html +++ b/tests/Format/WKT.html @@ -108,9 +108,9 @@ // test a multipoint t.eq(format.write(multipoint), - "MULTIPOINT(" + points[0].geometry.x + " " + points[0].geometry.y + "," + - points[1].geometry.x + " " + points[1].geometry.y + "," + - points[2].geometry.x + " " + points[2].geometry.y + ")", + "MULTIPOINT((" + points[0].geometry.x + " " + points[0].geometry.y + "),(" + + points[1].geometry.x + " " + points[1].geometry.y + "),(" + + points[2].geometry.x + " " + points[2].geometry.y + "))", "format correctly writes MultiPoint WKT"); // test a linestring diff --git a/tests/Format/WMC.html b/tests/Format/WMC.html index 52e4f662..218d9f65 100644 --- a/tests/Format/WMC.html +++ b/tests/Format/WMC.html @@ -3,11 +3,11 @@ @@ -223,7 +271,7 @@ 1e6 1e6 - 84 -180 + -180 84 256 256 60000 @@ -232,7 +280,7 @@ 2.5e6 2.5e6 - 84 -180 + -180 84 256 256 9000 diff --git a/tests/Format/XML.html b/tests/Format/XML.html index ebd984c9..a85b6fba 100644 --- a/tests/Format/XML.html +++ b/tests/Format/XML.html @@ -167,18 +167,38 @@ } function test_Format_XML_createTextNode(t) { - t.plan(4); + t.plan(10); var format = new OpenLayers.Format.XML(); - var value = Math.random().toString(); - var node = format.createTextNode(value); + var value, node; + + value = "string"; + node = format.createTextNode(value); t.eq(node.nodeType, 3, - "node has correct type"); + "[string] node has correct type"); t.eq(node.nodeName, "#text", - "node has correct name"); - t.eq(node.nodeValue, value, - "node has correct value"); + "[string] node has correct name"); + t.eq(node.nodeValue, "string", + "[string] node has correct value"); + value = 0.42; + node = format.createTextNode(value); + t.eq(node.nodeType, 3, + "[number] node has correct type"); + t.eq(node.nodeName, "#text", + "[number] node has correct name"); + t.eq(node.nodeValue, "0.42", + "[number] node has correct value"); + + value = false; + node = format.createTextNode(value); + t.eq(node.nodeType, 3, + "[boolean] node has correct type"); + t.eq(node.nodeName, "#text", + "[boolean] node has correct name"); + t.eq(node.nodeValue, "false", + "[boolean] node has correct value"); + var doc = format.read(text); if (doc.importNode) { node = doc.importNode(node, true); @@ -595,6 +615,10 @@ description: "value of 0 gets appended as a text node", node: format.createElementNSPlus("foo:bar", {value: 0}), expect: "0" + }, { + description: "value of 0.42 gets appended as a text node", + node: format.createElementNSPlus("foo:bar", {value: 0.42}), + expect: "0.42" }, { description: "value of true gets appended as a text node", node: format.createElementNSPlus("foo:bar", {value: true}), diff --git a/tests/Geometry.html b/tests/Geometry.html index f133061e..c52beffa 100644 --- a/tests/Geometry.html +++ b/tests/Geometry.html @@ -288,7 +288,7 @@ wkt: "POINT(1 2)", geom: new OpenLayers.Geometry.Point(1, 2) }, { - wkt: "MULTIPOINT(3.5 5.6,4.8 10.5)", + wkt: "MULTIPOINT((3.5 5.6),(4.8 10.5))", geom: new OpenLayers.Geometry.MultiPoint([ new OpenLayers.Geometry.Point(3.5, 5.6), new OpenLayers.Geometry.Point(4.8, 10.5) diff --git a/tests/Geometry/Collection.html b/tests/Geometry/Collection.html index a6364a8a..3c195810 100644 --- a/tests/Geometry/Collection.html +++ b/tests/Geometry/Collection.html @@ -250,6 +250,148 @@ t.eq(multipoint.bounds, null, "multipoint component bounds cleared"); } + + function test_getCentroid_pts_only(t) { + t.plan(3); + + coll = new OpenLayers.Geometry.Collection(); + coll.addComponent(new OpenLayers.Geometry.Point(0,0)); + coll.addComponent(new OpenLayers.Geometry.Point(1,1)); + + centroid = coll.getCentroid(true); + t.ok(centroid != null, 'The centroid is not null.'); + t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.'); + t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.'); + + coll.destroy(); + } + + function test_getCentroid_poly_nonrecursive(t) { + t.plan(3); + + coll = new OpenLayers.Geometry.Collection(); + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,1), + new OpenLayers.Geometry.Point(1,1), + new OpenLayers.Geometry.Point(1,0) + ]) + ]) + ); + // performing non-recursive getCentroid means this next polygon + // is excluded from the centroid computation + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(2,2), + new OpenLayers.Geometry.Point(2,3), + new OpenLayers.Geometry.Point(3,3), + new OpenLayers.Geometry.Point(3,2) + ]) + ]) + ); + + centroid = coll.getCentroid(); + t.ok(centroid != null, 'The centroid is not null.'); + t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.'); + t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.'); + + coll.destroy(); + } + + function test_getCentroid_poly_only(t) { + t.plan(3); + + coll = new OpenLayers.Geometry.Collection(); + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,1), + new OpenLayers.Geometry.Point(1,1), + new OpenLayers.Geometry.Point(1,0) + ]) + ]) + ); + + centroid = coll.getCentroid(true); + t.ok(centroid != null, 'The centroid is not null.'); + t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.'); + t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.'); + + coll.destroy(); + } + + function test_getCentroid_poly_and_pts(t) { + t.plan(3); + + coll = new OpenLayers.Geometry.Collection(); + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,1), + new OpenLayers.Geometry.Point(1,1), + new OpenLayers.Geometry.Point(1,0) + ]) + ]) + ); + + // since the polygon above has an area of 1 and these + // points have an area of 0, they should not change the centroid + coll.addComponent( new OpenLayers.Geometry.Point(2,2) ); + coll.addComponent( new OpenLayers.Geometry.Point(4,4) ); + + centroid = coll.getCentroid(true); + t.ok(centroid != null, 'The centroid is not null.'); + t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.'); + t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.'); + + coll.destroy(); + } + + function test_getCentroid_poly_big_and_small(t) { + t.plan(3); + + coll = new OpenLayers.Geometry.Collection(); + // polygon w/area=1, centroid=0.5,0.5 + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(0,0), + new OpenLayers.Geometry.Point(0,1), + new OpenLayers.Geometry.Point(1,1), + new OpenLayers.Geometry.Point(1,0) + ]) + ]) + ); + + // since the polygon above has an area of 1 and this + // polygon has an area of 4, the center is weighted 20% toward + // the first polygon + + // polygon w/area=4, centroid=5.5,5.5 + coll.addComponent( + new OpenLayers.Geometry.Polygon([ + new OpenLayers.Geometry.LinearRing([ + new OpenLayers.Geometry.Point(4.5,-0.5), + new OpenLayers.Geometry.Point(4.5,1.5), + new OpenLayers.Geometry.Point(6.5,1.5), + new OpenLayers.Geometry.Point(6.5,-0.5) + ]) + ]) + ); + + centroid = coll.getCentroid(true); + t.ok(centroid != null, 'The centroid is not null.'); + t.eq(centroid.x, 4.5, 'The centroid x coordinate is good.'); + t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.'); + + coll.destroy(); + } + function test_Collection_destroy(t) { t.plan( 3 ); diff --git a/tests/Handler/Drag.html b/tests/Handler/Drag.html index 4f93679c..581ffcca 100644 --- a/tests/Handler/Drag.html +++ b/tests/Handler/Drag.html @@ -289,7 +289,7 @@ } function test_Handler_Drag_submethods(t) { - t.plan(4); + t.plan(8); var map = new OpenLayers.Map('map', {controls: []}); @@ -300,6 +300,11 @@ var handler = new OpenLayers.Handler.Drag(control, {}); // set test events var events = ["down", "move", "up", "out"]; + var onselect = { + "move": OpenLayers.Function.False, + "up": OpenLayers.Function.False, + "out": OpenLayers.Function.True + } var testEvents = {}; var type, px; for(var i=0; i - \ No newline at end of file + +
+ + diff --git a/tests/Layer/Google.html b/tests/Layer/Google.html index 2f205260..81d34f99 100644 --- a/tests/Layer/Google.html +++ b/tests/Layer/Google.html @@ -196,9 +196,13 @@ { controls: [] , 'numZoomLevels':20}); var satellite = new OpenLayers.Layer.Google( "Google Satellite" , {type: G_SATELLITE_MAP, 'maxZoomLevel':18} ); - var layer = new OpenLayers.Layer.WMS.Untiled( "OpenLayers WMS", - "http://labs.metacarta.com/wms/vmap0", {layers: 'basic', 'transparent':true}, - {isBaseLayer: false} ); + var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", "http://labs.metacarta.com/wms/vmap0", { + layers: 'basic', + transparent: true + }, { + isBaseLayer: false, + singleTile: true + }); map.addLayers([satellite, layer]); map.setCenter(new OpenLayers.LonLat(10.205188,48.857593), 5); diff --git a/tests/Layer/Google/v3.html b/tests/Layer/Google/v3.html new file mode 100644 index 00000000..6d5df4ed --- /dev/null +++ b/tests/Layer/Google/v3.html @@ -0,0 +1,364 @@ + + + + + + + +
+ + \ No newline at end of file diff --git a/tests/Layer/Grid.html b/tests/Layer/Grid.html index e5c1ed51..9cfc1de8 100644 --- a/tests/Layer/Grid.html +++ b/tests/Layer/Grid.html @@ -100,7 +100,7 @@ function test_Layer_Grid_getTilesBounds(t) { - t.plan( 4 ); + t.plan( 3 ); layer = new OpenLayers.Layer.WMS(name, url, params); @@ -116,10 +116,6 @@ t.ok( bounds.equals(testBounds), "getTilesBounds() returns correct bounds"); - var bounds = layer.getGridBounds(); - - t.ok( bounds.equals(testBounds), "getGridBounds() wrapper works the same as getTilesBounds."); - //no tiles layer.grid = []; bounds = layer.getTilesBounds(); diff --git a/tests/Layer/Image.html b/tests/Layer/Image.html index 3925aabf..a5198590 100644 --- a/tests/Layer/Image.html +++ b/tests/Layer/Image.html @@ -7,7 +7,7 @@ function test_Layer_Image_constructor (t) { t.plan( 13 ); - var options = { chicken: 151, foo: "bar", projection: "none" }; + var options = { chicken: 151, foo: "bar", projection: "EPSG:4326" }; var layer = new OpenLayers.Layer.Image('Test Layer', 'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif', new OpenLayers.Bounds(-180, -88.759, 180, 88.759), @@ -18,7 +18,7 @@ t.eq( layer.name, "Test Layer", "layer.name is correct" ); t.ok( layer.id != null, "Layer is given an id"); - t.eq( layer.projection, "none", "default layer projection correctly set"); + t.eq( layer.projection.getCode(), "EPSG:4326", "default layer projection correctly set"); t.ok( ((layer.chicken == 151) && (layer.foo == "bar")), "layer.options correctly set to Layer Object" ); t.ok( ((layer.options["chicken"] == 151) && (layer.options["foo"] == "bar")), "layer.options correctly backed up" ); diff --git a/tests/Layer/MapServer.html b/tests/Layer/MapServer.html index 25eb1e8d..e5b7b371 100644 --- a/tests/Layer/MapServer.html +++ b/tests/Layer/MapServer.html @@ -296,174 +296,6 @@ map.destroy(); } - // Untiled tests - - var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); - var layer; - - var name = 'Test Layer'; - var url = "http://labs.metacarta.com/cgi-bin/mapserv"; - var params = { map: '/mapdata/vmap_wms.map', - layers: 'basic'}; - - function test_Layer_MapServer_Untiled_constructor (t) { - t.plan( 4 ); - - var url = "http://labs.metacarta.com/cgi-bin/mapserv"; - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params); - t.ok( layer instanceof OpenLayers.Layer.MapServer.Untiled, "new OpenLayers.Layer.MapServer returns object" ); - t.eq( layer.url, "http://labs.metacarta.com/cgi-bin/mapserv", "layer.url is correct (HTTPRequest inited)" ); - - t.eq( layer.params.mode, "map", "default mode param correctly copied"); - t.eq( layer.params.map_imagetype, "png", "default imagetype correctly copied"); - - - } - - function test_Layer_MapServer_Untiled_clone (t) { - t.plan(3); - - var url = "http://labs.metacarta.com/cgi-bin/mapserv"; - var map = new OpenLayers.Map('map', {}); - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params); - map.addLayer(layer); - - var clone = layer.clone(); - layer.tile = [[1,2],[3,4]]; - - t.ok( clone.tile != layer.tile, "clone does not copy tile"); - - layer.ratio += 1; - - t.eq( clone.ratio, 1.5, "changing layer.ratio does not change clone.ratio -- a fresh copy was made, not just copied reference"); - - t.eq( clone.alpha, layer.alpha, "alpha copied correctly"); - - layer.tile = null; - map.destroy(); - } - - function test_Layer_MapServer_Untiled_isBaseLayer(t) { - t.plan(3); - - var url = "http://labs.metacarta.com/cgi-bin/mapserv"; - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params); - t.ok( layer.isBaseLayer, "baselayer is true by default"); - - var newParams = OpenLayers.Util.extend({}, params); - newParams.transparent = "true"; - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, newParams); - t.ok( !layer.isBaseLayer, "baselayer is false when transparent is set to true"); - - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params, {isBaseLayer: false}); - t.ok( !layer.isBaseLayer, "baselayer is false when option is set to false" ); - } - - function test_Layer_MapServer_Untiled_mergeNewParams (t) { - t.plan( 5 ); - - var map = new OpenLayers.Map("map"); - var url = "http://labs.metacarta.com/cgi-bin/mapserv"; - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params); - - var newParams = { layers: 'sooper', - chickpeas: 'image/png'}; - - map.addLayer(layer); - map.zoomToMaxExtent(); - t.ok( !layer.grid[0][0].url.match("chickpeas"), "chickpeas is not in URL of first tile in grid" ); - - layer.mergeNewParams(newParams); - - t.eq( layer.params.layers, "sooper", "mergeNewParams() overwrites well"); - t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() adds well"); - t.ok( layer.grid[0][0].url.match("chickpeas"), "chickpeas is in URL of first tile in grid" ); - - newParams.chickpeas = 151; - - t.eq( layer.params.chickpeas, "image/png", "mergeNewParams() makes clean copy of hashtable"); - map.destroy(); - } - - function test_Layer_MapServer_Untiled_getFullRequestString (t) { - - - t.plan( 1 ); - var map = new OpenLayers.Map('map'); - tUrl = "http://labs.metacarta.com/cgi-bin/mapserv"; - tParams = { layers: 'basic', - format: 'png'}; - var tLayer = new OpenLayers.Layer.MapServer.Untiled(name, tUrl, tParams); - map.addLayer(tLayer); - str = tLayer.getFullRequestString(); - var tParams = { - layers: 'basic', - format: 'png', - mode: 'map', - map_imagetype: 'png' - }; - - var sStr = tUrl + "?" + OpenLayers.Util.getParameterString(tParams); - sStr = sStr.replace(/,/g, "+"); - - t.eq(str, sStr , "getFullRequestString() works"); - map.destroy(); - - } - - function test_Layer_MapServer_Untiled_setOpacity (t) { - t.plan( 4 ); - - var map = new OpenLayers.Map('map'); - map.projection = "xx"; - tUrl = "http://labs.metacarta.com/cgi-bin/mapserv"; - tParams = { layers: 'basic', - format: 'image/png'}; - tOptions = { 'opacity': '0.5' }; - var tLayer = new OpenLayers.Layer.MapServer.Untiled(name, tUrl, tParams, tOptions); - map.addLayer(tLayer); - map.zoomToMaxExtent(); - t.eq(tLayer.opacity, "0.5", "Opacity is set correctly"); - t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); - tLayer.setOpacity("0.6"); - t.eq(tLayer.opacity, "0.6", "setOpacity works properly"); - t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); - map.destroy(); - - } - - // DEPRECATED -- REMOVE IN 3.0 - function test_Layer_Untiled_MapServer(t) { - t.plan(1); - - var layer = new OpenLayers.Layer.MapServer.Untiled(); - - var clone = layer.clone(); - - t.ok(clone.singleTile, "regression test: clone works. this is for #1013"); - } - - function test_Layer_MapServer_Untiled_destroy (t) { - - t.plan( 1 ); - - var map = new OpenLayers.Map('map'); - layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params); - map.addLayer(layer); - - map.setCenter(new OpenLayers.LonLat(0,0), 5); - - //grab a reference to one of the tiles - var tile = layer.tile; - - layer.destroy(); - - // checks to make sure superclass (grid) destroy() was called - - t.ok( layer.tile == null, "tile set to null"); - map.destroy(); - } - diff --git a/tests/Layer/MultiMap.html b/tests/Layer/MultiMap.html index 7de9eda8..4c9a6191 100644 --- a/tests/Layer/MultiMap.html +++ b/tests/Layer/MultiMap.html @@ -1,6 +1,7 @@ - + + - - - -
- - diff --git a/tests/Layer/WMS.html b/tests/Layer/WMS.html index 7b2de35e..b454cb9f 100644 --- a/tests/Layer/WMS.html +++ b/tests/Layer/WMS.html @@ -367,17 +367,6 @@ } - // DEPRECATED -- REMOVE IN 3.0 - function test_Layer_Untiled_WMS(t) { - t.plan(1); - - var layer = new OpenLayers.Layer.WMS.Untiled(); - - var clone = layer.clone(); - - t.ok(clone.singleTile, "regression test: clone works. this is for #1013"); - } - function test_Layer_WMS_destroy (t) { t.plan( 1 ); @@ -400,7 +389,7 @@ function test_Layer_WMS_v13(t) { - t.plan(5); + t.plan(6); var lon = 5; var lat = 40; @@ -468,16 +457,19 @@ var url = layer.getURL(map.getExtent()); var params = url.split("&"); - var bbox; + var bbox, exceptions; for (var i=0, len=params.length; i diff --git a/tests/Map.html b/tests/Map.html index e2a2dddc..dfeef22e 100644 --- a/tests/Map.html +++ b/tests/Map.html @@ -83,9 +83,9 @@ function test_Map_setOptions(t) { t.plan(2); map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)}); - map.setOptions({theme: 'foo'}); + map.setOptions({projection: 'EPSG:900913'}); - t.eq(map.theme, 'foo', "theme is correctly set by setOptions"); + t.eq(map.projection, 'EPSG:900913', "projection is correctly set by setOptions"); t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)), "maxExtent is correct after calling setOptions"); @@ -128,10 +128,10 @@ function test_Map_options(t) { t.plan(3); - map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'}); + map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, projection: 'EPSG:900913'}); t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" ); t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" ); - t.eq( map.theme, 'foo', "map theme set correctly." ); + t.eq( map.projection, 'EPSG:900913', "map projection set correctly." ); map.destroy(); } @@ -652,7 +652,7 @@ function test_Map_double_addLayer(t) { t.plan( 1 ); - map = new OpenLayers.Map($('map')); + map = new OpenLayers.Map('map'); layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'} @@ -855,72 +855,6 @@ map.destroy(); } - function test_Map_defaultTheme(t) { - t.plan(5); - - var links = document.getElementsByTagName('link'); - map = new OpenLayers.Map('map'); - var gotNodes = 0; - var themeNode = null; - for(var i=0; i + + + + + +
+ + \ No newline at end of file diff --git a/tests/Style2.html b/tests/Style2.html new file mode 100644 index 00000000..9127f336 --- /dev/null +++ b/tests/Style2.html @@ -0,0 +1,56 @@ + + + + + + + diff --git a/tests/Symbolizer.html b/tests/Symbolizer.html new file mode 100644 index 00000000..5f51e91c --- /dev/null +++ b/tests/Symbolizer.html @@ -0,0 +1,31 @@ + + + + + + + diff --git a/tests/Symbolizer/Line.html b/tests/Symbolizer/Line.html new file mode 100644 index 00000000..ed321f18 --- /dev/null +++ b/tests/Symbolizer/Line.html @@ -0,0 +1,32 @@ + + + + + + + diff --git a/tests/Symbolizer/Point.html b/tests/Symbolizer/Point.html new file mode 100644 index 00000000..e308191f --- /dev/null +++ b/tests/Symbolizer/Point.html @@ -0,0 +1,32 @@ + + + + + + + diff --git a/tests/Symbolizer/Polygon.html b/tests/Symbolizer/Polygon.html new file mode 100644 index 00000000..84dc03aa --- /dev/null +++ b/tests/Symbolizer/Polygon.html @@ -0,0 +1,32 @@ + + + + + + + diff --git a/tests/Symbolizer/Raster.html b/tests/Symbolizer/Raster.html new file mode 100644 index 00000000..ff4bb045 --- /dev/null +++ b/tests/Symbolizer/Raster.html @@ -0,0 +1,32 @@ + + + + + + + diff --git a/tests/Symbolizer/Text.html b/tests/Symbolizer/Text.html new file mode 100644 index 00000000..482afb5b --- /dev/null +++ b/tests/Symbolizer/Text.html @@ -0,0 +1,32 @@ + + + + + + + diff --git a/tests/Util.html b/tests/Util.html index a79ff2ea..b04c4c36 100644 --- a/tests/Util.html +++ b/tests/Util.html @@ -1,9 +1,5 @@ -
  • Layer/PointTrack.html
  • Layer/SphericalMercator.html
  • Layer/Text.html
  • @@ -143,7 +145,6 @@
  • Layer/TMS.html
  • Layer/Vector.html
  • Layer/Vector/RootContainer.html
  • -
  • Layer/WFS.html
  • Layer/WMS.html
  • Layer/WMS/Post.html
  • Layer/WMTS.html
  • @@ -176,12 +177,20 @@
  • Strategy.html
  • Strategy/BBOX.html
  • Strategy/Cluster.html
  • +
  • Strategy/Filter.html
  • Strategy/Fixed.html
  • Strategy/Paging.html
  • Strategy/Save.html
  • Strategy/Refresh.html
  • Style.html
  • +
  • Style2.html
  • StyleMap.html
  • +
  • Symbolizer.html
  • +
  • Symbolizer/Line.html
  • +
  • Symbolizer/Point.html
  • +
  • Symbolizer/Polygon.html
  • +
  • Symbolizer/Raster.html
  • +
  • Symbolizer/Text.html
  • Tile.html
  • Tile/Image.html
  • Tile/Image/IFrame.html
  • diff --git a/tools/update_dev_dir.sh b/tools/update_dev_dir.sh index 7ca6e108..532ee910 100755 --- a/tools/update_dev_dir.sh +++ b/tools/update_dev_dir.sh @@ -2,10 +2,10 @@ # Used to update http://openlayers.org/dev/ -svn up /www/openlayers/docs/dev; +svn up /osgeo/openlayers/docs/dev; # Get current 'Last Changed Rev' -REV=`svn info /www/openlayers/docs/dev/ | grep 'Last Changed Rev' | awk '{print $4}'` +REV=`svn info /osgeo/openlayers/docs/dev/ | grep 'Revision' | awk '{print $2}'` # Get the last svn rev touch /tmp/ol_svn_rev @@ -14,32 +14,33 @@ OLD_REV="o`cat /tmp/ol_svn_rev`" # If they're not equal, do some work. if [ ! o$REV = $OLD_REV ]; then - cd /www/openlayers/docs/dev/tools/ + cd /osgeo/openlayers/docs/dev/tools/ python exampleparser.py - cd /www/openlayers/docs/dev/build + cd /osgeo/openlayers/docs/dev/build ./build.py cp OpenLayers.js .. cd .. sed -i -e 's!../lib/OpenLayers.js!../OpenLayers.js!' examples/*.html - perl /home/crschmidt/NaturalDocs -i /www/openlayers/docs/dev/lib -o HTML /www/openlayers/dev/apidocs -p /www/openlayers/docs/dev/apidoc_config -s Default OL >/dev/null - perl /home/crschmidt/NaturalDocs -i /www/openlayers/docs/dev/lib -o HTML /www/openlayers/dev/docs -p /www/openlayers/docs/dev/doc_config -s Default OL >/dev/null - + naturaldocs -i /osgeo/openlayers/docs/dev/lib -o HTML /osgeo/openlayers/dev/apidocs -p /osgeo/openlayers/docs/dev/apidoc_config -s Default OL >/dev/null + naturaldocs -i /osgeo/openlayers/docs/dev/lib -o HTML /osgeo/openlayers/dev/docs -p /osgeo/openlayers/docs/dev/doc_config -s Default OL >/dev/null + + svn up /osgeo/openlayers/dev/sandbox/ # Record the revision echo -n $REV > /tmp/ol_svn_rev fi -svn up /www/openlayers/documentation-checkout -REV=`svn info /www/openlayers/documentation-checkout | grep 'Last Changed Rev' | awk '{print $4}'` +svn up /osgeo/openlayers/documentation-checkout +REV=`svn info /osgeo/openlayers/documentation-checkout | grep 'Last Changed Rev' | awk '{print $4}'` # Get the last svn rev touch /tmp/ol_doc_rev OLD_REV="o`cat /tmp/ol_doc_rev`" # If they're not equal, do some work. if [ ! o$REV = $OLD_REV ]; then - cd /www/openlayers/documentation-checkout + cd /osgeo/openlayers/documentation-checkout make html > /dev/null - cp -r _build/html/* /www/openlayers/documentation + cp -r _build/html/* /osgeo/openlayers/documentation echo -n $REV > /tmp/ol_doc_rev fi