diff --git a/.gitignore b/.gitignore index 66d8c7908f..7ec33e4db6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,18 @@ -/build/OpenLayers.js -/tools/closure-compiler.jar -/tools/*.pyc /apidoc_config/Data/ +/bin/plovr*.jar +/build/OpenLayers.js +/build/ol.js +/build/ol3.js +/build/ol3-compiled.js +/build/webgl-debug.js +/demos/*/advanced-optimizations.* +/demos/*/build.html +/demos/*/debug.html +/demos/*/simple-optimizations.* /doc/apidocs/ /examples/example-list.js /examples/example-list.xml -/bin/plovr.jar -/jsdoc/ \ No newline at end of file +/jsdoc/ +/proj4js-combined.js +/tools/*.pyc +/tools/closure-compiler.jar diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..c335685327 --- /dev/null +++ b/Makefile @@ -0,0 +1,142 @@ +PLOVR_JAR=bin/plovr-4b3caf2b7d84.jar +SRC_OL = $(shell find src/ol -name \*.js) +SRC_OL3 = $(shell find externs src/ol3 -name \*.js) +TARGETS = $(shell find demos -name advanced-optimizations.js -o -name simple-optimizations.js) +comma := , +empty := +space := $(empty) $(empty) + +.PHONY: all +all: build demos + +.PHONY: build +build: build/ol.js build/ol3-compiled.js build/webgl-debug.js + +build/ol.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + build/ol.json src/ol/ol.js + java -jar $(PLOVR_JAR) build build/ol.json >$@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +build/ol3-compiled.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + build/ol3.json build/ol3.js + java -jar $(PLOVR_JAR) build build/ol3.json >$@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +build/ol3.js: $(SRC_OL3) + ( echo "goog.require('goog.dom');" ; find src/ol3 -name \*.js | xargs grep -rh ^goog.provide | sort | uniq | sed -e 's/provide/require/g' ) > $@ + +.PHONY: demos +demos: demos/api1 demos/proj4js demos/side-by-side demos/two-layers + +.PHONY: demos/api1 +demos/api1: \ + build/ol.js \ + demos/api1/build.html \ + demos/api1/debug.html + +demos/api1/build.html: demos/api1/index.html.in + sed -e 's|@SRC@|../../build/ol.js|' $< > $@ + +demos/api1/debug.html: demos/api1/index.html.in + sed -e 's|@SRC@|http://localhost:9810/compile?id=ol|' $< > $@ + +.PHONY: demos/proj4js +demos/proj4js: \ + build/ol.js \ + demos/proj4js/build.html \ + demos/proj4js/debug.html + +demos/proj4js/build.html: demos/proj4js/index.html.in + sed -e 's|@SRC@|../../build/ol.js|' $< > $@ + +demos/proj4js/debug.html: demos/proj4js/index.html.in + sed -e 's|@SRC@|http://localhost:9810/compile?id=ol|' $< > $@ + +.PHONY: demos/side-by-side +demos/side-by-side: \ + demos/side-by-side/advanced-optimizations.html \ + demos/side-by-side/advanced-optimizations.js \ + demos/side-by-side/debug.html \ + demos/side-by-side/simple-optimizations.html \ + demos/side-by-side/simple-optimizations.js + +demos/side-by-side/advanced-optimizations.html: demos/side-by-side/index.html.in + sed -e 's|@SRC@|advanced-optimizations.js|' $< > $@ + +demos/side-by-side/advanced-optimizations.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + demos/side-by-side/side-by-side.json demos/side-by-side/side-by-side.js + java -jar $(PLOVR_JAR) build demos/side-by-side/side-by-side.json >$@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +demos/side-by-side/debug.html: demos/side-by-side/index.html.in + sed -e 's|@SRC@|http://localhost:9810/compile?id=demo-side-by-side|' $< > $@ + +demos/side-by-side/simple-optimizations.html: demos/side-by-side/index.html.in + sed -e 's|@SRC@|simple-optimizations.js|' $< > $@ + +# FIXME invoke plovr directly, rather than assuming that the server is running +demos/side-by-side/simple-optimizations.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + demos/side-by-side/side-by-side.json demos/side-by-side/side-by-side.js + curl 'http://localhost:9810/compile?id=demo-side-by-side&mode=SIMPLE' > $@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +.PHONY: demos/two-layers +demos/two-layers: \ + demos/two-layers/advanced-optimizations.html \ + demos/two-layers/advanced-optimizations.js \ + demos/two-layers/debug.html \ + demos/two-layers/simple-optimizations.html \ + demos/two-layers/simple-optimizations.js + +demos/two-layers/advanced-optimizations.html: demos/two-layers/index.html.in + sed -e 's|@SRC@|advanced-optimizations.js|' $< > $@ + +demos/two-layers/advanced-optimizations.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + demos/two-layers/two-layers.json demos/two-layers/two-layers.js + java -jar $(PLOVR_JAR) build demos/two-layers/two-layers.json >$@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +demos/two-layers/debug.html: demos/two-layers/index.html.in + sed -e 's|@SRC@|http://localhost:9810/compile?id=demo-two-layers|' $< > $@ + +demos/two-layers/simple-optimizations.html: demos/two-layers/index.html.in + sed -e 's|@SRC@|simple-optimizations.js|' $< > $@ + +# FIXME invoke plovr directly, rather than assuming that the server is running +demos/two-layers/simple-optimizations.js: $(PLOVR_JAR) $(SRC_OL3) base.json \ + demos/two-layers/two-layers.json demos/two-layers/two-layers.js + curl 'http://localhost:9810/compile?id=demo-two-layers&mode=SIMPLE' > $@ + @echo $@ "uncompressed:" $$(wc -c <$@) bytes + @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes + +.PHONY: serve +serve: $(PLOVR_JAR) + java -jar $(PLOVR_JAR) serve build/ol.json build/ol3.json demos/*/*.json + +.PHONY: lint +lint: + gjslint --strict --limited_doc_files=$(subst $(space),$(comma),$(shell find externs -name \*.js)) $(SRC_OL3) $(SRC_OL) $(filter-out $(TARGETS),$(shell find demos -name \*.js)) + +build/webgl-debug.js: + curl https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/debug/webgl-debug.js > $@ + +$(PLOVR_JAR): + curl http://plovr.googlecode.com/files/$(notdir $@) > $@ + +clean: + rm -f build/all.js + rm -f build/ol.js + rm -f build/ol3.js + rm -f build/ol3-compiled.js + rm -f demos/*/*.html + rm -f demos/*/advanced-optimizations.* + rm -f demos/*/simple-optimizations.* + +reallyclean: clean + rm -f $(PLOVR_JAR) + rm -f build/webgl-debug.js diff --git a/api.json b/api.json deleted file mode 100644 index 7bd07e492e..0000000000 --- a/api.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "id": "api", - - "output-file": "api.js", - - "output-wrapper": [ - "// Copyright 2012 ...\n", - "(function(){%output%})();" - ], - - "inputs": "src/ol.export.js", - "paths": [ - "src" - ], - - "define": { - // "goog.dom.ASSUME_STANDARDS_MODE": true, - // "goog.userAgent.ASSUME_MOBILE_WEBKIT": true, - "goog.DEBUG": false, - "ol.API" : true - }, - - "mode": "ADVANCED", - "level": "VERBOSE", - // "pretty-print": true, - // "debug": true, - - // "experimental-compiler-options": { - // "generateExports": true - // }, - - - "checks": { - // acceptable values are "ERROR", "WARNING", and "OFF" - "accessControls": "WARNING", - "visibility": "WARNING", - "checkTypes": "WARNING", - "checkRegExp": "WARNING", - "checkVars": "WARNING", - "deprecated": "WARNING", - "fileoverviewTags": "WARNING", - "invalidCasts": "WARNING", - "missingProperties": "WARNING", - "nonStandardJsDocs": "WARNING", - "undefinedVars": "WARNING" - }, - - "jsdoc-html-output-path": "jsdoc" -} diff --git a/base.json b/base.json new file mode 100644 index 0000000000..e4d98e1efa --- /dev/null +++ b/base.json @@ -0,0 +1,37 @@ +{ + + "checks": { + "accessControls": "ERROR", + "visibility": "ERROR", + "checkTypes": "ERROR", + "checkRegExp": "ERROR", + "checkVars": "ERROR", + "deprecated": "ERROR", + "fileoverviewTags": "ERROR", + "invalidCasts": "ERROR", + "missingProperties": "ERROR", + "nonStandardJsDocs": "ERROR", + "undefinedVars": "ERROR" + }, + + "define": { + "goog.dom.ASSUME_STANDARDS_MODE": true, + "goog.DEBUG": false + }, + + "externs": [ + "externs/bingmaps.js", + "externs/proj4js.js", + "externs/tilejson.js", + "externs/webgl-debug.js" + ], + + "level": "VERBOSE", + + "mode": "ADVANCED", + + "paths": "src", + + "treat-warnings-as-errors": true + +} diff --git a/bin/build.xml b/bin/build.xml index 5c51c4a784..c70e948a9a 100644 --- a/bin/build.xml +++ b/bin/build.xml @@ -6,7 +6,8 @@ - + + @@ -25,7 +26,7 @@ - diff --git a/build/ol.json b/build/ol.json new file mode 100644 index 0000000000..935a6aac49 --- /dev/null +++ b/build/ol.json @@ -0,0 +1,9 @@ +{ + + "id": "ol", + + "inherits": "../base.json", + + "inputs": "src/ol/ol.js" + +} diff --git a/build/ol3.json b/build/ol3.json new file mode 100644 index 0000000000..1a392513a3 --- /dev/null +++ b/build/ol3.json @@ -0,0 +1,9 @@ +{ + + "id": "ol3", + + "inherits": "../base.json", + + "inputs": "build/ol3.js" + +} diff --git a/demo/hello-api.html b/demo/hello-api.html deleted file mode 100644 index e0da39a20e..0000000000 --- a/demo/hello-api.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - OL3 Hello World - - - - - - - -
- - diff --git a/demo/hello-compiled.html b/demo/hello-compiled.html deleted file mode 100644 index b50bd6b8f5..0000000000 --- a/demo/hello-compiled.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - OL3 Hello World - - - - - -
- - \ No newline at end of file diff --git a/demo/hello-compiled.json b/demo/hello-compiled.json deleted file mode 100644 index 5cab96f3ea..0000000000 --- a/demo/hello-compiled.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "id": "hello", - - "output-file": "hello-compiled.js", - - "inputs": [ - "hello.js", - "../src/ol.js" - ], - "paths": [ - "../src" - ], - - "define": { - // "goog.dom.ASSUME_STANDARDS_MODE": true, - "goog.DEBUG": false - }, - - "mode": "ADVANCED", - "level": "VERBOSE", - // "pretty-print": true, - // "debug": true, - - // "experimental-compiler-options": { - // "generateExports": true - // }, - - "checks": { - // acceptable values are "ERROR", "WARNING", and "OFF" - "accessControls": "WARNING", - "visibility": "WARNING", - "checkTypes": "WARNING", - "checkRegExp": "WARNING", - "checkVars": "WARNING", - "deprecated": "WARNING", - "fileoverviewTags": "WARNING", - "invalidCasts": "WARNING", - "missingProperties": "WARNING", - "nonStandardJsDocs": "WARNING", - "undefinedVars": "WARNING" - } -} diff --git a/demo/hello-epi-compiled.json b/demo/hello-epi-compiled.json deleted file mode 100644 index ac42ce4866..0000000000 --- a/demo/hello-epi-compiled.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "id": "hello-epi", - - "output-file": "hello-epi-compiled.js", - - "inputs": [ - "hello-epi.js" - ], - "paths": [ - "../src" - ], - - "define": { - // "goog.dom.ASSUME_STANDARDS_MODE": true, - "goog.DEBUG": false - }, - - "mode": "ADVANCED", - "level": "VERBOSE", - // "pretty-print": true, - // "debug": true, - - // "experimental-compiler-options": { - // "generateExports": true - // }, - - - "checks": { - // acceptable values are "ERROR", "WARNING", and "OFF" - "accessControls": "WARNING", - "visibility": "WARNING", - "checkTypes": "WARNING", - "checkRegExp": "WARNING", - "checkVars": "WARNING", - "deprecated": "WARNING", - "fileoverviewTags": "WARNING", - "invalidCasts": "WARNING", - "missingProperties": "WARNING", - "nonStandardJsDocs": "WARNING", - "undefinedVars": "WARNING" - } -} diff --git a/demo/hello-epi.js b/demo/hello-epi.js deleted file mode 100644 index 2b6ba9467f..0000000000 --- a/demo/hello-epi.js +++ /dev/null @@ -1,16 +0,0 @@ -/* This is a code which is going to be compiled together with the library */ - -goog.require('ol.Map'); -goog.require('ol.layer.OSM'); -goog.require('ol.Loc'); - -goog.require('goog.dom'); - -function init() { - var map = new ol.Map(); - map.setContainer(goog.dom.getElement('map')); - map.setLayers( [ new ol.layer.OSM() ] ); - map.setCenter( new ol.Loc(45, 5)); - map.setZoom(10); -} -window['init'] = init; diff --git a/demo/hello.js b/demo/hello.js deleted file mode 100644 index 90cfcae4e1..0000000000 --- a/demo/hello.js +++ /dev/null @@ -1,10 +0,0 @@ -/* This is a code which is going to be compiled together with the library */ - -function init() { - var map = ol.map() - .renderTo('map') - .layers([ol.layer.osm()]) - .center([45, 5]) - .zoom(10); -} -window['init'] = init; diff --git a/demo/loader.js b/demo/loader.js deleted file mode 100644 index 8b01bc2322..0000000000 --- a/demo/loader.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - Adds the plovr generated script to the document. - */ -(function() { - var url = "http://" + window.location.hostname + ":9810/compile?id=ol"; - document.write(""); -})(); diff --git a/demo/map.html b/demo/map.html deleted file mode 100644 index 0374e68fa1..0000000000 --- a/demo/map.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - OL3 Map - - - - - - -
- - diff --git a/demo/map.js b/demo/map.js deleted file mode 100644 index c5ea52311c..0000000000 --- a/demo/map.js +++ /dev/null @@ -1,6 +0,0 @@ -var map = ol.map({ - renderTo: 'map', - layers: [ol.layer.osm()], - center: [0, 0], - zoom: 1 -}); diff --git a/demo/map.json b/demo/map.json deleted file mode 100644 index 7725caf2bf..0000000000 --- a/demo/map.json +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Build configuration for the map.js example. Use following syntax: - * - * ol build map.json - * - * The output will be named map-compiled.js. - */ - -{ - "id": "hello", - - "output-file": "map-compiled.js", - - "inputs": ["../src/ol.js", "map.js"], - - "paths": ["../src"], - - "define": { - "goog.DEBUG": false - }, - - "mode": "ADVANCED", - "level": "VERBOSE", - - // acceptable values are "ERROR", "WARNING", and "OFF" - "checks": { - "accessControls": "WARNING", - "visibility": "WARNING", - "checkTypes": "WARNING", - "checkRegExp": "WARNING", - "checkVars": "WARNING", - "deprecated": "WARNING", - "fileoverviewTags": "WARNING", - "invalidCasts": "WARNING", - "missingProperties": "WARNING", - "nonStandardJsDocs": "WARNING", - "undefinedVars": "WARNING" - } -} diff --git a/demos/api1/api1.js b/demos/api1/api1.js new file mode 100644 index 0000000000..c6d7e92ca2 --- /dev/null +++ b/demos/api1/api1.js @@ -0,0 +1,6 @@ +var map = ol.map({ + renderTo: 'map', + layers: [ol.layer.osm()], + center: [45, 5], + zoom: 10 +}); diff --git a/demos/api1/index.html.in b/demos/api1/index.html.in new file mode 100644 index 0000000000..c2b0b0fa81 --- /dev/null +++ b/demos/api1/index.html.in @@ -0,0 +1,19 @@ + + + + + + ol3 api1 demo + + +

ol3 api1 demo

+
+ + + diff --git a/demos/proj4js/index.html.in b/demos/proj4js/index.html.in new file mode 100644 index 0000000000..5239fee524 --- /dev/null +++ b/demos/proj4js/index.html.in @@ -0,0 +1,13 @@ + + + + + + ol3 proj4js demo + + +

ol3 proj4js demo

+
+ + + diff --git a/demos/proj4js/proj4js.js b/demos/proj4js/proj4js.js new file mode 100644 index 0000000000..70f3adfb62 --- /dev/null +++ b/demos/proj4js/proj4js.js @@ -0,0 +1,23 @@ +goog.require('goog.dom'); +goog.require('ol3.Coordinate'); +goog.require('ol3.Projection'); + + +var outputElement = document.getElementById('output'); + +var point, transformedPoint; + +point = new ol3.Coordinate(-626172.13571216376, 6887893.4928337997); +transformedPoint = ol3.Projection.transformWithCodes( + point, 'GOOGLE', 'WGS84'); +outputElement.appendChild(goog.dom.createTextNode(transformedPoint.toString())); + +Proj4js.defs['EPSG:21781'] = + '+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 ' + + '+x_0=600000 +y_0=200000 +ellps=bessel ' + + '+towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs'; + +point = new ol3.Coordinate(7.439583333333333, 46.95240555555556); +transformedPoint = ol3.Projection.transformWithCodes( + point, 'EPSG:4326', 'EPSG:21781'); +outputElement.appendChild(goog.dom.createTextNode(transformedPoint.toString())); diff --git a/demos/side-by-side/index.html.in b/demos/side-by-side/index.html.in new file mode 100644 index 0000000000..0e9ced36a5 --- /dev/null +++ b/demos/side-by-side/index.html.in @@ -0,0 +1,72 @@ + + + + + ol3 side-by-side demo + + +

ol3 side-by-side demo

+ + + + + + + + + + + + + + + + +
DOMWebGL
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pan:drag, arrow keys
Zoom:double-click, Shift+double-click, mouse wheel, +/- keys; Shift+drag
Rotate:Alt+drag, r to reset (WebGL only)
Brightness/contrast:b/B/c/C keys (WebGL only)
Hue/saturation:h/H/s/S keys (WebGL only)
Opacity:o/O keys
Visibility:v/V keys
Reset0 key
+

Notes: The two maps share the same center, resolution, rotation and layers. Currently the DOM map does not support rotation.

+

Console tips: If you want to play around with the API in the console, first make sure that you're using the simple optimizations version of this demo, then open a console and experiment with the domMap, webglMap and layer variables in the console. The source code is in side-by-side.js.

+ + + diff --git a/demos/side-by-side/side-by-side.js b/demos/side-by-side/side-by-side.js new file mode 100644 index 0000000000..987d052a27 --- /dev/null +++ b/demos/side-by-side/side-by-side.js @@ -0,0 +1,109 @@ +goog.require('goog.debug.Console'); +goog.require('goog.debug.Logger'); +goog.require('goog.debug.Logger.Level'); +goog.require('ol3.CoordinateFormat'); +goog.require('ol3.RendererHint'); +goog.require('ol3.control.Attribution'); +goog.require('ol3.control.MousePosition'); +goog.require('ol3.createMap'); +goog.require('ol3.interaction.Keyboard'); +goog.require('ol3.layer.MapQuestOpenAerial'); + + +if (goog.DEBUG) { + goog.debug.Console.autoInstall(); + goog.debug.Logger.getLogger('ol').setLevel(goog.debug.Logger.Level.INFO); +} + + + +var layer = new ol3.layer.MapQuestOpenAerial(); + +var layers = new ol3.Collection(); +layers.push(layer); + +var domMap = ol3.createMap( + document.getElementById('domMap'), + {'layers': layers}, + ol3.RendererHint.DOM); +domMap.setCenter(new ol3.Coordinate(0, 0)); +domMap.setResolution(layer.getStore().getResolutions()[0]); + +var webglMap = ol3.createMap( + document.getElementById('webglMap'), + {}, + ol3.RendererHint.WEBGL); +if (!goog.isNull(webglMap)) { + webglMap.bindTo('center', domMap); + webglMap.bindTo('layers', domMap); + webglMap.bindTo('resolution', domMap); + webglMap.bindTo('rotation', domMap); +} + +var attributionControl = new ol3.control.Attribution(domMap); +document.getElementById('attribution').appendChild( + attributionControl.getElement()); + +var domMousePositionControl = new ol3.control.MousePosition(domMap, + ol3.Projection.getFromCode('EPSG:4326'), ol3.CoordinateFormat.hdms, + ' '); +document.getElementById('domMousePosition').appendChild( + domMousePositionControl.getElement()); + +var webglMousePositionControl = new ol3.control.MousePosition(webglMap, + ol3.Projection.getFromCode('EPSG:4326'), ol3.CoordinateFormat.hdms, + ' '); +document.getElementById('webglMousePosition').appendChild( + webglMousePositionControl.getElement()); + +var keyboardInteraction = new ol3.interaction.Keyboard(); +keyboardInteraction.addCallback('0', function() { + layer.setBrightness(0); + layer.setContrast(0); + layer.setHue(0); + layer.setSaturation(0); + layer.setOpacity(1); + layer.setVisible(true); +}); +keyboardInteraction.addCallback('b', function() { + layer.setBrightness(layer.getBrightness() - 0.1); +}); +keyboardInteraction.addCallback('B', function() { + layer.setBrightness(layer.getBrightness() + 0.1); +}); +keyboardInteraction.addCallback('c', function() { + layer.setContrast(layer.getContrast() - 0.1); +}); +keyboardInteraction.addCallback('C', function() { + layer.setContrast(layer.getContrast() + 0.1); +}); +keyboardInteraction.addCallback('h', function() { + layer.setHue(layer.getHue() - 0.1); +}); +keyboardInteraction.addCallback('H', function() { + layer.setHue(layer.getHue() + 0.1); +}); +keyboardInteraction.addCallback('o', function() { + layer.setOpacity(layer.getOpacity() - 0.1); +}); +keyboardInteraction.addCallback('O', function() { + layer.setOpacity(layer.getOpacity() + 0.1); +}); +keyboardInteraction.addCallback('r', function() { + webglMap.setRotation(0); +}); +keyboardInteraction.addCallback('s', function() { + layer.setSaturation(layer.getSaturation() - 0.1); +}); +keyboardInteraction.addCallback('S', function() { + layer.setSaturation(layer.getSaturation() + 0.1); +}); +keyboardInteraction.addCallback('vV', function() { + layer.setVisible(!layer.getVisible()); +}); +domMap.getInteractions().push(keyboardInteraction); + +goog.exportSymbol('layer', layer); +goog.exportSymbol('layers', layers); +goog.exportSymbol('domMap', domMap); +goog.exportSymbol('webglMap', webglMap); diff --git a/demos/side-by-side/side-by-side.json b/demos/side-by-side/side-by-side.json new file mode 100644 index 0000000000..9b14a6766a --- /dev/null +++ b/demos/side-by-side/side-by-side.json @@ -0,0 +1,9 @@ +{ + + "id": "demo-side-by-side", + + "inherits": "../../base.json", + + "inputs": "demos/side-by-side/side-by-side.js" + +} diff --git a/demos/two-layers/index.html.in b/demos/two-layers/index.html.in new file mode 100644 index 0000000000..0e3abdb732 --- /dev/null +++ b/demos/two-layers/index.html.in @@ -0,0 +1,32 @@ + + + + + ol3 two-layers demo + + +

ol3 two-layers demo

+ + + + + + + + + + + + +
DOMWebGL
+
+
+ + + diff --git a/demos/two-layers/two-layers.js b/demos/two-layers/two-layers.js new file mode 100644 index 0000000000..1428894886 --- /dev/null +++ b/demos/two-layers/two-layers.js @@ -0,0 +1,44 @@ +goog.require('ol3.Coordinate'); +goog.require('ol3.RendererHint'); +goog.require('ol3.control.Attribution'); +goog.require('ol3.createMap'); +goog.require('ol3.layer.BingMaps'); +goog.require('ol3.layer.TileJSON'); + + +var layer1 = new ol3.layer.BingMaps( + ol3.BingMapsStyle.AERIAL, + 'AheP841R-MsLErKQChaTba_xDoOCl40-EeTubD9uNhNAyQTePwFY9iVD1_pyqqlE'); +var layer2 = new ol3.layer.TileJSON( + 'http://api.tiles.mapbox.com/v3/mapbox.va-quake-aug.jsonp'); + +var layers = new ol3.Collection([layer1, layer2]); + +var webglMap = ol3.createMap( + document.getElementById('webglMap'), + {'layers': new ol3.Collection([layer1, layer2])}, + ol3.RendererHint.WEBGL); + +goog.events.listen(layer2, goog.events.EventType.LOAD, function() { + webglMap.setUserCenter(new ol3.Coordinate(-77.93254999999999, 37.9555)); + webglMap.setResolution(layer2.getStore().getResolutions()[5]); +}); + +var domMap = ol3.createMap( + document.getElementById('domMap'), + {}, + ol3.RendererHint.DOM); +domMap.bindTo('center', webglMap); +domMap.bindTo('layers', webglMap); +domMap.bindTo('resolution', webglMap); +domMap.bindTo('rotation', webglMap); + +var attributionControl = new ol3.control.Attribution(webglMap); +document.getElementById('attribution').appendChild( + attributionControl.getElement()); + +goog.exportSymbol('layer1', layer1); +goog.exportSymbol('layer2', layer2); +goog.exportSymbol('layers', layers); +goog.exportSymbol('domMap', domMap); +goog.exportSymbol('webglMap', webglMap); diff --git a/demos/two-layers/two-layers.json b/demos/two-layers/two-layers.json new file mode 100644 index 0000000000..722701e841 --- /dev/null +++ b/demos/two-layers/two-layers.json @@ -0,0 +1,9 @@ +{ + + "id": "demo-two-layers", + + "inherits": "../../base.json", + + "inputs": "demos/two-layers/two-layers.js" + +} diff --git a/doc/ol3.md b/doc/ol3.md new file mode 100644 index 0000000000..3b78e33c8c --- /dev/null +++ b/doc/ol3.md @@ -0,0 +1,274 @@ +CLASS HIERARCHY +=============== + +``` +goog.math.Coordinate // Simple 2D point +| ++- TileCoord + +goog.math.Box +| ++- Extent // The extent of a single object in two dimensions, projection not stored +| ++- TileBounds // A range of tiles in two dimensions, integer coordinates, z not stored + + +Projection + + +goog.events.EventTarget +| ++- MVCObject +| | +| +- Camera +| | +| +- Control +| | | +| | +- ? +| | +| +- Layer +| | | +| | +- TileLayer +| | | | +| | | +- TMSTileLayer +| | | | +| | | +- WMTSTileLayer +| | | | +| | | +- XYZTileLayer / OSMTileLayer +| | | +| | +- VectorLayer +| | | +| | +- ImageLayer +| | +| +- LayerRenderer +| | +| +- LayerRendererOptions +| | +| +- Map +| | +| +- MapRenderer +| | | +| | +- HTMLMapRenderer +| | | +| | +- WebGLMapRenderer +| | +| +- MVCArray +| | | +| | +- ControlArray +| | | +| | +- LayerViewArray +| +| +- TileQueue +| ++- Tile +``` + + +Layer renderer hierarchy +------------------------ + +``` +goog.events.EventTarget +| ++- MVCObject + | + +- LayerRenderer + | + +- SingleTileLayerRenderer + | | + | +- HTMLSingleTileLayerRenderer + | | + | +- WebGLSingleTileLayerRenderer + | + +- TileLayerRenderer + | | + | +- HTMLTileLayerRenderer + | | + | +- WebGLTileLayerRenderer + | + +- VectorLayerRenderer + | | + | +- HTMLVectorLayerRenderer + | | | + | | +- SVGHTMLVectorLayerRenderer + | | | + | | +- Canvas2DHTMLVectorLayerRenderer + | | | + | | +- VMLHTMLVectorLayerRenderer + | | + | +- WebGLVectorLayerRenderer +``` + + +OBJECT PROPERTIES AND METHODS +============================= + +Notation: + +- `property type` property with type, trailing ? indicates unsure, getters and setters are assumed to exist. +- `f(args) -> type` function taking args returning type. +- `f(args) -> type = something` f is a trivial wrapper around something. +- `fires 'x'` fires events of type 'x'. + +Principles: + +- All non-trivial objects inherit from `MVCObject`. +- All non-trivial collections are either `MVCArrays` or a child class thereof. +- Resolutions are `Array.`, infinitely scalable resources (e.g. vectore layers) have resolutions == null. + +``` +MVCObject + as Google Maps MVCObject + freeze() + unfreeze() + +TileCoord + clone() -> TileCoord + getHash() -> number + +TileBounds + forEachTileCoord(z, function(tileCoord)) + +Tile + tileCoord TileCoord + url string + state UNLOADED | LOADING | LOADED + fires 'loaded' // when loaded + fires 'aborted' // when loading is aborted + +Camera + position goog.math.Coordinate + resolution number + rotation number + +Layer + projections Array. + extent Extent + getResolutions() -> Array.|null + fires 'change' // when data changes + +LayerArray + getResolutions() -> Array.|null + getMaxResolution() = this.getResolutions()[0] | null + +LayerRendererOptions + layer Layer + visible boolean + opacity number + brightness number + color number + hue number + saturation number + +Map + projection Projection + renderer Renderer + layers LayerArray + addLayer(layer) = layers.push(layer) + getExtent() -> Extent + getMaxResolution() = layers.getMaxResolution() + +TileGrid + resolutions Array. + extent ol.Extent + xEast boolean + ySouth boolean + origin(s) Coord|Array. + tileSize goog.math.Size + forEachTileCoordChild(tileCoord, function(z, TileBounds)) + forEachTileCoordParent(tileCoord, function(z, TileBounds)) + getExtentTileBounds(z, extent) -> TileBounds + getTileCoord(coordinate) -> TileCoord + getTileCoordCenter(tileCoord) -> goog.math.Coordinate + getTileCoordExtent(tileCoord) -> ol.Extent + getTileCoordResolution(tileCoord) -> number + getZForResolution(resolution) -> number + +TileLayer + tileGrid TileGrid + tileUrl function(tileCoord) -> string + getTileCoordUrl(tileCoord) -> string = this.tileUrl(tileCoord) + +TileQueue + camera Camera // or maybe MVCArray. ? + getTileCoordPriority(tileCoord) -> number // private + enqueueTile(Tile) + +VectorLayer + forEachFeature(resolution, extent, projection, function(Feature)) + +Renderer + target HTMLDivElement + map Map + camera Camera + getCapabilities() -> Array. // maybe ? +``` + +Questions: + +- Store tile layer extent in TileLayer or in TileGrid? (not clear) + +Two concepts: tile coordinate system range and and available data extent. +TileGrid extent is range (or validity extent) of the tile coordinate system. +TileLayer extent is the available data extent. A particular TileGrid may range +from 0,0 to 10,10. My cache may conform to that grid but I may only have tiles +ranging from 2,2 to 8,8. When you need to wrap multiple worlds, you pay +attention to the TileGrid extent. When you need to decide whether or not to +bother requesting a tile, you pay attention to the TileLayer extent. + +- Who determines "best" resolution? (static function?) + + +Todo: if tile layer extent stored in TileLayer rather than TileGrid then extent +will occasionally need to be passed to TileGrid functions for cropping. + +DESIGN ASSERTIONS +================= + +Map + +- A map has a renderer (the map renderer). +- A map has a camera. +- Multiple maps can share the same camera. +- A map has a layer list. + +Layer + +- A layer can have multiple projections (the supported projections). +- A layer advertizes the projections it supports. +- A layer returns no data if asked data for an unsupported projection. + +LayerRendererOptions + +- A layer renderer options object stores view-related states for a layer. +- Options include visibility, opacity, saturation, hue, etc. +- A layer renderer options object has a layer. +- Multiple layer renderer options can share the same layer. +- In other words a layer can be viewed in different manners. + +Renderer + +- The map renderer responds to events. +- The map renderer receives events from the camera. +- The map renderer creates layer renderers. + +Control + +- A control may listen to map events. +- A control may listen to camera events. +- A map navigation control acts on the camera. + +MVC + +- Types can be described in MVC terms. +- Models don't know what rendering means. +- Maps are models. +- Layers are models. +- Layer views are models (sorry!). +- Cameras are models. +- Layer lists are collections. +- Renderers are views. +- Controls are views or controllers or both. +- An attribution control is a view. +- A map navigation control is a controller. +- A zoom slider control is both a view and a controller. diff --git a/externs/bingmaps.js b/externs/bingmaps.js new file mode 100644 index 0000000000..d38bb4e42e --- /dev/null +++ b/externs/bingmaps.js @@ -0,0 +1,176 @@ +/** + * @externs + */ + + + +/** + * @constructor + */ +var BingMapsCoverageArea = function() {}; + + +/** + * @type {Array.} + */ +BingMapsCoverageArea.prototype.bbox; + + +/** + * @type {number} + */ +BingMapsCoverageArea.prototype.zoomMax; + + +/** + * @type {number} + */ +BingMapsCoverageArea.prototype.zoomMin; + + + +/** + * @constructor + */ +var BingMapsImageryProvider = function() {}; + + +/** + * @type {string} + */ +BingMapsImageryProvider.prototype.attribution; + + +/** + * @type {Array.} + */ +BingMapsImageryProvider.prototype.coverageAreas; + + + +/** + * @constructor + */ +var BingMapsImageryMetadataResponse = function() {}; + + +/** + * @type {string} + */ +BingMapsImageryMetadataResponse.prototype.authenticationResultCode; + + +/** + * @type {string} + */ +BingMapsImageryMetadataResponse.prototype.brandLogoUri; + + +/** + * @type {string} + */ +BingMapsImageryMetadataResponse.prototype.copyright; + + +/** + * @type {Array.} + */ +BingMapsImageryMetadataResponse.prototype.resourceSets; + + +/** + * @type {number} + */ +BingMapsImageryMetadataResponse.prototype.statusCode; + + +/** + * @type {string} + */ +BingMapsImageryMetadataResponse.prototype.statusDescription; + + +/** + * @type {string} + */ +BingMapsImageryMetadataResponse.prototype.traceId; + + + +/** + * @constructor + */ +var BingMapsResource = function() {}; + + +/** + * @type {number} + */ +BingMapsResource.prototype.imageHeight; + + +/** + * @type {string} + */ +BingMapsResource.prototype.imageUrl; + + +/** + * @type {Array.} + */ +BingMapsResource.prototype.imageUrlSubdomains; + + +/** + * @type {number} + */ +BingMapsResource.prototype.imageWidth; + + +/** + * @type {Array.} + */ +BingMapsResource.prototype.imageryProviders; + + +/** + * @type {Object} + */ +BingMapsResource.prototype.vintageEnd; + + +/** + * @type {Object} + */ +BingMapsResource.prototype.vintageStart; + + +/** + * @type {number} + */ +BingMapsResource.prototype.zoomMax; + + +/** + * @type {number} + */ +BingMapsResource.prototype.zoomMin; + + + +/** + * @constructor + */ +var BingMapsResourceSet = function() {}; + + +/** + * @type {number} + */ +BingMapsResourceSet.prototype.estimatedTotal; + + +/** + * @type {Array.} + */ +BingMapsResourceSet.prototype.resources; diff --git a/externs/geojson.js b/externs/geojson.js index 68a6bc0178..687eb4cecb 100644 --- a/externs/geojson.js +++ b/externs/geojson.js @@ -1,3 +1,4 @@ + /** * @fileoverview Externs for GeoJSON. * @see http://geojson.org/geojson-spec.html diff --git a/externs/proj4js.js b/externs/proj4js.js new file mode 100644 index 0000000000..1eab482820 --- /dev/null +++ b/externs/proj4js.js @@ -0,0 +1,74 @@ +/** + * @externs + * @see http://trac.osgeo.org/proj4js/ + */ + + +/** + * @type {Object} + */ +var Proj4js = {}; + + +/** + * @type {Object.} + */ +Proj4js.defs; + + +/** + * @type {function(string)} + */ +Proj4js.reportError; + + + +/** + * @constructor + * @param {number} x + * @param {number} y + */ +Proj4js.Point = function(x, y) {}; + + +/** + * @type {number} + */ +Proj4js.Point.prototype.x; + + +/** + * @type {number} + */ +Proj4js.Point.prototype.y; + + + +/** + * @constructor + * @param {string} srsCode + * @param {Function=} opt_callback + */ +Proj4js.Proj = function(srsCode, opt_callback) {}; + + +/** + * @type {string} + */ +Proj4js.Proj.prototype.title; + + +/** + * @type {string} + */ +Proj4js.Proj.prototype.units; + + +/** + * @nosideeffects + * @param {Proj4js.Proj} source + * @param {Proj4js.Proj} dest + * @param {Proj4js.Point|{x:number, y:number}} point + * @return {Proj4js.Point} + */ +Proj4js.transform = function(source, dest, point) {}; diff --git a/externs/tilejson.js b/externs/tilejson.js new file mode 100644 index 0000000000..5927c479ee --- /dev/null +++ b/externs/tilejson.js @@ -0,0 +1,95 @@ +/** + * @externs + * @see https://github.com/mapbox/tilejson-spec + */ + + + +/** + * @constructor + */ +var TileJSON = function() {}; + + +/** + * @type {string} + */ +TileJSON.prototype.tilejson; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.name; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.description; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.version; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.attribution; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.template; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.legend; + + +/** + * @type {string|undefined} + */ +TileJSON.prototype.scheme; + + +/** + * @type {!Array.} + */ +TileJSON.prototype.tiles; + + +/** + * @type {!Array.} + */ +TileJSON.prototype.grids; + + +/** + * @type {number|undefined} + */ +TileJSON.prototype.minzoom; + + +/** + * @type {number|undefined} + */ +TileJSON.prototype.maxzoom; + + +/** + * @type {!Array.|undefined} + */ +TileJSON.prototype.bounds; + + +/** + * @type {!Array.|undefined} + */ +TileJSON.prototype.center; diff --git a/externs/webgl-debug.js b/externs/webgl-debug.js new file mode 100644 index 0000000000..9f5803831c --- /dev/null +++ b/externs/webgl-debug.js @@ -0,0 +1,98 @@ +/** + * @externs + * @see http://www.khronos.org/webgl/wiki/Debugging + * @see http://www.khronos.org/webgl/wiki/HandlingContextLost + */ + + + +/** + * @constructor + * @extends {WebGLRenderingContext} + */ +var WebGLDebugRenderingContext = function() {}; + + + +/** + * @constructor + * @extends {HTMLCanvasElement} + */ +var WebGLDebugLostContextSimulatingCanvas = function() {}; + + +/** + * @nosideeffects + * @return {number} + */ +WebGLDebugLostContextSimulatingCanvas.prototype.getNumCalls = function() {}; + + +/** + */ +WebGLDebugLostContextSimulatingCanvas.prototype.loseContext = function() {}; + + +/** + * @param {number} numCalls + */ +WebGLDebugLostContextSimulatingCanvas.prototype.loseContextInNCalls = + function(numCalls) {}; + + +/** + */ +WebGLDebugLostContextSimulatingCanvas.prototype.restoreContext = function() {}; + + +/** + * @param {number} timeout + */ +WebGLDebugLostContextSimulatingCanvas.prototype.setRestoreTimeout = + function(timeout) {}; + + +/** + * @type {Object} + */ +var WebGLDebugUtils = {}; + + +/** + * @nosideeffects + * @param {number} value + * @return {string} + */ +WebGLDebugUtils.glEnumToString = function(value) {}; + + +/** + * @nosideeffects + * @param {string} functionName + * @param {Array} args Args. + * @return {string} String. + */ +WebGLDebugUtils.glFunctionArgsToString = function(functionName, args) {}; + + +/** + * @param {WebGLRenderingContext} ctx + */ +WebGLDebugUtils.init = function(ctx) {}; + + +/** + * @param {HTMLCanvasElement} canvas + * @return {WebGLDebugLostContextSimulatingCanvas} + */ +WebGLDebugUtils.makeLostContextSimulatingCanvas = function(canvas) {}; + + +/** + * @param {WebGLRenderingContext} context + * @param {Function=} opt_onErrorFunc + * @param {Function=} opt_onFunc + * @return {WebGLDebugRenderingContext} + */ +WebGLDebugUtils.makeDebugContext = + function(context, opt_onErrorFunc, opt_onFunc) {}; diff --git a/main.json b/main.json deleted file mode 100644 index 5e5a6efe1f..0000000000 --- a/main.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "id": "ol", - - "inputs": [ - "src/ol.js", - "src/ol.export.js" - ], - "paths": [ - "src" - ], - - "define": { - // "goog.dom.ASSUME_STANDARDS_MODE": true, - "goog.DEBUG": false - }, - - "externs": [ - "externs/geojson.js" - ], - - "mode": "ADVANCED", - "level": "VERBOSE", - "pretty-print": true, - "debug": true, - - // "experimental-compiler-options": { - // "generateExports": true - // }, - - "checks": { - // acceptable values are "ERROR", "WARNING", and "OFF" - "accessControls": "WARNING", - "visibility": "WARNING", - "checkTypes": "WARNING", - "checkRegExp": "WARNING", - "checkVars": "WARNING", - "deprecated": "WARNING", - "fileoverviewTags": "WARNING", - "invalidCasts": "WARNING", - "missingProperties": "WARNING", - "nonStandardJsDocs": "WARNING", - "undefinedVars": "WARNING" - }, - - "jsdoc-html-output-path": "jsdoc" -} diff --git a/readme.md b/readme.md index f41fcc8bb8..1895d719de 100644 --- a/readme.md +++ b/readme.md @@ -1,79 +1,35 @@ -# OpenLayers +# OpenLayers 3 -Copyright (c) 2005-2012 OpenLayers Contributors. See authors.txt for -more details. +## Build it -OpenLayers is a JavaScript library for building map applications -on the web. OpenLayers is made available under a BSD-license. -Please see license.txt in this distribution for more details. +Run make: -## Getting OpenLayers + $ make -OpenLayers lives at http://www.openlayers.org/. Find details on downloading stable releases or the development version the [development site](http://trac.osgeo.org/openlayers/wiki/HowToDownload). +## Run the examples -## Installing OpenLayers +Run make (as above), then explore the `demos/` directory with your web browser. -You can use OpenLayers as-is by copying build/OpenLayers.js and the -entire theme/ and img/ directories up to your webserver and putting them -in the same directory. The files can be in subdirectories on your website, -or right in the root of the site, as in these examples. -To include the OpenLayers library in your web page from the root of the site, use: +## Run the examples in debug mode -