Compare commits
8 Commits
v5.0.0-bet
...
v4.6.4-bac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af013db6d8 | ||
|
|
9b0cd2a7c8 | ||
|
|
f7a1aba38e | ||
|
|
6e9fc2cbad | ||
|
|
61245fb83a | ||
|
|
e065c851de | ||
|
|
ed29dde552 | ||
|
|
8a73db9331 |
9
.babelrc
9
.babelrc
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"plugins": ["jsdoc-closure"],
|
||||
"parserOpts": {
|
||||
"parser": "recast"
|
||||
},
|
||||
"generatorOpts": {
|
||||
"generator": "recast"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
examples/Jugl.js
|
||||
examples/resources/
|
||||
build/package/**/*webgl*
|
||||
config/jsdoc/api/template/static/scripts/
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -6,3 +6,4 @@ In order to get your proposed changes merged into the master branch, we ask you
|
||||
- [ ] It contains one or more small, incremental, logically separate commits, with no merge commits.
|
||||
- [ ] I have used clear commit messages.
|
||||
- [ ] Existing tests pass for me locally & I have added or updated tests for new or changed functionality.
|
||||
- [ ] The work herein is covered by a valid [Contributor License Agreement (CLA)](https://github.com/openlayers/cla).
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,4 +2,3 @@
|
||||
/coverage/
|
||||
/dist/
|
||||
/node_modules/
|
||||
src/index.js
|
||||
|
||||
1
.npmignore
Normal file
1
.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/build/
|
||||
@@ -1,9 +1,14 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- '8'
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
before_script:
|
||||
- rm src/ol/renderer/webgl/*shader.js
|
||||
- rm src/ol/renderer/webgl/*shader/locations.js
|
||||
script: make ci
|
||||
after_success:
|
||||
- cat coverage/lcov.info | coveralls
|
||||
branches:
|
||||
|
||||
@@ -31,7 +31,12 @@ This page describes what you need to know to contribute code to OpenLayers as a
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Your contribution will be under our [license](https://raw.githubusercontent.com/openlayers/openlayers/master/LICENSE.md) as per [GitHub's terms of service](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license).
|
||||
Before accepting a contribution, we ask that you provide us a Contributor
|
||||
License Agreement. If you are making your contribution as part of work for
|
||||
your employer, please follow the guidelines on submitting a [Corporate
|
||||
Contributor License Agreement](https://raw.github.com/openlayers/cla/master/ccla.txt). If you are
|
||||
making your contribution as an individual, you can submit a digital [Individual
|
||||
Contributor License Agreement](https://docs.google.com/spreadsheet/viewform?formkey=dGNNVUJEMXF2dERTU0FXM3JjNVBQblE6MQ).
|
||||
|
||||
|
||||
## Pull request guidelines
|
||||
@@ -55,6 +60,66 @@ Your pull request must:
|
||||
* Be possible to merge automatically.
|
||||
|
||||
|
||||
### The `check` build target
|
||||
|
||||
It is strongly recommended that you run
|
||||
|
||||
$ make check
|
||||
|
||||
before every commit. This will catch many problems quickly, and it is much
|
||||
faster than waiting for the Travis CI integration tests to run.
|
||||
|
||||
The `check` build target runs a number of quick tests on your code. These
|
||||
include:
|
||||
|
||||
* Lint
|
||||
* Compile
|
||||
* Tests
|
||||
|
||||
|
||||
### Follow OpenLayers's coding style
|
||||
|
||||
OpenLayers follows [Google's JavaScript Style
|
||||
Guide](https://google.github.io/styleguide/javascriptguide.xml).
|
||||
This is checked using [ESLint](http://eslint.org/), you
|
||||
can run the linter locally on your machine before committing using the `lint`
|
||||
target:
|
||||
|
||||
$ make lint
|
||||
|
||||
In addition to fixing problems identified by the linter, please also follow the
|
||||
style of the existing OpenLayers code, which includes:
|
||||
|
||||
* Always wrap the body of `for`, `if`, and `while` statements in braces.
|
||||
|
||||
* Class methods should be in alphabetical order.
|
||||
|
||||
* `var` declarations should not span multiple lines. If you cannot fit all
|
||||
the declarations in a single line, then start a new `var` declaration on a
|
||||
new line. Within a single line, variables should be declared in
|
||||
alphabetical order.
|
||||
|
||||
* Do not use assignments inside expressions.
|
||||
|
||||
* Use uppercase for `@const` variables.
|
||||
|
||||
### Configure your editor
|
||||
|
||||
If possible, configure your editor to follow the coding conventions of the
|
||||
library. A `.editorconfig` file is included at the root of the repository that
|
||||
can be used to configure whitespace and charset handling in your editor. See
|
||||
that file for a description of the conventions. The [EditorConfig](
|
||||
http://editorconfig.org/#download) site links to plugins for various editors.
|
||||
|
||||
### Pass the integration tests run automatically by the Travis CI system
|
||||
|
||||
The integration tests contain a number of automated checks to ensure that the
|
||||
code follows the OpenLayers style and does not break tests or examples. You
|
||||
can run the integration tests locally using the `ci` target:
|
||||
|
||||
$ make ci
|
||||
|
||||
|
||||
### Address a single issue or add a single item of functionality
|
||||
|
||||
Please submit separate pull requests for separate issues. This allows each to
|
||||
@@ -108,3 +173,33 @@ Occasionally other changes to `master` might mean that your pull request cannot
|
||||
be merged automatically. In this case you may need to rebase your branch on a
|
||||
more recent `master`, resolve any conflicts, and `git push --force` to update
|
||||
your branch so that it can be merged automatically.
|
||||
|
||||
## Building on Windows
|
||||
|
||||
Most developers build on Linux. Building on Windows is possible under Cygwin.
|
||||
When installing Cygwin from https://www.cygwin.com/, include the developer
|
||||
tools to get GNU make.
|
||||
|
||||
First (before npm install), to avoid file permission problems between Windows
|
||||
and Cygwin, edit Cygwin's /etc/fstab file to disable ACLs like this
|
||||
`none /cygdrive cygdrive binary,noacl,posix=0,user 0 0`
|
||||
|
||||
Python is normally installed with Cygwin so need not be installed separately.
|
||||
By default Cygwin will use its own version of Python rather than Window's,
|
||||
so the Python modules should be installed for Cygwin's Python.
|
||||
|
||||
The build targets `check-deps`, `serve`, `lint`, `build`, `test`, `check` and
|
||||
`host-examples` described above should all work. `host-examples` takes quite a
|
||||
while to run. If a target does not run properly first time, try it again.
|
||||
|
||||
Currently, Firefox fails to run http://localhost:3000/build/examples
|
||||
from make serve, but Chrome and Internet Explorer will.
|
||||
|
||||
Microsoft Visual Studio's javascript debugger may be used to debug the
|
||||
build/hosted/your-branch/examples. It will be convenient to set
|
||||
build/hosted/your-branch/examples/index.html as the startup page.
|
||||
|
||||
Your OpenLayers source tree need not be under the Cygwin root.
|
||||
if you checkout to c:/openlayers then you can build under Cygwin at /cygdrive/c/openlayers .
|
||||
However, keep the path to the OpenLayers files short otherwise you may see
|
||||
`ENAMETOOLONG` errors.
|
||||
|
||||
@@ -15,32 +15,103 @@ pull requests will not be merged.
|
||||
|
||||
The minimum requirements are:
|
||||
|
||||
* GNU Make
|
||||
* Git
|
||||
* [Node.js](http://nodejs.org/) (version 8 and above)
|
||||
* Python 2.6 or 2.7
|
||||
* Java 7 (JRE and JDK)
|
||||
|
||||
The executables `git` and `node` should be in your `PATH`.
|
||||
The executables `git`, `node`, and `java` should be in your `PATH`.
|
||||
|
||||
You can check your configuration by running:
|
||||
|
||||
$ make check-deps
|
||||
|
||||
To install the Node.js dependencies run
|
||||
|
||||
$ npm install
|
||||
|
||||
## Working with the build tool
|
||||
|
||||
As an OpenLayers developer you will use `make` to run build targets defined in the
|
||||
`Makefile` located at the root of the repository. The `Makefile` includes
|
||||
targets for running the linter, the compiler, the tests, etc.
|
||||
|
||||
The usage of `make` is as follows:
|
||||
|
||||
$ make <target>
|
||||
|
||||
where `<target>` is the name of the build target you want to execute. For
|
||||
example:
|
||||
|
||||
$ make test
|
||||
|
||||
The main build targets are `serve`, `lint`, `build`, `test`, and `check`. The
|
||||
latter is a meta-target that basically runs `lint`, `build`, and `test`.
|
||||
|
||||
The `serve` target starts a node-based web server, which we will refer to as the *dev server*. You'll need to start that server for running the examples and the tests in a browser. More information on that further down.
|
||||
|
||||
Other targets include `apidoc` and `ci`. The latter is the target used on Travis CI. See OpenLayers's [Travis configuration file](https://github.com/openlayers/openlayers/blob/master/.travis.yml).
|
||||
|
||||
## Running the `check` target
|
||||
|
||||
The `check` target is to be run before pushing code to GitHub and opening pull
|
||||
requests. Branches that don't pass `check` won't pass the integration tests,
|
||||
and have therefore no chance of being merged into `master`.
|
||||
|
||||
To run the `check` target:
|
||||
|
||||
$ make check
|
||||
|
||||
If you want to run the full suite of integration tests, see "Running the integration
|
||||
tests" below.
|
||||
|
||||
## Running examples
|
||||
|
||||
To run the examples you first need to start the dev server:
|
||||
|
||||
$ npm run serve-examples
|
||||
$ make serve
|
||||
|
||||
Then, load <http://localhost:5000/> in your browser.
|
||||
Then, just point your browser <http://localhost:3000/build/examples> in your browser. For example <http://localhost:3000/build/examples/side-by-side.html>.
|
||||
|
||||
Run examples against the `ol.js` standalone build:
|
||||
|
||||
The examples can also be run against the `ol.js` standalone build, just like
|
||||
the examples [hosted](https://openlayers.org/en/master/examples/) on GitHub.
|
||||
Start by executing the `host-examples` build target:
|
||||
|
||||
$ make host-examples
|
||||
|
||||
After running `host-examples` you can now open the examples index page in the browser: <http://localhost:3000/build/hosted/master/examples/>. (This assumes that you still have the dev server running.)
|
||||
|
||||
Append `?mode=raw` to make the example work in full debug mode. In raw mode the OpenLayers and Closure Library scripts are loaded individually by the Closure Library's `base.js` script (which the example page loads and executes before any other script).
|
||||
|
||||
## Running tests
|
||||
|
||||
To run the tests once:
|
||||
To run the tests in a browser start the dev server (`make serve`) and open <http://localhost:3000/test/index.html> in the browser.
|
||||
|
||||
$ npm test
|
||||
To run the tests on the console (headless testing with PhantomJS) use the `test` target:
|
||||
|
||||
To run the tests continuously during development:
|
||||
$ make test
|
||||
|
||||
$ npm run karma
|
||||
See also the test-specific [README](../master/test/README.md).
|
||||
|
||||
## Running the integration tests
|
||||
|
||||
When you submit a pull request the [Travis continuous integration
|
||||
server](https://travis-ci.org/) will run a full suite of tests, including
|
||||
building all versions of the library and checking that all of the examples
|
||||
work. You will receive an email with the results, and the status will be
|
||||
displayed in the pull request.
|
||||
|
||||
To run the full suite of integration tests use the `ci` target:
|
||||
|
||||
$ make ci
|
||||
|
||||
Running the full suite of integration tests currently takes 5-10 minutes.
|
||||
|
||||
This makes sure that your commit won't break the build. It also runs JSDoc3 to
|
||||
make sure that there are no invalid API doc directives.
|
||||
|
||||
## Adding examples
|
||||
|
||||
@@ -52,3 +123,14 @@ implies creating two or three files in this directory, an `.html` file, a `.js`
|
||||
file, and, optionally, a `.css` file.
|
||||
|
||||
You can use `simple.js` and `simple.html` as templates for new examples.
|
||||
|
||||
### Use of the `goog` namespace in examples
|
||||
|
||||
Short story: the OpenLayers examples should not use the `goog` namespace, except
|
||||
for `goog.require`.
|
||||
|
||||
Longer story: we want that the OpenLayers examples work in multiple modes, with the
|
||||
standalone lib (which has implications of the symbols and properties we
|
||||
export), and compiled together with the OpenLayers library.
|
||||
|
||||
Compiling the examples together with the library makes it mandatory to declare dependencies with `goog.require` statements.
|
||||
|
||||
275
Makefile
275
Makefile
@@ -1,13 +1,280 @@
|
||||
OS := $(shell uname)
|
||||
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
SRC_GLSL := $(shell find src -type f -name '*.glsl')
|
||||
SRC_SHADER_JS := $(patsubst %shader.glsl,%shader.js,$(SRC_GLSL))
|
||||
SRC_SHADERLOCATIONS_JS := $(patsubst %shader.glsl,%shader/Locations.js,$(SRC_GLSL))
|
||||
SRC_SHADERLOCATIONS_JS := $(patsubst %shader.glsl,%shader/locations.js,$(SRC_GLSL))
|
||||
SRC_JS := $(filter-out $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS),$(shell find src -name '*.js'))
|
||||
SRC_JSDOC = $(shell find src -type f -name '*.jsdoc')
|
||||
|
||||
EXAMPLES := $(shell find examples -type f)
|
||||
EXAMPLES_HTML := $(filter-out examples/index.html,$(shell find examples -maxdepth 1 -type f -name '*.html'))
|
||||
EXAMPLES_JS := $(patsubst %.html,%.js,$(EXAMPLES_HTML))
|
||||
|
||||
BUILD_EXAMPLES := $(subst examples,build/examples,$(EXAMPLES)) build/examples/index.js
|
||||
|
||||
BUILD_HOSTED := build/hosted/$(BRANCH)
|
||||
BUILD_HOSTED_EXAMPLES := $(addprefix $(BUILD_HOSTED)/,$(EXAMPLES))
|
||||
BUILD_HOSTED_EXAMPLES_JS := $(addprefix $(BUILD_HOSTED)/,$(EXAMPLES_JS))
|
||||
|
||||
UNPHANTOMABLE_EXAMPLES = examples/shaded-relief.html examples/raster.html examples/region-growing.html examples/color-manipulation.html
|
||||
CHECK_EXAMPLE_TIMESTAMPS = $(patsubst examples/%.html,build/timestamps/check-%-timestamp,$(filter-out $(UNPHANTOMABLE_EXAMPLES),$(EXAMPLES_HTML)))
|
||||
|
||||
TASKS_JS := $(shell find tasks -name '*.js')
|
||||
|
||||
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
|
||||
CLOSURE_LIB = $(shell cygpath -u $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())'))
|
||||
else
|
||||
CLOSURE_LIB = $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())')
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
STAT_COMPRESSED = stat -f ' compressed: %z bytes'
|
||||
STAT_UNCOMPRESSED = stat -f 'uncompressed: %z bytes'
|
||||
else
|
||||
STAT_COMPRESSED = stat -c ' compressed: %s bytes'
|
||||
STAT_UNCOMPRESSED = stat -c 'uncompressed: %s bytes'
|
||||
endif
|
||||
|
||||
.PHONY: default
|
||||
default: help
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo
|
||||
@echo "The most common targets are:"
|
||||
@echo
|
||||
@echo "- install Install node dependencies"
|
||||
@echo "- serve Start dev server for running examples and tests"
|
||||
@echo "- test Run unit tests in the console"
|
||||
@echo "- check Perform a number of checks on the code"
|
||||
@echo "- clean Remove generated files"
|
||||
@echo "- help Display this help message"
|
||||
@echo
|
||||
@echo "Other less frequently used targets are:"
|
||||
@echo
|
||||
@echo "- build Build ol.js, ol-debug.js, ol.js.map and ol.css"
|
||||
@echo "- ci Run the full continuous integration process"
|
||||
@echo "- apidoc Build the API documentation using JSDoc"
|
||||
@echo "- cleanall Remove all the build artefacts"
|
||||
@echo "- check-deps Check if the required dependencies are installed"
|
||||
@echo
|
||||
|
||||
.PHONY: apidoc
|
||||
apidoc: build/timestamps/jsdoc-$(BRANCH)-timestamp
|
||||
|
||||
.PHONY: build
|
||||
build: build/ol.css build/ol.js build/ol-debug.js build/ol.js.map
|
||||
|
||||
.PHONY: check
|
||||
check: build/ol.js test
|
||||
|
||||
.PHONY: check-examples
|
||||
check-examples: $(CHECK_EXAMPLE_TIMESTAMPS)
|
||||
|
||||
.PHONY: check-deps
|
||||
check-deps: EXECUTABLES = git node python java
|
||||
check-deps:
|
||||
@for exe in $(EXECUTABLES) ;\
|
||||
do \
|
||||
which $${exe} > /dev/null && \
|
||||
echo "Program $${exe} OK" || \
|
||||
echo "Program $${exe} MISSING!" ;\
|
||||
done ;\
|
||||
|
||||
.PHONY: ci
|
||||
ci: build test package compile-examples check-examples apidoc
|
||||
|
||||
.PHONY: compile-examples
|
||||
compile-examples: build/compiled-examples/all.combined.js
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f build/timestamps/check-*-timestamp
|
||||
rm -f build/ol.css
|
||||
rm -f build/ol.js
|
||||
rm -f build/ol.js.map
|
||||
rm -f build/ol-debug.js
|
||||
rm -rf build/examples
|
||||
rm -rf build/compiled-examples
|
||||
rm -rf build/package
|
||||
rm -rf $(BUILD_HOSTED)
|
||||
|
||||
.PHONY: cleanall
|
||||
cleanall:
|
||||
rm -rf build
|
||||
|
||||
.PHONY: css
|
||||
css: build/ol.css
|
||||
|
||||
.PHONY: examples
|
||||
examples: $(BUILD_EXAMPLES)
|
||||
|
||||
.PHONY: install
|
||||
install: build/timestamps/node-modules-timestamp
|
||||
|
||||
.PHONY: npm-install
|
||||
npm-install: build/timestamps/node-modules-timestamp
|
||||
|
||||
.PHONY: shaders
|
||||
shaders: $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS)
|
||||
shaders: $(SRC_SHADER_JS $(SRC_SHADERLOCATIONS_JS)
|
||||
|
||||
%shader.js: %shader.glsl src/ol/webgl/shader.mustache tasks/glslunit.js
|
||||
.PHONY: serve
|
||||
serve:
|
||||
node tasks/serve.js
|
||||
|
||||
.PHONY: test
|
||||
test: build/timestamps/node-modules-timestamp
|
||||
npm test
|
||||
|
||||
.PHONY: host-examples
|
||||
host-examples: $(BUILD_HOSTED_EXAMPLES) \
|
||||
$(BUILD_HOSTED)/build/ol.js \
|
||||
$(BUILD_HOSTED)/build/ol-debug.js \
|
||||
$(BUILD_HOSTED)/css/ol.css \
|
||||
$(BUILD_HOSTED)/examples/loader.js \
|
||||
$(BUILD_HOSTED)/examples/index.js \
|
||||
$(BUILD_HOSTED)/build/ol-deps.js
|
||||
|
||||
.PHONY: host-libraries
|
||||
host-libraries: build/timestamps/node-modules-timestamp
|
||||
@rm -rf $(BUILD_HOSTED)/closure-library
|
||||
@mkdir -p $(BUILD_HOSTED)/closure-library
|
||||
@cp -r $(CLOSURE_LIB)/* $(BUILD_HOSTED)/closure-library/
|
||||
@rm -rf $(BUILD_HOSTED)/ol/ol
|
||||
@mkdir -p $(BUILD_HOSTED)/ol/ol
|
||||
@cp -r src/ol/* $(BUILD_HOSTED)/ol/ol/
|
||||
@rm -rf $(BUILD_HOSTED)/ol.ext
|
||||
@mkdir -p $(BUILD_HOSTED)/ol.ext
|
||||
@cp -r build/ol.ext/* $(BUILD_HOSTED)/ol.ext/
|
||||
|
||||
$(BUILD_EXAMPLES): $(EXAMPLES) package.json
|
||||
@mkdir -p $(@D)
|
||||
@node tasks/build-examples.js
|
||||
|
||||
build/timestamps/check-%-timestamp: $(BUILD_HOSTED)/examples/%.html \
|
||||
$(BUILD_HOSTED)/examples/%.js \
|
||||
$(filter $(BUILD_HOSTED)/examples/resources/%,$(BUILD_HOSTED_EXAMPLES)) \
|
||||
$(filter $(BUILD_HOSTED)/examples/data/%,$(BUILD_HOSTED_EXAMPLES)) \
|
||||
$(BUILD_HOSTED)/examples/loader.js \
|
||||
$(BUILD_HOSTED)/build/ol.js \
|
||||
$(BUILD_HOSTED)/css/ol.css
|
||||
@mkdir -p $(@D)
|
||||
node tasks/check-example.js $<
|
||||
@touch $@
|
||||
|
||||
build/compiled-examples/all.js: $(EXAMPLES_JS)
|
||||
@mkdir -p $(@D)
|
||||
@python bin/combine-examples.py $^ > $@
|
||||
|
||||
build/compiled-examples/all.combined.js: config/examples-all.json build/compiled-examples/all.js \
|
||||
$(SRC_JS) $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
node tasks/build.js $< $@
|
||||
|
||||
build/compiled-examples/%.json: config/example.json build/examples/%.js \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@sed -e 's|{{id}}|$*|' $< > $@
|
||||
|
||||
build/compiled-examples/%.combined.js: build/compiled-examples/%.json \
|
||||
$(SRC_JS) $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS)\
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
node tasks/build.js $< $@
|
||||
|
||||
build/timestamps/jsdoc-$(BRANCH)-timestamp: config/jsdoc/api/index.md \
|
||||
config/jsdoc/api/conf.json $(SRC_JS) \
|
||||
$(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS) \
|
||||
$(shell find config/jsdoc/api/template -type f) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@rm -rf $(BUILD_HOSTED)/apidoc
|
||||
./node_modules/.bin/jsdoc config/jsdoc/api/index.md -c config/jsdoc/api/conf.json --package package.json -d $(BUILD_HOSTED)/apidoc
|
||||
@touch $@
|
||||
|
||||
$(BUILD_HOSTED_EXAMPLES_JS): $(BUILD_HOSTED)/examples/%.js: build/examples/%.js
|
||||
@mkdir -p $(@D)
|
||||
@python bin/split-example.py $< $(@D)
|
||||
|
||||
$(BUILD_HOSTED)/examples/loader.js: bin/loader_hosted_examples.js
|
||||
@mkdir -p $(@D)
|
||||
@cp $< $@
|
||||
|
||||
$(BUILD_HOSTED)/examples/%: build/examples/%
|
||||
@mkdir -p $(@D)
|
||||
@cp $< $@
|
||||
|
||||
$(BUILD_HOSTED)/build/ol.js: build/ol.js
|
||||
@mkdir -p $(@D)
|
||||
@cp $< $@
|
||||
|
||||
$(BUILD_HOSTED)/build/ol-debug.js: build/ol-debug.js
|
||||
@mkdir -p $(@D)
|
||||
@cp $< $@
|
||||
|
||||
$(BUILD_HOSTED)/css/ol.css: build/ol.css
|
||||
@mkdir -p $(@D)
|
||||
@cp $< $@
|
||||
|
||||
$(BUILD_HOSTED)/build/ol-deps.js: host-libraries
|
||||
@mkdir -p $(@D)
|
||||
@python $(CLOSURE_LIB)/closure/bin/build/depswriter.py \
|
||||
--root_with_prefix "src ../../../ol" \
|
||||
--root_with_prefix "build/ol.ext ../../../ol.ext" \
|
||||
--root $(BUILD_HOSTED)/closure-library/closure/goog \
|
||||
--root_with_prefix "$(BUILD_HOSTED)/closure-library/third_party ../../third_party" \
|
||||
--output_file $@
|
||||
|
||||
build/timestamps/node-modules-timestamp: package.json
|
||||
@mkdir -p $(@D)
|
||||
npm install
|
||||
@touch $@
|
||||
|
||||
build/ol.css: css/ol.css build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@echo "Running cleancss..."
|
||||
@./node_modules/.bin/cleancss $< > $@
|
||||
|
||||
build/ol.js: config/ol.json $(SRC_JS) $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
node tasks/build.js $< $@
|
||||
@$(STAT_UNCOMPRESSED) $@
|
||||
@cp $@ /tmp/
|
||||
@gzip /tmp/ol.js
|
||||
@$(STAT_COMPRESSED) /tmp/ol.js.gz
|
||||
@rm /tmp/ol.js.gz
|
||||
|
||||
build/ol.js.map: config/ol.json $(SRC_JS) $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
node tasks/build.js $< $@
|
||||
|
||||
build/ol-debug.js: config/ol-debug.json $(SRC_JS) $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
node tasks/build.js $< $@
|
||||
@$(STAT_UNCOMPRESSED) $@
|
||||
@cp $@ /tmp/
|
||||
@gzip /tmp/ol-debug.js
|
||||
@$(STAT_COMPRESSED) /tmp/ol-debug.js.gz
|
||||
@rm /tmp/ol-debug.js.gz
|
||||
|
||||
%shader.js: %shader.glsl src/ol/webgl/shader.mustache tasks/glslunit.js build/timestamps/node-modules-timestamp
|
||||
@node tasks/glslunit.js --input $< | ./node_modules/.bin/mustache - src/ol/webgl/shader.mustache > $@
|
||||
|
||||
%shader/Locations.js: %shader.glsl src/ol/webgl/shaderlocations.mustache tasks/glslunit.js
|
||||
%shader/locations.js: %shader.glsl src/ol/webgl/shaderlocations.mustache tasks/glslunit.js build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@node tasks/glslunit.js --input $< | ./node_modules/.bin/mustache - src/ol/webgl/shaderlocations.mustache > $@
|
||||
|
||||
.PHONY: package
|
||||
package:
|
||||
@rm -rf build/package
|
||||
@cp -r package build
|
||||
@cd ./src && cp -r ol/* ../build/package
|
||||
@rm build/package/typedefs.js
|
||||
@cp css/ol.css build/package
|
||||
./node_modules/.bin/jscodeshift --transform transforms/module.js build/package
|
||||
npm run lint-package
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
[](https://greenkeeper.io/)
|
||||
[](https://coveralls.io/github/openlayers/openlayers?branch=master)
|
||||
[](http://osgeo.org/)
|
||||
[](https://www.jsdelivr.com/package/npm/openlayers)
|
||||
|
||||
[OpenLayers](https://openlayers.org/) is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic information of all kinds. It is completely free, Open Source JavaScript, released under the 2-clause BSD License (also known as the FreeBSD).
|
||||
|
||||
|
||||
33
bin/check-example.js
Normal file
33
bin/check-example.js
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// A PhantomJS script used to check that the hosted examples load
|
||||
// without errors. This script is executed by the build tool's
|
||||
// check-examples target.
|
||||
//
|
||||
var args = require('system').args;
|
||||
if (args.length != 2) {
|
||||
phantom.exit(2);
|
||||
}
|
||||
var examplePath = args[1];
|
||||
var page = require('webpage').create();
|
||||
page.onError = function(msg, trace) {
|
||||
var msgStack = ['JavaScript ERROR: ' + msg];
|
||||
if (trace) {
|
||||
msgStack.push('TRACE:');
|
||||
trace.forEach(function(t) {
|
||||
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
|
||||
});
|
||||
}
|
||||
console.error(msgStack.join('\n'));
|
||||
phantom.exit(1);
|
||||
};
|
||||
page.open(examplePath, function(s) {
|
||||
var exitCode = 0;
|
||||
if (s != 'success') {
|
||||
exitCode = 1;
|
||||
console.error('PAGE LOAD ERROR');
|
||||
}
|
||||
phantom.exit(exitCode);
|
||||
});
|
||||
page.onConsoleMessage = function(msg) {
|
||||
console.log('console:', msg);
|
||||
};
|
||||
27
bin/combine-examples.py
Executable file
27
bin/combine-examples.py
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def main(argv):
|
||||
examples = {}
|
||||
requires = set()
|
||||
for filename in argv[1:]:
|
||||
lines = open(filename, 'rU').readlines()
|
||||
if len(lines) > 0 and lines[0].startswith('// NOCOMPILE'):
|
||||
continue
|
||||
requires.update(line for line in lines if line.startswith('goog.require'))
|
||||
examples[filename] = [line for line in lines if not line.startswith('goog.require')]
|
||||
for require in sorted(requires):
|
||||
sys.stdout.write(require)
|
||||
for filename in sorted(examples.keys()):
|
||||
sys.stdout.write('// ' + filename + '\n')
|
||||
sys.stdout.write('(function(){\n')
|
||||
for line in examples[filename]:
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.write('})();\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
180
bin/example-screenshot.js
Normal file
180
bin/example-screenshot.js
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
/**
|
||||
* This script is supposed to be executed via phantomjs. It will generate
|
||||
* screenshots of the html files in the directory specified by a commandline
|
||||
* option when these files are served through a webserver which can also be
|
||||
* specified. The screenshots will be in the current working directory.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* user@host:~/openlayers/bin $ phantomjs example-screenshot.js \
|
||||
* http://localhost:8000/openlayers/examples/ \
|
||||
* ../examples
|
||||
*
|
||||
* The above command will generate `*.png` files in `examples/` for all html
|
||||
* files that are served through `http://localhost:8000/openlayers/examples/`.
|
||||
*
|
||||
* So if there is a file `my-humpty-example.html` inside of the relative folder
|
||||
* `../examples/` which is being served through the webserver so that
|
||||
* `http://localhost:8000/openlayers/examples/my-humpty-example.html` is a valid and
|
||||
* reachable URL, this script will generate a screenshot and store it as
|
||||
* `my-humpty-example.html.png`.
|
||||
*
|
||||
* The query string `?mode=raw` will be appended to the generated URL.
|
||||
*
|
||||
* Known limitations:
|
||||
*
|
||||
* As phantomjs doesn't support WebGL (see e.g.
|
||||
* https://github.com/ariya/phantomjs/wiki/Supported-Web-Standards and
|
||||
* http://code.google.com/p/phantomjs/issues/detail?id=273) This won't render
|
||||
* OpenLayers maps rendered through the webglrenderer.
|
||||
*
|
||||
* In parts based upon this gist: https://gist.github.com/crazy4groovy/3160121
|
||||
*/
|
||||
(function() { // global closure
|
||||
|
||||
var page = require('webpage').create(), // imports
|
||||
fs = require('fs'),
|
||||
system = require('system'),
|
||||
// arguments
|
||||
baseExamplesUrl = system.args[1],
|
||||
exampleDir = system.args[2],
|
||||
// various settings
|
||||
ignoreFiles = [
|
||||
'index.html'
|
||||
],
|
||||
intervalMillisecs = 25,
|
||||
renderMillisecs = 2000,
|
||||
// basic variables
|
||||
curDir = fs.workingDirectory,
|
||||
exampleDirList = fs.list(exampleDir),
|
||||
pageindex = 0,
|
||||
fileName = '',
|
||||
htmlFiles = [],
|
||||
lenHtmlFiles = 0,
|
||||
loadInProgress = false;
|
||||
|
||||
// simple object with helper functions
|
||||
var util = {
|
||||
/**
|
||||
* Returns the basename of a file given a path.
|
||||
*/
|
||||
baseName: function(path) {
|
||||
var parts = path.split(fs.separator);
|
||||
return parts[parts.length - 1];
|
||||
},
|
||||
/**
|
||||
* Super basic test whether a file can be considered a HTML-file.
|
||||
*/
|
||||
isHtmlFile: function(filename) {
|
||||
return (/\.html?$/).test(filename);
|
||||
},
|
||||
/**
|
||||
* Appends a slash to given string if it isn't there already.
|
||||
*/
|
||||
appendSlash: function(str) {
|
||||
return ((/\/$/).test(str)) ? str : str + '/';
|
||||
},
|
||||
/**
|
||||
* Generates an URL out of given baseurl and path.
|
||||
*/
|
||||
buildUrl: function(baseurl, path) {
|
||||
var name = util.baseName(path),
|
||||
mode = 'raw';
|
||||
return util.appendSlash(baseurl) + name + '?mode=' + mode;
|
||||
},
|
||||
/**
|
||||
* Simple progressbar logger that uses our globals pageindex & lenHtmlFiles.
|
||||
*/
|
||||
logProgress: function() {
|
||||
var doneSymbol = '-',
|
||||
todoSymbol = ' ',
|
||||
currentSymbol = '>',
|
||||
barStrLeft = '[',
|
||||
barStrRight = ']',
|
||||
progresStep = 5, // one doneSymbol equals this percentage
|
||||
totalSteps = Math.round(100 / progresStep),
|
||||
ratio = (lenHtmlFiles === 0) ? 0 : (pageindex / lenHtmlFiles),
|
||||
percent = (ratio === 0) ? 0 : ratio * 100,
|
||||
normalizedNumDone = Math.floor(ratio * totalSteps),
|
||||
normalizedNumTodo = totalSteps - normalizedNumDone,
|
||||
progressLine = '',
|
||||
i = 0;
|
||||
// the progress bar
|
||||
progressLine += barStrLeft;
|
||||
for (; i < normalizedNumDone; i++) {
|
||||
progressLine += doneSymbol;
|
||||
}
|
||||
for (i = 0; i < normalizedNumTodo; i++) {
|
||||
progressLine += (i === 0) ? currentSymbol : todoSymbol;
|
||||
}
|
||||
progressLine += barStrRight;
|
||||
// the percentage information
|
||||
// pad if necessary
|
||||
if (percent < 10) {
|
||||
progressLine += ' ';
|
||||
} else if (percent < 100) {
|
||||
progressLine += ' ';
|
||||
}
|
||||
progressLine += ' ' + percent.toFixed(1) + ' % done';
|
||||
// additional information
|
||||
if (fileName !== '') {
|
||||
progressLine += ', ' + util.baseName(fileName) + '';
|
||||
}
|
||||
console.log(progressLine);
|
||||
}
|
||||
};
|
||||
|
||||
// iterate over all files in examples directory
|
||||
// and find the HTML files.
|
||||
for (var i = 0; i < exampleDirList.length; i++) {
|
||||
var fullpath = exampleDir + fs.separator + exampleDirList[i];
|
||||
if (fs.isFile(fullpath) && util.isHtmlFile(fullpath) &&
|
||||
ignoreFiles.indexOf(util.baseName(fullpath)) === -1) {
|
||||
//TODO: make this more async (i.e. pop on/off stack WHILE rending pages)
|
||||
htmlFiles.push(fullpath);
|
||||
}
|
||||
}
|
||||
lenHtmlFiles = htmlFiles.length;
|
||||
|
||||
console.log('Capturing ' + lenHtmlFiles + ' example screenshots.');
|
||||
|
||||
// The main interval function that is executed regularly and renders a
|
||||
// page to a file
|
||||
var interval = setInterval(function() {
|
||||
if (!loadInProgress && pageindex < lenHtmlFiles) {
|
||||
util.logProgress();
|
||||
fileName = htmlFiles[pageindex];
|
||||
page.viewportSize = { width: 800, height: 600 };
|
||||
page.clipRect = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: page.viewportSize.width,
|
||||
height: page.viewportSize.height
|
||||
};
|
||||
page.open(util.buildUrl(baseExamplesUrl, htmlFiles[pageindex]));
|
||||
}
|
||||
if (pageindex == lenHtmlFiles) {
|
||||
util.logProgress();
|
||||
console.log(lenHtmlFiles + ' screenshots captured.');
|
||||
phantom.exit();
|
||||
}
|
||||
}, intervalMillisecs);
|
||||
|
||||
// set loadInProgress flag so we only process one image at time.
|
||||
page.onLoadStarted = function() {
|
||||
loadInProgress = true;
|
||||
};
|
||||
|
||||
// When the page is loaded, render it to an image
|
||||
page.onLoadFinished = function() {
|
||||
var dest = exampleDir + fs.separator + util.baseName(fileName) + '.png';
|
||||
window.setTimeout(function() {
|
||||
loadInProgress = false;
|
||||
page.render(dest); // actually render the page.
|
||||
pageindex++;
|
||||
}, renderMillisecs);
|
||||
};
|
||||
|
||||
})(); // eof global closure
|
||||
69
bin/loader_hosted_examples.js
Normal file
69
bin/loader_hosted_examples.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* This loader is used for the hosted examples. It is used in place of the
|
||||
* development loader (examples/loader.js).
|
||||
*
|
||||
* The loader loads ol.js and the example's script in "production" mode; it
|
||||
* loads Closure Library's base.js, ol-deps.js, the example's "goog.require"
|
||||
* script, and the example's script in "development" mode.
|
||||
*
|
||||
* The ol.js and ol-deps.js scripts are built using OpenLayers's Makefile. They are
|
||||
* located in the ../build/ directory, relative to this script.
|
||||
*
|
||||
* The script must be named loader.js.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <script src="../loader.js?id=my-demo"></script>
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
var i, pair;
|
||||
|
||||
var href = window.location.href, start, end, paramsString, pairs,
|
||||
pageParams = {};
|
||||
if (href.indexOf('?') > 0) {
|
||||
start = href.indexOf('?') + 1;
|
||||
end = href.indexOf('#') > 0 ? href.indexOf('#') : href.length;
|
||||
paramsString = href.substring(start, end);
|
||||
pairs = paramsString.split(/[&;]/);
|
||||
for (i = 0; i < pairs.length; ++i) {
|
||||
pair = pairs[i].split('=');
|
||||
if (pair[0]) {
|
||||
pageParams[decodeURIComponent(pair[0])] =
|
||||
decodeURIComponent(pair[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var src, index, search, chunks, scriptParams = {};
|
||||
for (i = scripts.length - 1; i >= 0; --i) {
|
||||
src = scripts[i].getAttribute('src');
|
||||
if (~(index = src.indexOf('loader.js?'))) {
|
||||
search = src.substr(index + 10);
|
||||
chunks = search ? search.split('&') : [];
|
||||
for (i = chunks.length - 1; i >= 0; --i) {
|
||||
pair = chunks[i].split('=');
|
||||
if (pair[0]) {
|
||||
scriptParams[decodeURIComponent(pair[0])] =
|
||||
decodeURIComponent(pair[1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var raw = pageParams.mode && pageParams.mode.toLowerCase() === 'raw';
|
||||
|
||||
var scriptId = encodeURIComponent(scriptParams.id);
|
||||
if (!raw) {
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="../build/ol.js"></scr' + 'ipt>');
|
||||
} else {
|
||||
window.CLOSURE_NO_DEPS = true; // we've got our own deps file
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="../closure-library/closure/goog/base.js"></scr' + 'ipt>');
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="../build/ol-deps.js"></scr' + 'ipt>');
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="' + scriptId + '-require.js"></scr' + 'ipt>');
|
||||
}
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="' + scriptId + '.js"></scr' + 'ipt>');
|
||||
}());
|
||||
39
bin/split-example.py
Normal file
39
bin/split-example.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def split_example_file(example, dst_dir):
|
||||
lines = open(example, 'rU').readlines()
|
||||
|
||||
target_lines = []
|
||||
target_require_lines = []
|
||||
|
||||
found_requires = False
|
||||
found_code = False
|
||||
for line in lines:
|
||||
m = re.match(r'goog.require\(\'(.*)\'\);', line)
|
||||
if m:
|
||||
found_requires = True
|
||||
target_require_lines.append(line)
|
||||
elif found_requires:
|
||||
if found_code or line not in ('\n', '\r\n'):
|
||||
found_code = True
|
||||
target_lines.append(line)
|
||||
|
||||
target = open(
|
||||
os.path.join(dst_dir, os.path.basename(example)), 'wb')
|
||||
target_require = open(
|
||||
os.path.join(dst_dir, os.path.basename(example)
|
||||
.replace('.js', '-require.js')),
|
||||
'wb')
|
||||
|
||||
target.writelines(target_lines)
|
||||
target.close()
|
||||
|
||||
target_require.writelines(target_require_lines)
|
||||
target_require.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
split_example_file(*sys.argv[1:])
|
||||
@@ -2,59 +2,6 @@
|
||||
|
||||
### Next release
|
||||
|
||||
#### Removal of the renderer option for maps
|
||||
|
||||
The `renderer` option has been removed from the `Map` constructor. The purpose of this change is to avoid bundling code in your application that you do not need. Previously, code for both the Canvas and WebGL renderers was included in all applications - even though most people only use one renderer. The `Map` constructor now gives you a Canvas (2D) based renderer. If you want to try the WebGL renderer, you can import the constructor from `ol/WebGLMap`.
|
||||
|
||||
Old code:
|
||||
```js
|
||||
import Map from 'ol/Map';
|
||||
|
||||
const canvasMap = new Map({
|
||||
renderer: ['canvas']
|
||||
// other options...
|
||||
});
|
||||
|
||||
const webglMap = new Map({
|
||||
renderer: ['webgl']
|
||||
// other options...
|
||||
});
|
||||
```
|
||||
|
||||
New code:
|
||||
```js
|
||||
import Map from 'ol/Map';
|
||||
import WebGLMap from 'ol/WebGLMap';
|
||||
|
||||
const canvasMap = new Map({
|
||||
// options...
|
||||
});
|
||||
|
||||
const webglMap = new WebGLMap({
|
||||
// options...
|
||||
});
|
||||
```
|
||||
|
||||
#### Removal of ol.FeatureStyleFunction
|
||||
|
||||
The signature of the vector style function passed to the feature has changed. The function now always takes the `feature` and the `resolution` as arguments, the `feature` is no longer bound to `this`.
|
||||
|
||||
Old code:
|
||||
```js
|
||||
feature.setStyle(function(resolution) {
|
||||
var text = this.get('name');
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
New code:
|
||||
```js
|
||||
feature.setStyle(function(feature, resolution) {
|
||||
var text = feature.get('name');
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
#### Changed behavior of the `Draw` interaction
|
||||
|
||||
For better drawing experience, two changes were made to the behavior of the Draw interaction:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# 4.6.5
|
||||
|
||||
The v4.6.5 release fixes a hit detection issue when `declutter: true` is set on an `ol.layer.VectorTile`.
|
||||
|
||||
## Fixes
|
||||
|
||||
* [#7669](https://github.com/openlayers/openlayers/pull/7559) - Use declutter tree only for text and image replays ([@ahocevar](https://github.com/ahocevar))
|
||||
45
config/example.json
Normal file
45
config/example.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"exports": [],
|
||||
"src": [
|
||||
"src/**/*.js",
|
||||
"build/ol.ext/*.js",
|
||||
"build/examples/{{id}}.js"
|
||||
],
|
||||
"compile": {
|
||||
"js": [
|
||||
"externs/olx.js",
|
||||
"externs/oli.js"
|
||||
],
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/cartodb.js",
|
||||
"externs/bootstrap.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/esrijson.js",
|
||||
"externs/example.js",
|
||||
"externs/geojson.js",
|
||||
"externs/jquery-1.9.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"*"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"lintChecks",
|
||||
"analyzerChecks",
|
||||
"missingProvide",
|
||||
"unknownDefines"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"rewrite_polyfills": "false",
|
||||
"compilation_level": "ADVANCED",
|
||||
"warning_level": "VERBOSE",
|
||||
"output_wrapper": "(function(){%output%})();",
|
||||
"use_types_for_optimization": true,
|
||||
"manage_closure_dependencies": true
|
||||
}
|
||||
}
|
||||
45
config/examples-all.json
Normal file
45
config/examples-all.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"exports": [],
|
||||
"src": [
|
||||
"src/**/*.js",
|
||||
"build/ol.ext/*.js",
|
||||
"build/compiled-examples/all.js"
|
||||
],
|
||||
"compile": {
|
||||
"js": [
|
||||
"externs/olx.js",
|
||||
"externs/oli.js"
|
||||
],
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/bootstrap.js",
|
||||
"externs/cartodb.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/esrijson.js",
|
||||
"externs/example.js",
|
||||
"externs/geojson.js",
|
||||
"externs/jquery-1.9.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"*"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"lintChecks",
|
||||
"analyzerChecks",
|
||||
"unusedLocalVariables"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"rewrite_polyfills": "false",
|
||||
"compilation_level": "ADVANCED",
|
||||
"warning_level": "VERBOSE",
|
||||
"output_wrapper": "(function(){%output%})();",
|
||||
"use_types_for_optimization": true,
|
||||
"manage_closure_dependencies": true
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
{{{ extraHead.local }}}
|
||||
{{{ css.tag }}}
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
|
||||
<script src="./resources/zeroclipboard/ZeroClipboard.min.js"></script>
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
@@ -52,12 +52,13 @@
|
||||
<div class="span12">
|
||||
<p id="shortdesc">{{ shortdesc }}</p>
|
||||
<div id="docs">{{ md docs }}</div>
|
||||
<div id="api-links">Related API documentation: {{{ js.apiHtml }}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div id="source-controls">
|
||||
<a id="copy-button" data-clipboard-target="#example-source"><i class="fa fa-clipboard"></i> Copy</a>
|
||||
<a id="copy-button"><i class="fa fa-clipboard"></i> Copy</a>
|
||||
<a id="codepen-button"><i class="fa fa-codepen"></i> Edit</a>
|
||||
</div>
|
||||
<form method="POST" id="codepen-form" target="_blank" action="https://codepen.io/pen/define/">
|
||||
@@ -104,7 +105,7 @@
|
||||
var branchSearch = url.match(/\/([^\/]*)\/examples\//);
|
||||
var cookieText = 'dismissed=-' + latestVersion + '-';
|
||||
var dismissed = document.cookie.indexOf(cookieText) != -1;
|
||||
if (branchSearch && !dismissed && /^v[0-9\.]*$/.test(branchSearch[1]) && '{{ olVersion }}' != latestVersion) {
|
||||
if (!dismissed && /^v[0-9\.]*$/.test(branchSearch[1]) && '{{ olVersion }}' != latestVersion) {
|
||||
var link = url.replace(branchSearch[0], '/latest/examples/');
|
||||
fetch(link, {method: 'head'}).then(function(response) {
|
||||
var a = document.getElementById('latest-link');
|
||||
@@ -11,7 +11,8 @@
|
||||
"excludePattern": "(^|\\/|\\\\)_",
|
||||
"include": [
|
||||
"src",
|
||||
"externs/oli.js"
|
||||
"externs/oli.js",
|
||||
"externs/olx.js"
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/**
|
||||
* Define an @api tag
|
||||
* @param {Object} dictionary The tag dictionary.
|
||||
*/
|
||||
exports.defineTags = function(dictionary) {
|
||||
dictionary.defineTag('api', {
|
||||
@@ -9,31 +8,32 @@ exports.defineTags = function(dictionary) {
|
||||
canHaveName: false,
|
||||
onTagged: function(doclet, tag) {
|
||||
includeTypes(doclet);
|
||||
doclet.stability = 'stable';
|
||||
doclet.stability = "stable";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Based on @api annotations, and assuming that items with no @api annotation
|
||||
* should not be documented, this plugin removes undocumented symbols
|
||||
* from the documentation.
|
||||
*/
|
||||
|
||||
const api = [];
|
||||
const classes = {};
|
||||
const types = {};
|
||||
var api = [];
|
||||
var classes = {};
|
||||
var types = {};
|
||||
|
||||
function hasApiMembers(doclet) {
|
||||
return doclet.longname.split('#')[0] == this.longname;
|
||||
}
|
||||
|
||||
function includeAugments(doclet) {
|
||||
const augments = doclet.augments;
|
||||
var augments = doclet.augments;
|
||||
if (augments) {
|
||||
let cls;
|
||||
for (let i = augments.length - 1; i >= 0; --i) {
|
||||
var cls;
|
||||
for (var i = augments.length - 1; i >= 0; --i) {
|
||||
cls = classes[augments[i]];
|
||||
if (cls) {
|
||||
includeAugments(cls);
|
||||
@@ -68,7 +68,7 @@ function includeAugments(doclet) {
|
||||
|
||||
function extractTypes(item) {
|
||||
item.type.names.forEach(function(type) {
|
||||
const match = type.match(/^(.*<)?([^>]*)>?$/);
|
||||
var match = type.match(/^(.*<)?([^>]*)>?$/);
|
||||
if (match) {
|
||||
types[match[2]] = true;
|
||||
}
|
||||
@@ -86,6 +86,7 @@ function includeTypes(doclet) {
|
||||
types[doclet.meta.code.name] = true;
|
||||
}
|
||||
if (doclet.type && doclet.meta.code.type == 'MemberExpression') {
|
||||
// types in olx.js
|
||||
extractTypes(doclet);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +94,12 @@ function includeTypes(doclet) {
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
const doclet = e.doclet;
|
||||
var doclet = e.doclet;
|
||||
// Keep track of api items - needed in parseComplete to determine classes
|
||||
// with api members.
|
||||
if (doclet.meta.filename == 'olx.js' && doclet.kind == 'typedef') {
|
||||
doclet.undocumented = false;
|
||||
}
|
||||
if (doclet.stability) {
|
||||
api.push(doclet);
|
||||
}
|
||||
@@ -108,9 +114,9 @@ exports.handlers = {
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
const doclets = e.doclets;
|
||||
for (let i = doclets.length - 1; i >= 0; --i) {
|
||||
const doclet = doclets[i];
|
||||
var doclets = e.doclets;
|
||||
for (var i = doclets.length - 1; i >= 0; --i) {
|
||||
var doclet = doclets[i];
|
||||
if (doclet.stability || doclet.namespace_) {
|
||||
if (doclet.kind == 'class') {
|
||||
includeAugments(doclet);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
const events = {};
|
||||
const classes = {};
|
||||
var events = {};
|
||||
var classes = {};
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
const doclet = e.doclet;
|
||||
let cls;
|
||||
var doclet = e.doclet;
|
||||
var cls;
|
||||
if (doclet.kind == 'event') {
|
||||
cls = doclet.longname.split('#')[0];
|
||||
if (!(cls in events)) {
|
||||
@@ -18,8 +18,8 @@ exports.handlers = {
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
const doclets = e.doclets;
|
||||
let doclet, i, ii, j, jj, event, fires;
|
||||
var doclets = e.doclets;
|
||||
var doclet, i, ii, j, jj, event, fires;
|
||||
for (i = 0, ii = doclets.length - 1; i < ii; ++i) {
|
||||
doclet = doclets[i];
|
||||
if (doclet.fires) {
|
||||
@@ -28,7 +28,7 @@ exports.handlers = {
|
||||
for (j = 0, jj = doclet.fires.length; j < jj; ++j) {
|
||||
event = doclet.fires[j].replace('event:', '');
|
||||
if (events[event]) {
|
||||
fires.push.apply(fires, events[event]);
|
||||
fires.push.apply(fires, events[event]);
|
||||
} else {
|
||||
fires.push(doclet.fires[j]);
|
||||
}
|
||||
|
||||
@@ -19,16 +19,16 @@ exports.defineTags = function(dictionary) {
|
||||
};
|
||||
|
||||
|
||||
const lookup = {};
|
||||
const incompleteByClass = {};
|
||||
const keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment',
|
||||
'stability'];
|
||||
var lookup = {};
|
||||
var incompleteByClass = {};
|
||||
var keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment',
|
||||
'stability'];
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
const doclet = e.doclet;
|
||||
let incompletes;
|
||||
var doclet = e.doclet;
|
||||
var incompletes;
|
||||
if (!(doclet.longname in lookup)) {
|
||||
lookup[doclet.longname] = [];
|
||||
}
|
||||
@@ -45,9 +45,9 @@ exports.handlers = {
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
let ancestors, candidate, candidates, doclet, i, j, k, l, key;
|
||||
let incompleteDoclet, stability, incomplete, incompletes;
|
||||
const doclets = e.doclets;
|
||||
var ancestors, candidate, candidates, doclet, i, j, k, l, key;
|
||||
var incompleteDoclet, stability, incomplete, incompletes;
|
||||
var doclets = e.doclets;
|
||||
for (i = doclets.length - 1; i >= 0; --i) {
|
||||
doclet = doclets[i];
|
||||
if (doclet.augments) {
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const classes = {};
|
||||
const observables = {};
|
||||
var classes = {};
|
||||
var observables = {};
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
const doclet = e.doclet;
|
||||
var doclet = e.doclet;
|
||||
if (doclet.kind == 'class') {
|
||||
classes[doclet.longname] = doclet;
|
||||
}
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
const doclets = e.doclets;
|
||||
let cls, doclet, event, i, ii, observable;
|
||||
var doclets = e.doclets;
|
||||
var cls, doclet, event, i, ii, observable;
|
||||
for (i = 0, ii = doclets.length - 1; i < ii; ++i) {
|
||||
doclet = doclets[i];
|
||||
cls = classes[doclet.longname.split('#')[0]];
|
||||
if (typeof doclet.observable == 'string' && cls) {
|
||||
let name = doclet.name.replace(/^[sg]et/, '');
|
||||
var name = doclet.name.replace(/^[sg]et/, '');
|
||||
name = name.substr(0, 1).toLowerCase() + name.substr(1);
|
||||
const key = doclet.longname.split('#')[0] + '#' + name;
|
||||
var key = doclet.longname.split('#')[0] + '#' + name;
|
||||
doclet.observable = key;
|
||||
if (!observables[key]) {
|
||||
observables[key] = {};
|
||||
@@ -27,7 +27,7 @@ exports.handlers = {
|
||||
observable = observables[key];
|
||||
observable.name = name;
|
||||
observable.readonly = typeof observable.readonly == 'boolean' ?
|
||||
observable.readonly : true;
|
||||
observable.readonly : true;
|
||||
if (doclet.name.indexOf('get') === 0) {
|
||||
observable.type = doclet.returns[0].type;
|
||||
observable.description = doclet.returns[0].description;
|
||||
|
||||
@@ -1,27 +1,49 @@
|
||||
/*
|
||||
* Converts olx.js @type annotations into properties of the previous @typedef.
|
||||
* Changes @enum annotations into @typedef.
|
||||
*/
|
||||
|
||||
var lastOlxTypedef = null;
|
||||
var olxTypes = {};
|
||||
// names of the olx typenames
|
||||
var olxTypeNames = [];
|
||||
// types that are undefined or typedefs containing undefined
|
||||
let undefinedLikes = null;
|
||||
var undefinedLikes = null;
|
||||
|
||||
function addSubparams(params) {
|
||||
for (var j = 0, jj = params.length; j < jj; ++j) {
|
||||
var param = params[j];
|
||||
var types = param.type.names;
|
||||
for (var k = 0, kk = types.length; k < kk; ++k) {
|
||||
var name = types[k];
|
||||
if (name in olxTypes) {
|
||||
param.subparams = olxTypes[name];
|
||||
// TODO addSubparams(param.subparams);
|
||||
// TODO Do we need to support multiple object literal types per
|
||||
// param?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the description of the param if it is required.
|
||||
* @param {Object} doclet The doclet.
|
||||
* @returns {Object} The modified doclet.
|
||||
* Changes the description of the param, if it is found to be a required
|
||||
* option of an olxTypeName.
|
||||
*/
|
||||
function markRequiredIfNeeded(doclet) {
|
||||
const memberof = doclet.memberof;
|
||||
if (!memberof) {
|
||||
function markRequiredIfNeeded(doclet){
|
||||
var memberof = doclet.memberof;
|
||||
// only check doclets that belong to an olxTypeName
|
||||
if (!memberof || olxTypeNames.indexOf(memberof) == -1) {
|
||||
return doclet;
|
||||
}
|
||||
|
||||
const types = doclet.type.names;
|
||||
let isRequiredParam = true;
|
||||
var types = doclet.type.names;
|
||||
var isRequiredParam = true;
|
||||
|
||||
// iterate over all types that are like-undefined (see above for explanation)
|
||||
for (let idx = undefinedLikes.length - 1; idx >= 0; idx--) {
|
||||
const undefinedLike = undefinedLikes[idx];
|
||||
for (var idx = undefinedLikes.length - 1; idx >= 0; idx--) {
|
||||
var undefinedLike = undefinedLikes[idx];
|
||||
// … if the current types contains a type that is undefined-like,
|
||||
// it is not required.
|
||||
if (types.indexOf(undefinedLike) != -1) {
|
||||
@@ -30,9 +52,9 @@ function markRequiredIfNeeded(doclet) {
|
||||
}
|
||||
|
||||
if (isRequiredParam) {
|
||||
const reqSnippet = '<span class="required-option">Required.</span></p>';
|
||||
const endsWithP = /<\/p>$/i;
|
||||
let description = doclet.description;
|
||||
var reqSnippet = '<span class="required-option">Required.</span></p>';
|
||||
var endsWithP = /<\/p>$/i;
|
||||
var description = doclet.description;
|
||||
if (description && endsWithP.test(description)) {
|
||||
description = description.replace(endsWithP, ' ' + reqSnippet);
|
||||
} else if (doclet.description === undefined) {
|
||||
@@ -47,14 +69,13 @@ function markRequiredIfNeeded(doclet) {
|
||||
* Iterates over all doclets and finds the names of types that contain
|
||||
* undefined. Stores the names in the global variable undefinedLikes, so
|
||||
* that e.g. markRequiredIfNeeded can use these.
|
||||
* @param {Array} doclets The doclets.
|
||||
*/
|
||||
function findTypesLikeUndefined(doclets) {
|
||||
undefinedLikes = ['undefined']; // include type 'undefined' explicitly
|
||||
for (let i = doclets.length - 1; i >= 0; --i) {
|
||||
const doclet = doclets[i];
|
||||
if (doclet.kind === 'typedef') {
|
||||
const types = doclet.type.names;
|
||||
for (var i = doclets.length - 1; i >= 0; --i) {
|
||||
var doclet = doclets[i];
|
||||
if(doclet.kind === 'typedef') {
|
||||
var types = doclet.type.names;
|
||||
if (types.indexOf('undefined') !== -1) {
|
||||
// the typedef contains 'undefined', so it self is undefinedLike.
|
||||
undefinedLikes.push(doclet.longname);
|
||||
@@ -66,8 +87,20 @@ function findTypesLikeUndefined(doclets) {
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
const doclet = e.doclet;
|
||||
if (doclet.isEnum) {
|
||||
var doclet = e.doclet;
|
||||
if (doclet.meta.filename == 'olx.js') {
|
||||
if (doclet.kind == 'typedef') {
|
||||
lastOlxTypedef = doclet;
|
||||
olxTypeNames.push(doclet.longname);
|
||||
olxTypes[doclet.longname] = [];
|
||||
doclet.properties = [];
|
||||
} else if (lastOlxTypedef && doclet.memberof == lastOlxTypedef.longname) {
|
||||
lastOlxTypedef.properties.push(doclet);
|
||||
olxTypes[lastOlxTypedef.longname].push(doclet);
|
||||
} else {
|
||||
lastOlxTypedef = null;
|
||||
}
|
||||
} else if (doclet.isEnum) {
|
||||
// We never export enums, so we document them like typedefs
|
||||
doclet.kind = 'typedef';
|
||||
delete doclet.isEnum;
|
||||
@@ -75,10 +108,15 @@ exports.handlers = {
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
const doclets = e.doclets;
|
||||
var doclets = e.doclets;
|
||||
findTypesLikeUndefined(doclets);
|
||||
for (let i = doclets.length - 1; i >= 0; --i) {
|
||||
markRequiredIfNeeded(doclets[i]);
|
||||
for (var i = doclets.length - 1; i >= 0; --i) {
|
||||
var doclet = doclets[i];
|
||||
var params = doclet.params;
|
||||
if (params) {
|
||||
addSubparams(params);
|
||||
}
|
||||
markRequiredIfNeeded(doclet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,152 +1,152 @@
|
||||
/*global env: true */
|
||||
const template = require('jsdoc/lib/jsdoc/template');
|
||||
const fs = require('jsdoc/lib/jsdoc/fs');
|
||||
const path = require('jsdoc/lib/jsdoc/path');
|
||||
const taffy = require('taffydb').taffy;
|
||||
const handle = require('jsdoc/lib/jsdoc/util/error').handle;
|
||||
const helper = require('jsdoc/lib/jsdoc/util/templateHelper');
|
||||
const _ = require('underscore');
|
||||
const htmlsafe = helper.htmlsafe;
|
||||
const linkto = helper.linkto;
|
||||
const resolveAuthorLinks = helper.resolveAuthorLinks;
|
||||
const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
const outdir = env.opts.destination;
|
||||
|
||||
let view;
|
||||
let data;
|
||||
var template = require('jsdoc/lib/jsdoc/template'),
|
||||
fs = require('jsdoc/lib/jsdoc/fs'),
|
||||
path = require('jsdoc/lib/jsdoc/path'),
|
||||
taffy = require('taffydb').taffy,
|
||||
handle = require('jsdoc/lib/jsdoc/util/error').handle,
|
||||
helper = require('jsdoc/lib/jsdoc/util/templateHelper'),
|
||||
_ = require('underscore'),
|
||||
htmlsafe = helper.htmlsafe,
|
||||
linkto = helper.linkto,
|
||||
resolveAuthorLinks = helper.resolveAuthorLinks,
|
||||
scopeToPunc = helper.scopeToPunc,
|
||||
hasOwnProp = Object.prototype.hasOwnProperty,
|
||||
data,
|
||||
view,
|
||||
outdir = env.opts.destination;
|
||||
|
||||
function find(spec) {
|
||||
return helper.find(data, spec);
|
||||
return helper.find(data, spec);
|
||||
}
|
||||
|
||||
function tutoriallink(tutorial) {
|
||||
return helper.toTutorial(tutorial, null, {tag: 'em', classname: 'disabled', prefix: 'Tutorial: '});
|
||||
return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' });
|
||||
}
|
||||
|
||||
function getAncestorLinks(doclet) {
|
||||
return helper.getAncestorLinks(data, doclet);
|
||||
return helper.getAncestorLinks(data, doclet);
|
||||
}
|
||||
|
||||
function hashToLink(doclet, hash) {
|
||||
if (!/^(#.+)/.test(hash)) {
|
||||
return hash;
|
||||
}
|
||||
if ( !/^(#.+)/.test(hash) ) { return hash; }
|
||||
|
||||
let url = helper.createLink(doclet);
|
||||
var url = helper.createLink(doclet);
|
||||
|
||||
url = url.replace(/(#.+|$)/, hash);
|
||||
return '<a href="' + url + '">' + hash + '</a>';
|
||||
url = url.replace(/(#.+|$)/, hash);
|
||||
return '<a href="' + url + '">' + hash + '</a>';
|
||||
}
|
||||
|
||||
function needsSignature(doclet) {
|
||||
let needsSig = false;
|
||||
var needsSig = false;
|
||||
|
||||
// function and class definitions always get a signature
|
||||
if (doclet.kind === 'function' || doclet.kind === 'class') {
|
||||
needsSig = true;
|
||||
} else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names &&
|
||||
doclet.type.names.length) {
|
||||
// typedefs that contain functions get a signature, too
|
||||
for (let i = 0, l = doclet.type.names.length; i < l; i++) {
|
||||
if (doclet.type.names[i].toLowerCase() === 'function') {
|
||||
// function and class definitions always get a signature
|
||||
if (doclet.kind === 'function' || doclet.kind === 'class') {
|
||||
needsSig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// typedefs that contain functions get a signature, too
|
||||
else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names &&
|
||||
doclet.type.names.length) {
|
||||
for (var i = 0, l = doclet.type.names.length; i < l; i++) {
|
||||
if (doclet.type.names[i].toLowerCase() === 'function') {
|
||||
needsSig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return needsSig;
|
||||
return needsSig;
|
||||
}
|
||||
|
||||
function addSignatureParams(f) {
|
||||
const params = helper.getSignatureParams(f, 'optional');
|
||||
var params = helper.getSignatureParams(f, 'optional');
|
||||
|
||||
f.signature = (f.signature || '') + '(' + params.join(', ') + ')';
|
||||
f.signature = (f.signature || '') + '('+params.join(', ')+')';
|
||||
}
|
||||
|
||||
function addSignatureReturns(f) {
|
||||
const returnTypes = helper.getSignatureReturns(f);
|
||||
var returnTypes = helper.getSignatureReturns(f);
|
||||
|
||||
f.signature = '<span class="signature">' + (f.signature || '') + '</span>';
|
||||
f.signature = '<span class="signature">'+(f.signature || '') + '</span>';
|
||||
|
||||
if (returnTypes.length) {
|
||||
f.signature += '<span class="glyphicon glyphicon-circle-arrow-right"></span><span class="type-signature returnType">' + (returnTypes.length ? '{' + returnTypes.join('|') + '}' : '') + '</span>';
|
||||
}
|
||||
if (returnTypes.length) {
|
||||
f.signature += '<span class="glyphicon glyphicon-circle-arrow-right"></span><span class="type-signature returnType">'+(returnTypes.length ? '{'+returnTypes.join('|')+'}' : '')+'</span>';
|
||||
}
|
||||
}
|
||||
|
||||
function addSignatureTypes(f) {
|
||||
const types = helper.getSignatureTypes(f);
|
||||
var types = helper.getSignatureTypes(f);
|
||||
|
||||
f.signature = (f.signature || '') + '<span class="type-signature">' + (types.length ? ' :' + types.join('|') : '') + ' </span>';
|
||||
f.signature = (f.signature || '') + '<span class="type-signature">'+(types.length? ' :'+types.join('|') : '')+' </span>';
|
||||
}
|
||||
|
||||
function shortenPaths(files, commonPrefix) {
|
||||
// always use forward slashes
|
||||
const regexp = new RegExp('\\\\', 'g');
|
||||
// always use forward slashes
|
||||
var regexp = new RegExp('\\\\', 'g');
|
||||
|
||||
Object.keys(files).forEach(function(file) {
|
||||
files[file].shortened = files[file].resolved.replace(commonPrefix, '')
|
||||
.replace(regexp, '/');
|
||||
});
|
||||
Object.keys(files).forEach(function(file) {
|
||||
files[file].shortened = files[file].resolved.replace(commonPrefix, '')
|
||||
.replace(regexp, '/');
|
||||
});
|
||||
|
||||
return files;
|
||||
return files;
|
||||
}
|
||||
|
||||
function resolveSourcePath(filepath) {
|
||||
return path.resolve(process.cwd(), filepath);
|
||||
return path.resolve(process.cwd(), filepath);
|
||||
}
|
||||
|
||||
function getPathFromDoclet(doclet) {
|
||||
if (!doclet.meta) {
|
||||
return;
|
||||
}
|
||||
if (!doclet.meta) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filepath = doclet.meta.path && doclet.meta.path !== 'null' ?
|
||||
doclet.meta.path + '/' + doclet.meta.filename.split(/[\/\\]/).pop() :
|
||||
doclet.meta.filename;
|
||||
var filepath = doclet.meta.path && doclet.meta.path !== 'null' ?
|
||||
doclet.meta.path + '/' + doclet.meta.filename.split(/[\/\\]/).pop() :
|
||||
doclet.meta.filename;
|
||||
|
||||
return filepath;
|
||||
return filepath;
|
||||
}
|
||||
|
||||
function generate(title, docs, filename, resolveLinks) {
|
||||
resolveLinks = resolveLinks === false ? false : true;
|
||||
resolveLinks = resolveLinks === false ? false : true;
|
||||
|
||||
const docData = {
|
||||
filename: filename,
|
||||
title: title,
|
||||
docs: docs,
|
||||
packageInfo: (find({kind: 'package'}) || []) [0]
|
||||
};
|
||||
var docData = {
|
||||
filename: filename,
|
||||
title: title,
|
||||
docs: docs,
|
||||
packageInfo: ( find({kind: 'package'}) || [] ) [0]
|
||||
};
|
||||
|
||||
const outpath = path.join(outdir, filename);
|
||||
let html = view.render('container.tmpl', docData);
|
||||
var outpath = path.join(outdir, filename),
|
||||
html = view.render('container.tmpl', docData);
|
||||
|
||||
if (resolveLinks) {
|
||||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
||||
}
|
||||
if (resolveLinks) {
|
||||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
||||
}
|
||||
|
||||
fs.writeFileSync(outpath, html, 'utf8');
|
||||
fs.writeFileSync(outpath, html, 'utf8');
|
||||
}
|
||||
|
||||
function generateSourceFiles(sourceFiles) {
|
||||
Object.keys(sourceFiles).forEach(function(file) {
|
||||
let source;
|
||||
// links are keyed to the shortened path in each doclet's `meta.filename` property
|
||||
const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
|
||||
helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
|
||||
Object.keys(sourceFiles).forEach(function(file) {
|
||||
var source;
|
||||
// links are keyed to the shortened path in each doclet's `meta.filename` property
|
||||
var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
|
||||
helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
|
||||
|
||||
try {
|
||||
source = {
|
||||
kind: 'source',
|
||||
code: helper.htmlsafe(fs.readFileSync(sourceFiles[file].resolved, 'utf8'))
|
||||
};
|
||||
} catch (e) {
|
||||
handle(e);
|
||||
}
|
||||
try {
|
||||
source = {
|
||||
kind: 'source',
|
||||
code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, 'utf8') )
|
||||
};
|
||||
}
|
||||
catch(e) {
|
||||
handle(e);
|
||||
}
|
||||
|
||||
generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile,
|
||||
false);
|
||||
});
|
||||
generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile,
|
||||
false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,348 +161,346 @@ function generateSourceFiles(sourceFiles) {
|
||||
* @param {Array.<module:jsdoc/doclet.Doclet>} modules - The array of module doclets to search.
|
||||
*/
|
||||
function attachModuleSymbols(doclets, modules) {
|
||||
const symbols = {};
|
||||
var symbols = {};
|
||||
|
||||
// build a lookup table
|
||||
doclets.forEach(function(symbol) {
|
||||
symbols[symbol.longname] = symbol;
|
||||
});
|
||||
// build a lookup table
|
||||
doclets.forEach(function(symbol) {
|
||||
symbols[symbol.longname] = symbol;
|
||||
});
|
||||
|
||||
modules.forEach(function(module) {
|
||||
if (symbols[module.longname]) {
|
||||
module.module = symbols[module.longname];
|
||||
module.module.name = module.module.name.replace('module:', 'require("') + '")';
|
||||
}
|
||||
});
|
||||
return modules.map(function(module) {
|
||||
if (symbols[module.longname]) {
|
||||
module.module = symbols[module.longname];
|
||||
module.module.name = module.module.name.replace('module:', 'require("') + '")';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the navigation sidebar.
|
||||
* @param {object} members The members that will be used to create the sidebar.
|
||||
* @param {Array<Object>} members.classes Classes.
|
||||
* @param {Array<Object>} members.externals Externals.
|
||||
* @param {Array<Object>} members.globals Globals.
|
||||
* @param {Array<Object>} members.mixins Mixins.
|
||||
* @param {Array<Object>} members.modules Modules.
|
||||
* @param {Array<Object>} members.namespaces Namespaces.
|
||||
* @param {Array<Object>} members.tutorials Tutorials.
|
||||
* @param {Array<Object>} members.events Events.
|
||||
* @param {array<object>} members.classes
|
||||
* @param {array<object>} members.externals
|
||||
* @param {array<object>} members.globals
|
||||
* @param {array<object>} members.mixins
|
||||
* @param {array<object>} members.modules
|
||||
* @param {array<object>} members.namespaces
|
||||
* @param {array<object>} members.tutorials
|
||||
* @param {array<object>} members.events
|
||||
* @return {string} The HTML for the navigation sidebar.
|
||||
*/
|
||||
function buildNav(members) {
|
||||
const nav = [];
|
||||
// merge namespaces and classes, then sort
|
||||
const merged = members.namespaces.concat(members.classes);
|
||||
merged.sort(function(a, b) {
|
||||
if (a.longname > b.longname) {
|
||||
return 1;
|
||||
}
|
||||
if (a.longname < b.longname) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
_.each(merged, function(v) {
|
||||
// exclude interfaces from sidebar
|
||||
if (v.interface !== true) {
|
||||
if (v.kind == 'namespace') {
|
||||
nav.push({
|
||||
type: 'namespace',
|
||||
longname: v.longname,
|
||||
name: v.name,
|
||||
members: find({
|
||||
kind: 'member',
|
||||
memberof: v.longname
|
||||
}),
|
||||
methods: find({
|
||||
kind: 'function',
|
||||
memberof: v.longname
|
||||
}),
|
||||
typedefs: find({
|
||||
kind: 'typedef',
|
||||
memberof: v.longname
|
||||
}),
|
||||
events: find({
|
||||
kind: 'event',
|
||||
memberof: v.longname
|
||||
})
|
||||
});
|
||||
var nav = [];
|
||||
// merge namespaces and classes, then sort
|
||||
var merged = members.namespaces.concat(members.classes);
|
||||
merged.sort(function (a, b) {
|
||||
if (a.longname > b.longname)
|
||||
return 1;
|
||||
if (a.longname < b.longname)
|
||||
return -1;
|
||||
return 0;
|
||||
});
|
||||
_.each(merged, function (v) {
|
||||
// exclude 'olx' and interfaces from sidebar
|
||||
if (v.longname.indexOf('olx') !== 0 && v.interface !== true) {
|
||||
if (v.kind == 'namespace') {
|
||||
nav.push({
|
||||
type: 'namespace',
|
||||
longname: v.longname,
|
||||
name: v.name,
|
||||
members: find({
|
||||
kind: 'member',
|
||||
memberof: v.longname
|
||||
}),
|
||||
methods: find({
|
||||
kind: 'function',
|
||||
memberof: v.longname
|
||||
}),
|
||||
typedefs: find({
|
||||
kind: 'typedef',
|
||||
memberof: v.longname
|
||||
}),
|
||||
events: find({
|
||||
kind: 'event',
|
||||
memberof: v.longname
|
||||
})
|
||||
});
|
||||
}
|
||||
if (v.kind == 'class') {
|
||||
nav.push({
|
||||
type: 'class',
|
||||
longname: v.longname,
|
||||
name: v.name,
|
||||
members: find({
|
||||
kind: 'member',
|
||||
memberof: v.longname
|
||||
}),
|
||||
methods: find({
|
||||
kind: 'function',
|
||||
memberof: v.longname
|
||||
}),
|
||||
typedefs: find({
|
||||
kind: 'typedef',
|
||||
memberof: v.longname
|
||||
}),
|
||||
fires: v.fires,
|
||||
events: find({
|
||||
kind: 'event',
|
||||
memberof: v.longname
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
if (v.kind == 'class') {
|
||||
nav.push({
|
||||
type: 'class',
|
||||
longname: v.longname,
|
||||
name: v.name,
|
||||
members: find({
|
||||
kind: 'member',
|
||||
memberof: v.longname
|
||||
}),
|
||||
methods: find({
|
||||
kind: 'function',
|
||||
memberof: v.longname
|
||||
}),
|
||||
typedefs: find({
|
||||
kind: 'typedef',
|
||||
memberof: v.longname
|
||||
}),
|
||||
fires: v.fires,
|
||||
events: find({
|
||||
kind: 'event',
|
||||
memberof: v.longname
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return nav;
|
||||
});
|
||||
return nav;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object} taffyData See <http://taffydb.com/>.
|
||||
* @param {Object} opts Options.
|
||||
* @param {Object} tutorials Tutorials.
|
||||
@param {TAFFY} taffyData See <http://taffydb.com/>.
|
||||
@param {object} opts
|
||||
@param {Tutorial} tutorials
|
||||
*/
|
||||
exports.publish = function(taffyData, opts, tutorials) {
|
||||
data = taffyData;
|
||||
data = taffyData;
|
||||
|
||||
const conf = env.conf.templates || {};
|
||||
conf['default'] = conf['default'] || {};
|
||||
var conf = env.conf.templates || {};
|
||||
conf['default'] = conf['default'] || {};
|
||||
|
||||
const templatePath = opts.template;
|
||||
view = new template.Template(templatePath + '/tmpl');
|
||||
var templatePath = opts.template;
|
||||
view = new template.Template(templatePath + '/tmpl');
|
||||
|
||||
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
|
||||
// doesn't try to hand them out later
|
||||
const indexUrl = helper.getUniqueFilename('index');
|
||||
// don't call registerLink() on this one! 'index' is also a valid longname
|
||||
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
|
||||
// doesn't try to hand them out later
|
||||
var indexUrl = helper.getUniqueFilename('index');
|
||||
// don't call registerLink() on this one! 'index' is also a valid longname
|
||||
|
||||
const globalUrl = helper.getUniqueFilename('global');
|
||||
helper.registerLink('global', globalUrl);
|
||||
var globalUrl = helper.getUniqueFilename('global');
|
||||
helper.registerLink('global', globalUrl);
|
||||
|
||||
// set up templating
|
||||
view.layout = 'layout.tmpl';
|
||||
// set up templating
|
||||
view.layout = 'layout.tmpl';
|
||||
|
||||
// set up tutorials for helper
|
||||
helper.setTutorials(tutorials);
|
||||
// set up tutorials for helper
|
||||
helper.setTutorials(tutorials);
|
||||
|
||||
data = helper.prune(data);
|
||||
data.sort('longname, version, since');
|
||||
helper.addEventListeners(data);
|
||||
data = helper.prune(data);
|
||||
data.sort('longname, version, since');
|
||||
helper.addEventListeners(data);
|
||||
|
||||
let sourceFiles = {};
|
||||
const sourceFilePaths = [];
|
||||
data().each(function(doclet) {
|
||||
doclet.attribs = '';
|
||||
var sourceFiles = {};
|
||||
var sourceFilePaths = [];
|
||||
data().each(function(doclet) {
|
||||
doclet.attribs = '';
|
||||
|
||||
if (doclet.examples) {
|
||||
doclet.examples = doclet.examples.map(function(example) {
|
||||
let caption, code;
|
||||
if (doclet.examples) {
|
||||
doclet.examples = doclet.examples.map(function(example) {
|
||||
var caption, code;
|
||||
|
||||
if (example.match(/^\s*<caption>([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
|
||||
caption = RegExp.$1;
|
||||
code = RegExp.$3;
|
||||
if (example.match(/^\s*<caption>([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
|
||||
caption = RegExp.$1;
|
||||
code = RegExp.$3;
|
||||
}
|
||||
|
||||
return {
|
||||
caption: caption || '',
|
||||
code: code || example
|
||||
};
|
||||
});
|
||||
}
|
||||
if (doclet.see) {
|
||||
doclet.see.forEach(function(seeItem, i) {
|
||||
doclet.see[i] = hashToLink(doclet, seeItem);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
caption: caption || '',
|
||||
code: code || example
|
||||
};
|
||||
});
|
||||
}
|
||||
if (doclet.see) {
|
||||
doclet.see.forEach(function(seeItem, i) {
|
||||
doclet.see[i] = hashToLink(doclet, seeItem);
|
||||
});
|
||||
}
|
||||
// build a list of source files
|
||||
var sourcePath;
|
||||
var resolvedSourcePath;
|
||||
if (doclet.meta) {
|
||||
sourcePath = getPathFromDoclet(doclet);
|
||||
resolvedSourcePath = resolveSourcePath(sourcePath);
|
||||
sourceFiles[sourcePath] = {
|
||||
resolved: resolvedSourcePath,
|
||||
shortened: null
|
||||
};
|
||||
sourceFilePaths.push(resolvedSourcePath);
|
||||
}
|
||||
});
|
||||
|
||||
// build a list of source files
|
||||
let sourcePath;
|
||||
let resolvedSourcePath;
|
||||
if (doclet.meta) {
|
||||
sourcePath = getPathFromDoclet(doclet);
|
||||
resolvedSourcePath = resolveSourcePath(sourcePath);
|
||||
sourceFiles[sourcePath] = {
|
||||
resolved: resolvedSourcePath,
|
||||
shortened: null
|
||||
};
|
||||
sourceFilePaths.push(resolvedSourcePath);
|
||||
}
|
||||
});
|
||||
fs.mkPath(outdir);
|
||||
|
||||
fs.mkPath(outdir);
|
||||
// copy the template's static files to outdir
|
||||
var fromDir = path.join(templatePath, 'static');
|
||||
var staticFiles = fs.ls(fromDir, 3);
|
||||
|
||||
// copy the template's static files to outdir
|
||||
const fromDir = path.join(templatePath, 'static');
|
||||
const staticFiles = fs.ls(fromDir, 3);
|
||||
|
||||
staticFiles.forEach(function(fileName) {
|
||||
const toDir = fs.toDir(fileName.replace(fromDir, outdir));
|
||||
fs.mkPath(toDir);
|
||||
fs.copyFileSync(fileName, toDir);
|
||||
});
|
||||
|
||||
// copy user-specified static files to outdir
|
||||
let staticFilePaths;
|
||||
let staticFileFilter;
|
||||
let staticFileScanner;
|
||||
if (conf['default'].staticFiles) {
|
||||
staticFilePaths = conf['default'].staticFiles.paths || [];
|
||||
staticFileFilter = new (require('jsdoc/lib/jsdoc/src/filter')).Filter(conf['default'].staticFiles);
|
||||
staticFileScanner = new (require('jsdoc/lib/jsdoc/src/scanner')).Scanner();
|
||||
|
||||
staticFilePaths.forEach(function(filePath) {
|
||||
const extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter);
|
||||
|
||||
extraStaticFiles.forEach(function(fileName) {
|
||||
const sourcePath = fs.statSync(filePath).isDirectory() ? filePath :
|
||||
path.dirname(filePath);
|
||||
const toDir = fs.toDir(fileName.replace(sourcePath, outdir));
|
||||
staticFiles.forEach(function(fileName) {
|
||||
var toDir = fs.toDir( fileName.replace(fromDir, outdir) );
|
||||
fs.mkPath(toDir);
|
||||
fs.copyFileSync(fileName, toDir);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (sourceFilePaths.length) {
|
||||
sourceFiles = shortenPaths(sourceFiles, path.commonPrefix(sourceFilePaths));
|
||||
}
|
||||
data().each(function(doclet) {
|
||||
const url = helper.createLink(doclet);
|
||||
helper.registerLink(doclet.longname, url);
|
||||
// copy user-specified static files to outdir
|
||||
var staticFilePaths;
|
||||
var staticFileFilter;
|
||||
var staticFileScanner;
|
||||
if (conf['default'].staticFiles) {
|
||||
staticFilePaths = conf['default'].staticFiles.paths || [];
|
||||
staticFileFilter = new (require('jsdoc/lib/jsdoc/src/filter')).Filter(conf['default'].staticFiles);
|
||||
staticFileScanner = new (require('jsdoc/lib/jsdoc/src/scanner')).Scanner();
|
||||
|
||||
// replace the filename with a shortened version of the full path
|
||||
let docletPath;
|
||||
if (doclet.meta) {
|
||||
docletPath = getPathFromDoclet(doclet);
|
||||
docletPath = sourceFiles[docletPath].shortened;
|
||||
if (docletPath) {
|
||||
doclet.meta.filename = docletPath;
|
||||
}
|
||||
}
|
||||
});
|
||||
staticFilePaths.forEach(function(filePath) {
|
||||
var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter);
|
||||
|
||||
data().each(function(doclet) {
|
||||
const url = helper.longnameToUrl[doclet.longname];
|
||||
|
||||
if (url.indexOf('#') > -1) {
|
||||
doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
|
||||
} else {
|
||||
doclet.id = doclet.name;
|
||||
extraStaticFiles.forEach(function(fileName) {
|
||||
var sourcePath = fs.statSync(filePath).isDirectory() ? filePath :
|
||||
path.dirname(filePath);
|
||||
var toDir = fs.toDir( fileName.replace(sourcePath, outdir) );
|
||||
fs.mkPath(toDir);
|
||||
fs.copyFileSync(fileName, toDir);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (needsSignature(doclet)) {
|
||||
addSignatureParams(doclet);
|
||||
addSignatureReturns(doclet);
|
||||
if (sourceFilePaths.length) {
|
||||
sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) );
|
||||
}
|
||||
});
|
||||
data().each(function(doclet) {
|
||||
var url = helper.createLink(doclet);
|
||||
helper.registerLink(doclet.longname, url);
|
||||
|
||||
// do this after the urls have all been generated
|
||||
data().each(function(doclet) {
|
||||
doclet.ancestors = getAncestorLinks(doclet);
|
||||
// replace the filename with a shortened version of the full path
|
||||
var docletPath;
|
||||
if (doclet.meta) {
|
||||
docletPath = getPathFromDoclet(doclet);
|
||||
docletPath = sourceFiles[docletPath].shortened;
|
||||
if (docletPath) {
|
||||
doclet.meta.filename = docletPath;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (doclet.kind === 'member') {
|
||||
addSignatureTypes(doclet);
|
||||
data().each(function(doclet) {
|
||||
var url = helper.longnameToUrl[doclet.longname];
|
||||
|
||||
if (url.indexOf('#') > -1) {
|
||||
doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
|
||||
}
|
||||
else {
|
||||
doclet.id = doclet.name;
|
||||
}
|
||||
|
||||
if ( needsSignature(doclet) ) {
|
||||
addSignatureParams(doclet);
|
||||
addSignatureReturns(doclet);
|
||||
}
|
||||
});
|
||||
|
||||
// do this after the urls have all been generated
|
||||
data().each(function(doclet) {
|
||||
doclet.ancestors = getAncestorLinks(doclet);
|
||||
|
||||
if (doclet.kind === 'member') {
|
||||
addSignatureTypes(doclet);
|
||||
}
|
||||
|
||||
if (doclet.kind === 'constant') {
|
||||
addSignatureTypes(doclet);
|
||||
doclet.kind = 'member';
|
||||
}
|
||||
});
|
||||
|
||||
var members = helper.getMembers(data);
|
||||
members.tutorials = tutorials.children;
|
||||
|
||||
// add template helpers
|
||||
view.find = find;
|
||||
view.linkto = linkto;
|
||||
view.resolveAuthorLinks = resolveAuthorLinks;
|
||||
view.tutoriallink = tutoriallink;
|
||||
view.htmlsafe = htmlsafe;
|
||||
view.members = members; //@davidshimjs: To make navigation for customizing
|
||||
|
||||
// once for all
|
||||
view.nav = buildNav(members);
|
||||
attachModuleSymbols( find({ kind: ['class', 'function'], longname: {left: 'module:'} }),
|
||||
members.modules );
|
||||
|
||||
// only output pretty-printed source files if requested; do this before generating any other
|
||||
// pages, so the other pages can link to the source files
|
||||
if (conf['default'].outputSourceFiles) {
|
||||
generateSourceFiles(sourceFiles);
|
||||
}
|
||||
|
||||
if (doclet.kind === 'constant') {
|
||||
addSignatureTypes(doclet);
|
||||
doclet.kind = 'member';
|
||||
}
|
||||
});
|
||||
if (members.globals.length) { generate('Global', [{kind: 'globalobj'}], globalUrl); }
|
||||
|
||||
const members = helper.getMembers(data);
|
||||
members.tutorials = tutorials.children;
|
||||
// index page displays information from package.json and lists files
|
||||
var files = find({kind: 'file'});
|
||||
|
||||
// add template helpers
|
||||
view.find = find;
|
||||
view.linkto = linkto;
|
||||
view.resolveAuthorLinks = resolveAuthorLinks;
|
||||
view.tutoriallink = tutoriallink;
|
||||
view.htmlsafe = htmlsafe;
|
||||
view.members = members; //@davidshimjs: To make navigation for customizing
|
||||
|
||||
// once for all
|
||||
view.nav = buildNav(members);
|
||||
attachModuleSymbols(find({kind: ['class', 'function'], longname: {left: 'module:'}}),
|
||||
members.modules);
|
||||
|
||||
// only output pretty-printed source files if requested; do this before generating any other
|
||||
// pages, so the other pages can link to the source files
|
||||
if (conf['default'].outputSourceFiles) {
|
||||
generateSourceFiles(sourceFiles);
|
||||
}
|
||||
|
||||
if (members.globals.length) {
|
||||
generate('Global', [{kind: 'globalobj'}], globalUrl);
|
||||
}
|
||||
|
||||
// index page displays information from package.json and lists files
|
||||
const files = find({kind: 'file'});
|
||||
|
||||
generate('Index',
|
||||
[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}].concat(files),
|
||||
generate('Index',
|
||||
[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}].concat(files),
|
||||
indexUrl);
|
||||
|
||||
// set up the lists that we'll use to generate pages
|
||||
const classes = taffy(members.classes);
|
||||
const modules = taffy(members.modules);
|
||||
const namespaces = taffy(members.namespaces);
|
||||
const mixins = taffy(members.mixins);
|
||||
const externals = taffy(members.externals);
|
||||
// set up the lists that we'll use to generate pages
|
||||
var classes = taffy(members.classes);
|
||||
var modules = taffy(members.modules);
|
||||
var namespaces = taffy(members.namespaces);
|
||||
var mixins = taffy(members.mixins);
|
||||
var externals = taffy(members.externals);
|
||||
|
||||
for (const longname in helper.longnameToUrl) {
|
||||
if (hasOwnProp.call(helper.longnameToUrl, longname)) {
|
||||
const myClasses = helper.find(classes, {longname: longname});
|
||||
if (myClasses.length) {
|
||||
generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]);
|
||||
}
|
||||
for (var longname in helper.longnameToUrl) {
|
||||
if ( hasOwnProp.call(helper.longnameToUrl, longname) ) {
|
||||
var myClasses = helper.find(classes, {longname: longname});
|
||||
if (myClasses.length) {
|
||||
generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]);
|
||||
}
|
||||
|
||||
const myModules = helper.find(modules, {longname: longname});
|
||||
if (myModules.length) {
|
||||
generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]);
|
||||
}
|
||||
var myModules = helper.find(modules, {longname: longname});
|
||||
if (myModules.length) {
|
||||
generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]);
|
||||
}
|
||||
|
||||
const myNamespaces = helper.find(namespaces, {longname: longname});
|
||||
if (myNamespaces.length) {
|
||||
generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]);
|
||||
}
|
||||
var myNamespaces = helper.find(namespaces, {longname: longname});
|
||||
if (myNamespaces.length) {
|
||||
generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]);
|
||||
}
|
||||
|
||||
const myMixins = helper.find(mixins, {longname: longname});
|
||||
if (myMixins.length) {
|
||||
generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]);
|
||||
}
|
||||
var myMixins = helper.find(mixins, {longname: longname});
|
||||
if (myMixins.length) {
|
||||
generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]);
|
||||
}
|
||||
|
||||
const myExternals = helper.find(externals, {longname: longname});
|
||||
if (myExternals.length) {
|
||||
generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]);
|
||||
}
|
||||
var myExternals = helper.find(externals, {longname: longname});
|
||||
if (myExternals.length) {
|
||||
generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move the tutorial functions to templateHelper.js
|
||||
function generateTutorial(title, tutorial, filename) {
|
||||
const tutorialData = {
|
||||
title: title,
|
||||
header: tutorial.title,
|
||||
content: tutorial.parse(),
|
||||
children: tutorial.children
|
||||
};
|
||||
// TODO: move the tutorial functions to templateHelper.js
|
||||
function generateTutorial(title, tutorial, filename) {
|
||||
var tutorialData = {
|
||||
title: title,
|
||||
header: tutorial.title,
|
||||
content: tutorial.parse(),
|
||||
children: tutorial.children
|
||||
};
|
||||
|
||||
let html = view.render('tutorial.tmpl', tutorialData);
|
||||
// yes, you can use {@link} in tutorials too!
|
||||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
||||
var tutorialPath = path.join(outdir, filename),
|
||||
html = view.render('tutorial.tmpl', tutorialData);
|
||||
|
||||
const tutorialPath = path.join(outdir, filename);
|
||||
fs.writeFileSync(tutorialPath, html, 'utf8');
|
||||
}
|
||||
// yes, you can use {@link} in tutorials too!
|
||||
html = helper.resolveLinks(html); // turn {@link foo} into <a href="foodoc.html">foo</a>
|
||||
|
||||
// tutorials can have only one parent so there is no risk for loops
|
||||
function saveChildren(node) {
|
||||
node.children.forEach(function(child) {
|
||||
generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name));
|
||||
saveChildren(child);
|
||||
});
|
||||
}
|
||||
saveChildren(tutorials);
|
||||
fs.writeFileSync(tutorialPath, html, 'utf8');
|
||||
}
|
||||
|
||||
// tutorials can have only one parent so there is no risk for loops
|
||||
function saveChildren(node) {
|
||||
node.children.forEach(function(child) {
|
||||
generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name));
|
||||
saveChildren(child);
|
||||
});
|
||||
}
|
||||
saveChildren(tutorials);
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ exports.defineTags = function(dictionary) {
|
||||
|
||||
dictionary.defineTag('api', {
|
||||
onTagged: function(doclet, tag) {
|
||||
doclet.api = true;
|
||||
doclet.api = tag.text || 'experimental';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
|
||||
const DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i;
|
||||
var DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i;
|
||||
|
||||
|
||||
/**
|
||||
@@ -19,9 +19,9 @@ exports.defineTags = function(dictionary) {
|
||||
canHaveType: true,
|
||||
mustHaveValue: true,
|
||||
onTagged: function(doclet, tag) {
|
||||
const types = tag.value.type.names;
|
||||
var types = tag.value.type.names;
|
||||
if (types.length === 1 && types[0] === 'boolean') {
|
||||
const match = tag.value.description.match(DEFAULT_VALUE);
|
||||
var match = tag.value.description.match(DEFAULT_VALUE);
|
||||
if (match) {
|
||||
doclet.define = {
|
||||
default: match[1] === 'true'
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* @fileoverview Generates JSON output based on exportable symbols (those with
|
||||
* an api tag) and boolean defines (with a define tag and a default value).
|
||||
*/
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
/**
|
||||
@@ -15,52 +15,67 @@ const path = require('path');
|
||||
exports.publish = function(data, opts) {
|
||||
|
||||
function getTypes(data) {
|
||||
const types = [];
|
||||
var types = [];
|
||||
data.forEach(function(name) {
|
||||
types.push(name.replace(/^function$/, 'Function'));
|
||||
});
|
||||
return types;
|
||||
}
|
||||
|
||||
// get all doclets with the "api" property or define (excluding events)
|
||||
const classes = {};
|
||||
const docs = data(
|
||||
[
|
||||
{define: {isObject: true}},
|
||||
function() {
|
||||
if (this.kind == 'class') {
|
||||
if (!('extends' in this) || typeof this.api == 'boolean') {
|
||||
classes[this.longname] = this;
|
||||
return true;
|
||||
// get all doclets with the "api" property or define (excluding events) or
|
||||
// with olx namespace
|
||||
var classes = {};
|
||||
var docs = data(
|
||||
[
|
||||
{define: {isObject: true}},
|
||||
function() {
|
||||
if (this.kind == 'class') {
|
||||
if (!('extends' in this) || typeof this.api == 'string') {
|
||||
classes[this.longname] = this;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (typeof this.api == 'boolean' ||
|
||||
return (typeof this.api == 'string' ||
|
||||
this.meta && (/[\\\/]externs$/).test(this.meta.path));
|
||||
}
|
||||
],
|
||||
{kind: {'!is': 'file'}},
|
||||
{kind: {'!is': 'event'}}).get();
|
||||
}
|
||||
],
|
||||
{kind: {'!is': 'file'}},
|
||||
{kind: {'!is': 'event'}}).get();
|
||||
|
||||
// get symbols data, filter out those that are members of private classes
|
||||
const symbols = [];
|
||||
const defines = [];
|
||||
const typedefs = [];
|
||||
const externs = [];
|
||||
let base = [];
|
||||
const augments = {};
|
||||
const symbolsByName = {};
|
||||
var symbols = [];
|
||||
var defines = [];
|
||||
var typedefs = [];
|
||||
var externs = [];
|
||||
var base = [];
|
||||
var augments = {};
|
||||
var symbolsByName = {};
|
||||
docs.filter(function(doc) {
|
||||
let include = true;
|
||||
const constructor = doc.memberof;
|
||||
if (constructor && constructor.substr(-1) === '_' && constructor.indexOf('module:') === -1) {
|
||||
var include = true;
|
||||
var constructor = doc.memberof;
|
||||
if (constructor && constructor.substr(-1) === '_') {
|
||||
assert.strictEqual(doc.inherited, true,
|
||||
'Unexpected export on private class: ' + doc.longname);
|
||||
'Unexpected export on private class: ' + doc.longname);
|
||||
include = false;
|
||||
}
|
||||
return include;
|
||||
}).forEach(function(doc) {
|
||||
const isExterns = (/[\\\/]externs$/).test(doc.meta.path);
|
||||
if (doc.define) {
|
||||
var isExterns = (/[\\\/]externs$/).test(doc.meta.path);
|
||||
if (isExterns && doc.longname.indexOf('olx.') === 0) {
|
||||
if (doc.kind == 'typedef') {
|
||||
typedefs.push({
|
||||
name: doc.longname,
|
||||
types: ['{}']
|
||||
});
|
||||
} else {
|
||||
var typedef = typedefs[typedefs.length - 1];
|
||||
var type = typedef.types[0];
|
||||
typedef.types[0] = type
|
||||
.replace(/\}$/, ', ' + doc.longname.split('#')[1] +
|
||||
': (' + getTypes(doc.type.names).join('|') + ')}')
|
||||
.replace('{, ', '{');
|
||||
}
|
||||
} else if (doc.define) {
|
||||
defines.push({
|
||||
name: doc.longname,
|
||||
description: doc.description,
|
||||
@@ -73,10 +88,11 @@ exports.publish = function(data, opts) {
|
||||
types: getTypes(doc.type.names)
|
||||
});
|
||||
} else {
|
||||
const symbol = {
|
||||
var symbol = {
|
||||
name: doc.longname,
|
||||
kind: doc.kind,
|
||||
description: doc.classdesc || doc.description,
|
||||
stability: doc.api,
|
||||
path: path.join(doc.meta.path, doc.meta.filename)
|
||||
};
|
||||
if (doc.augments) {
|
||||
@@ -89,9 +105,9 @@ exports.publish = function(data, opts) {
|
||||
symbol.types = getTypes(doc.type.names);
|
||||
}
|
||||
if (doc.params) {
|
||||
const params = [];
|
||||
var params = [];
|
||||
doc.params.forEach(function(param) {
|
||||
const paramInfo = {
|
||||
var paramInfo = {
|
||||
name: param.name
|
||||
};
|
||||
params.push(paramInfo);
|
||||
@@ -126,10 +142,10 @@ exports.publish = function(data, opts) {
|
||||
});
|
||||
}
|
||||
|
||||
const target = isExterns ? externs : (doc.api ? symbols : base);
|
||||
const existingSymbol = symbolsByName[symbol.name];
|
||||
var target = isExterns ? externs : (doc.api ? symbols : base);
|
||||
var existingSymbol = symbolsByName[symbol.name];
|
||||
if (existingSymbol) {
|
||||
const idx = target.indexOf(existingSymbol);
|
||||
var idx = target.indexOf(existingSymbol);
|
||||
target.splice(idx, 1);
|
||||
}
|
||||
target.push(symbol);
|
||||
@@ -153,13 +169,13 @@ exports.publish = function(data, opts) {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
process.stdout.write(
|
||||
JSON.stringify({
|
||||
symbols: symbols,
|
||||
defines: defines,
|
||||
typedefs: typedefs,
|
||||
externs: externs,
|
||||
base: base
|
||||
}, null, 2));
|
||||
JSON.stringify({
|
||||
symbols: symbols,
|
||||
defines: defines,
|
||||
typedefs: typedefs,
|
||||
externs: externs,
|
||||
base: base
|
||||
}, null, 2));
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
exports.defineTags = function(dictionary) {
|
||||
|
||||
const classTag = dictionary.lookUp('class');
|
||||
var classTag = dictionary.lookUp('class');
|
||||
dictionary.defineTag('interface', {
|
||||
mustHaveValue: false,
|
||||
onTagged: function(doclet, tag) {
|
||||
|
||||
4
config/ol-debug.json
Normal file
4
config/ol-debug.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"umd": true
|
||||
}
|
||||
38
config/ol.json
Normal file
38
config/ol.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"umd": true,
|
||||
"compile": {
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/cartodb.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/esrijson.js",
|
||||
"externs/geojson.js",
|
||||
"externs/oli.js",
|
||||
"externs/olx.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js"
|
||||
],
|
||||
"define": [
|
||||
"ol.DEBUG_WEBGL=false"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"*"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"lintChecks",
|
||||
"analyzerChecks"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"rewrite_polyfills": "false",
|
||||
"compilation_level": "ADVANCED",
|
||||
"warning_level": "VERBOSE",
|
||||
"use_types_for_optimization": true,
|
||||
"manage_closure_dependencies": true,
|
||||
"create_source_map": "build/ol.js.map",
|
||||
"source_map_format": "V3"
|
||||
}
|
||||
}
|
||||
3
config/readme.md
Normal file
3
config/readme.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Configuration Files
|
||||
|
||||
This directory includes configuration files for the build scripts in and documentation templates.
|
||||
@@ -1,14 +0,0 @@
|
||||
const webpack = require('webpack');
|
||||
const MinifyPlugin = require('babel-minify-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
filename: 'build/ol.js'
|
||||
},
|
||||
devtool: 'source-map',
|
||||
plugins: [
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
new MinifyPlugin()
|
||||
]
|
||||
};
|
||||
18
css/ol.css
18
css/ol.css
@@ -44,10 +44,10 @@
|
||||
}
|
||||
.ol-selectable {
|
||||
-webkit-touch-callout: default;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
-webkit-user-select: auto;
|
||||
-moz-user-select: auto;
|
||||
-ms-user-select: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
.ol-grabbing {
|
||||
cursor: -webkit-grabbing;
|
||||
@@ -179,6 +179,9 @@
|
||||
.ol-attribution.ol-collapsed ul {
|
||||
display: none;
|
||||
}
|
||||
.ol-attribution.ol-logo-only ul {
|
||||
display: block;
|
||||
}
|
||||
.ol-attribution:not(.ol-collapsed) {
|
||||
background: rgba(255,255,255,0.8);
|
||||
}
|
||||
@@ -189,10 +192,17 @@
|
||||
height: 1.1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.ol-attribution.ol-logo-only {
|
||||
background: transparent;
|
||||
bottom: .4em;
|
||||
height: 1.1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.ol-attribution.ol-uncollapsible img {
|
||||
margin-top: -.2em;
|
||||
max-height: 1.6em;
|
||||
}
|
||||
.ol-attribution.ol-logo-only button,
|
||||
.ol-attribution.ol-uncollapsible button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
18
src/ol/ol.css → dist/ol-debug.css
vendored
18
src/ol/ol.css → dist/ol-debug.css
vendored
@@ -44,10 +44,10 @@
|
||||
}
|
||||
.ol-selectable {
|
||||
-webkit-touch-callout: default;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
-webkit-user-select: auto;
|
||||
-moz-user-select: auto;
|
||||
-ms-user-select: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
.ol-grabbing {
|
||||
cursor: -webkit-grabbing;
|
||||
@@ -179,6 +179,9 @@
|
||||
.ol-attribution.ol-collapsed ul {
|
||||
display: none;
|
||||
}
|
||||
.ol-attribution.ol-logo-only ul {
|
||||
display: block;
|
||||
}
|
||||
.ol-attribution:not(.ol-collapsed) {
|
||||
background: rgba(255,255,255,0.8);
|
||||
}
|
||||
@@ -189,10 +192,17 @@
|
||||
height: 1.1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.ol-attribution.ol-logo-only {
|
||||
background: transparent;
|
||||
bottom: .4em;
|
||||
height: 1.1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.ol-attribution.ol-uncollapsible img {
|
||||
margin-top: -.2em;
|
||||
max-height: 1.6em;
|
||||
}
|
||||
.ol-attribution.ol-logo-only button,
|
||||
.ol-attribution.ol-uncollapsible button {
|
||||
display: none;
|
||||
}
|
||||
96548
dist/ol-debug.js
vendored
Normal file
96548
dist/ol-debug.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/ol.css
vendored
Normal file
1
dist/ol.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.ol-box{box-sizing:border-box;border-radius:2px;border:2px solid #00f}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width}.ol-overlay-container{will-change:left,right,top,bottom}.ol-unsupported{display:none}.ol-unselectable,.ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px}.ol-control:hover{background-color:rgba(255,255,255,.6)}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}@media print{.ol-control{display:none}}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:focus,.ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7)}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em)}.ol-attribution ul{margin:0;padding:0 .5em;font-size:.7rem;line-height:1.375em;color:#000;text-shadow:0 0 2px #fff}.ol-attribution li{display:inline;list-style:none;line-height:inherit}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button,.ol-attribution ul{display:inline-block}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution.ol-logo-only ul{display:block}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0;height:1.1em;line-height:1em}.ol-attribution.ol-logo-only{background:0 0;bottom:.4em;height:1.1em;line-height:1em}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-logo-only button,.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:inline-block}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:1px;left:2px;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move}
|
||||
1075
dist/ol.js
vendored
Normal file
1075
dist/ol.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -43,7 +43,7 @@ Unknown `serverType` configured.
|
||||
|
||||
### 10
|
||||
|
||||
The default `geometryFunction` can only handle `ol/geom/Point` geometries.
|
||||
The default `geometryFunction` can only handle `ol.geom.Point` geometries.
|
||||
|
||||
### 11
|
||||
|
||||
@@ -139,7 +139,7 @@ Invalid geometry layout. Must be `XY`, `XYZ`, `XYM` or `XYZM`.
|
||||
|
||||
### 36
|
||||
|
||||
Unknown SRS type. Expected `"name"`.
|
||||
Unknown SRS type. Expected `"name"` or `"EPSG"`.
|
||||
|
||||
### 37
|
||||
|
||||
@@ -165,6 +165,14 @@ Expected an `ol.style.Style` or an array of `ol.style.Style`.
|
||||
|
||||
Expected `layers` to be an array or an `ol.Collection`.
|
||||
|
||||
### 44
|
||||
|
||||
`logo.href` should be a string.
|
||||
|
||||
### 45
|
||||
|
||||
`logo.src` should be a string.
|
||||
|
||||
### 46
|
||||
|
||||
Incorrect format for `renderer` option.
|
||||
|
||||
@@ -176,6 +176,8 @@ The minimum config file looks like this:
|
||||
"ol.ENABLE_WEBGL=false"
|
||||
],
|
||||
"js": [
|
||||
"node_modules/openlayers/src/ol/typedefs.js",
|
||||
"node_modules/openlayers/externs/olx.js",
|
||||
"node_modules/openlayers/externs/oli.js"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
@@ -226,6 +228,8 @@ Here is a version of `config.json` with more compilation checks enabled:
|
||||
"ol.ENABLE_WEBGL=false"
|
||||
],
|
||||
"js": [
|
||||
"node_modules/openlayers/src/ol/typedefs.js",
|
||||
"node_modules/openlayers/externs/olx.js",
|
||||
"node_modules/openlayers/externs/oli.js"
|
||||
],
|
||||
"jscomp_error": [
|
||||
|
||||
@@ -56,6 +56,7 @@ Creating a custom build requires writing a build configuration file. The format
|
||||
"externs/esrijson.js",
|
||||
"externs/geojson.js",
|
||||
"externs/oli.js",
|
||||
"externs/olx.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js"
|
||||
@@ -168,6 +169,8 @@ and re-run the build script. The build size should now be smaller.
|
||||
|
||||
The Closure documentation explains that "externs" are for external names used in the code being compiled. The compiler includes externs for built-ins such as `document`. The `externs` directory of the OpenLayers code includes files for all those used in some part of the library. For example, if you use Bing Maps, you should include the Bing externs file in the `externs` section of the config file.
|
||||
|
||||
`oli.js` and `olx.js` are externs files for the OpenLayers API. For example `olx.js` includes extern definitions for OpenLayers's constructor options. `closure-compiler.js` fixes any issues that may arise with a specific compiler version. You should always use these three files as externs when creating custom builds.
|
||||
|
||||
### Other compiler options
|
||||
|
||||
There are a couple of other compiler options in the config file above. `manage_closure_dependencies` and `rewrite_polyfills` should always be used.
|
||||
@@ -205,6 +208,7 @@ Now let's try a more complicated example: [`heatmaps-earthquakes`](https://openl
|
||||
"externs/closure-compiler.js",
|
||||
"externs/esrijson.js",
|
||||
"externs/geojson.js",
|
||||
"externs/olx.js",
|
||||
"externs/oli.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
|
||||
@@ -107,7 +107,7 @@ In case you are creating a custom build of OpenLayers and do not need the reproj
|
||||
See [Custom builds](custom-builds.html#defines) tutorial on how to do this.
|
||||
|
||||
### Triangulation precision threshold
|
||||
The default [triangulation error threshold](#dynamic-triangulation) in pixels is given by `ERROR_THRESHOLD` (0.5 pixel).
|
||||
The default [triangulation error threshold](#dynamic-triangulation) in pixels is given by `ol.DEFAULT_RASTER_REPROJECTION_ERROR_THRESHOLD` (0.5 pixel).
|
||||
In case a different threshold needs to be defined for different sources, the `reprojectionErrorThreshold` option can be passed when constructing the tile image source.
|
||||
|
||||
###Limiting visibility of reprojected map by extent
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/*
|
||||
* Jugl.js -- JavaScript Template Library
|
||||
*
|
||||
* Copyright 2007-2010 Tim Schaub
|
||||
* Released under the MIT license. Please see
|
||||
* http://github.com/tschaub/jugl/blob/master/license.txt for the full license.
|
||||
*/
|
||||
/*
|
||||
* Jugl.js -- JavaScript Template Library
|
||||
*
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
}),
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
document.getElementById('zoom-out').onclick = function() {
|
||||
const view = map.getView();
|
||||
const zoom = view.getZoom();
|
||||
var view = map.getView();
|
||||
var zoom = view.getZoom();
|
||||
view.setZoom(zoom - 1);
|
||||
};
|
||||
|
||||
document.getElementById('zoom-in').onclick = function() {
|
||||
const view = map.getView();
|
||||
const zoom = view.getZoom();
|
||||
var view = map.getView();
|
||||
var zoom = view.getZoom();
|
||||
view.setZoom(zoom + 1);
|
||||
};
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {easeIn, easeOut} from '../src/ol/easing.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.easing');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
const london = fromLonLat([-0.12755, 51.507222]);
|
||||
const moscow = fromLonLat([37.6178, 55.7517]);
|
||||
const istanbul = fromLonLat([28.9744, 41.0128]);
|
||||
const rome = fromLonLat([12.5, 41.9]);
|
||||
const bern = fromLonLat([7.4458, 46.95]);
|
||||
var london = ol.proj.fromLonLat([-0.12755, 51.507222]);
|
||||
var moscow = ol.proj.fromLonLat([37.6178, 55.7517]);
|
||||
var istanbul = ol.proj.fromLonLat([28.9744, 41.0128]);
|
||||
var rome = ol.proj.fromLonLat([12.5, 41.9]);
|
||||
var bern = ol.proj.fromLonLat([7.4458, 46.95]);
|
||||
|
||||
const view = new View({
|
||||
var view = new ol.View({
|
||||
center: istanbul,
|
||||
zoom: 6
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
new ol.layer.Tile({
|
||||
preload: 4,
|
||||
source: new OSM()
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
// Improve user experience by loading tiles while animating. Will make
|
||||
@@ -32,9 +32,7 @@ const map = new Map({
|
||||
|
||||
// A bounce easing method (from https://github.com/DmitryBaranovskiy/raphael).
|
||||
function bounce(t) {
|
||||
const s = 7.5625;
|
||||
const p = 2.75;
|
||||
let l;
|
||||
var s = 7.5625, p = 2.75, l;
|
||||
if (t < (1 / p)) {
|
||||
l = s * t * t;
|
||||
} else {
|
||||
@@ -77,15 +75,15 @@ onClick('rotate-right', function() {
|
||||
|
||||
onClick('rotate-around-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
const rotation = view.getRotation();
|
||||
var rotation = view.getRotation();
|
||||
view.animate({
|
||||
rotation: rotation + Math.PI,
|
||||
anchor: rome,
|
||||
easing: easeIn
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
rotation: rotation + 2 * Math.PI,
|
||||
anchor: rome,
|
||||
easing: easeOut
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
@@ -114,26 +112,26 @@ onClick('bounce-to-istanbul', function() {
|
||||
|
||||
onClick('spin-to-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
const center = view.getCenter();
|
||||
var center = view.getCenter();
|
||||
view.animate({
|
||||
center: [
|
||||
center[0] + (rome[0] - center[0]) / 2,
|
||||
center[1] + (rome[1] - center[1]) / 2
|
||||
],
|
||||
rotation: Math.PI,
|
||||
easing: easeIn
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
center: rome,
|
||||
rotation: 2 * Math.PI,
|
||||
easing: easeOut
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
function flyTo(location, done) {
|
||||
const duration = 2000;
|
||||
const zoom = view.getZoom();
|
||||
let parts = 2;
|
||||
let called = false;
|
||||
var duration = 2000;
|
||||
var zoom = view.getZoom();
|
||||
var parts = 2;
|
||||
var called = false;
|
||||
function callback(complete) {
|
||||
--parts;
|
||||
if (called) {
|
||||
@@ -162,13 +160,13 @@ onClick('fly-to-bern', function() {
|
||||
});
|
||||
|
||||
function tour() {
|
||||
const locations = [london, bern, rome, moscow, istanbul];
|
||||
let index = -1;
|
||||
var locations = [london, bern, rome, moscow, istanbul];
|
||||
var index = -1;
|
||||
function next(more) {
|
||||
if (more) {
|
||||
++index;
|
||||
if (index < locations.length) {
|
||||
const delay = index === 0 ? 0 : 750;
|
||||
var delay = index === 0 ? 0 : 750;
|
||||
setTimeout(function() {
|
||||
flyTo(locations[index], next);
|
||||
}, delay);
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Tile as TileLayer, Image as ImageLayer} from '../src/ol/layer.js';
|
||||
import {OSM, ImageArcGISRest} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.ImageArcGISRest');
|
||||
|
||||
const url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
|
||||
var url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
|
||||
'Specialty/ESRI_StateCityHighway_USA/MapServer';
|
||||
|
||||
const layers = [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
var layers = [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new ImageLayer({
|
||||
source: new ImageArcGISRest({
|
||||
new ol.layer.Image({
|
||||
source: new ol.source.ImageArcGISRest({
|
||||
ratio: 1,
|
||||
params: {},
|
||||
url: url
|
||||
})
|
||||
})
|
||||
];
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: layers,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-10997148, 4569099],
|
||||
zoom: 4
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ docs: >
|
||||
This example shows how to use an ArcGIS REST MapService as tiles.
|
||||
This source type supports Map and Image Services. For cached ArcGIS
|
||||
services, better performance is available by using
|
||||
<code>ol/source/XYZ</code> instead.
|
||||
<code>ol.source.XYZ</code> instead.
|
||||
tags: arcgis, tile, tilelayer"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {OSM, TileArcGISRest} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.TileArcGISRest');
|
||||
|
||||
const url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
|
||||
var url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
|
||||
'Specialty/ESRI_StateCityHighway_USA/MapServer';
|
||||
|
||||
const layers = [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
var layers = [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new TileLayer({
|
||||
new ol.layer.Tile({
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
source: new TileArcGISRest({
|
||||
source: new ol.source.TileArcGISRest({
|
||||
url: url
|
||||
})
|
||||
})
|
||||
];
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: layers,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-10997148, 4569099],
|
||||
zoom: 4
|
||||
})
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls, Attribution} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.control.Attribution');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
const attribution = new Attribution({
|
||||
var attribution = new ol.control.Attribution({
|
||||
collapsible: false
|
||||
});
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
controls: defaultControls({attribution: false}).extend([attribution]),
|
||||
controls: ol.control.defaults({attribution: false}).extend([attribution]),
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
function checkSize() {
|
||||
const small = map.getSize()[0] < 600;
|
||||
var small = map.getSize()[0] < 600;
|
||||
attribution.setCollapsible(small);
|
||||
attribution.setCollapsed(small);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ layout: example.html
|
||||
title: Bing Maps
|
||||
shortdesc: Example of a Bing Maps layer.
|
||||
docs: >
|
||||
<p>When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set <code>maxZoom</code> to <code>19</code> in the options passed to <code>ol/source/BingMaps</code>.</p>
|
||||
<p>When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set <code>maxZoom</code> to <code>19</code> in the options passed to <code>ol.source.BingMaps</code>.</p>
|
||||
tags: "bing, bing-maps"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<select id="layer-select">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.BingMaps');
|
||||
|
||||
|
||||
const styles = [
|
||||
var styles = [
|
||||
'Road',
|
||||
'RoadOnDemand',
|
||||
'Aerial',
|
||||
@@ -12,13 +12,13 @@ const styles = [
|
||||
'collinsBart',
|
||||
'ordnanceSurvey'
|
||||
];
|
||||
const layers = [];
|
||||
let i, ii;
|
||||
var layers = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||
layers.push(new TileLayer({
|
||||
layers.push(new ol.layer.Tile({
|
||||
visible: false,
|
||||
preload: Infinity,
|
||||
source: new BingMaps({
|
||||
source: new ol.source.BingMaps({
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||
imagerySet: styles[i]
|
||||
// use maxZoom 19 to see stretched tiles instead of the BingMaps
|
||||
@@ -27,22 +27,22 @@ for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||
})
|
||||
}));
|
||||
}
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: layers,
|
||||
// Improve user experience by loading tiles while dragging/zooming. Will make
|
||||
// zooming choppy on mobile or slow devices.
|
||||
loadTilesWhileInteracting: true,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-6655.5402445057125, 6709968.258934638],
|
||||
zoom: 13
|
||||
})
|
||||
});
|
||||
|
||||
const select = document.getElementById('layer-select');
|
||||
var select = document.getElementById('layer-select');
|
||||
function onChange() {
|
||||
const style = select.value;
|
||||
for (let i = 0, ii = layers.length; i < ii; ++i) {
|
||||
var style = select.value;
|
||||
for (var i = 0, ii = layers.length; i < ii; ++i) {
|
||||
layers[i].setVisible(styles[i] === style);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
// Create separate layers for red, green an blue circles.
|
||||
//
|
||||
// Every layer has one feature that is styled with a circle, together the
|
||||
// features form the corners of an equilateral triangle and their styles overlap
|
||||
const redLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([0, 0]))]
|
||||
var redLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [new ol.Feature(new ol.geom.Point([0, 0]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,0,0,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(255,0,0)',
|
||||
width: 15
|
||||
}),
|
||||
@@ -28,17 +31,17 @@ const redLayer = new VectorLayer({
|
||||
})
|
||||
})
|
||||
});
|
||||
const greenLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
var greenLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
// 433.013 is roughly 250 * Math.sqrt(3)
|
||||
features: [new Feature(new Point([250, 433.013]))]
|
||||
features: [new ol.Feature(new ol.geom.Point([250, 433.013]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,255,0,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(0,255,0)',
|
||||
width: 15
|
||||
}),
|
||||
@@ -46,16 +49,16 @@ const greenLayer = new VectorLayer({
|
||||
})
|
||||
})
|
||||
});
|
||||
const blueLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([500, 0]))]
|
||||
var blueLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [new ol.Feature(new ol.geom.Point([500, 0]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,255,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(0,0,255)',
|
||||
width: 15
|
||||
}),
|
||||
@@ -66,14 +69,14 @@ const blueLayer = new VectorLayer({
|
||||
|
||||
// Create the map, the view is centered on the triangle. Zooming and panning is
|
||||
// restricted to a sane area
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
redLayer,
|
||||
greenLayer,
|
||||
blueLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [250, 220],
|
||||
extent: [0, 0, 500, 500],
|
||||
resolution: 4,
|
||||
@@ -83,19 +86,19 @@ const map = new Map({
|
||||
});
|
||||
|
||||
// Get the form elements and bind the listeners
|
||||
const select = document.getElementById('blend-mode');
|
||||
const affectRed = document.getElementById('affect-red');
|
||||
const affectGreen = document.getElementById('affect-green');
|
||||
const affectBlue = document.getElementById('affect-blue');
|
||||
var select = document.getElementById('blend-mode');
|
||||
var affectRed = document.getElementById('affect-red');
|
||||
var affectGreen = document.getElementById('affect-green');
|
||||
var affectBlue = document.getElementById('affect-blue');
|
||||
|
||||
|
||||
/**
|
||||
* This method sets the globalCompositeOperation to the value of the select
|
||||
* field and it is bound to the precompose event of the layers.
|
||||
*
|
||||
* @param {module:ol/render/Event~RenderEvent} evt The render event.
|
||||
* @param {ol.render.Event} evt The render event.
|
||||
*/
|
||||
const setBlendModeFromSelect = function(evt) {
|
||||
var setBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = select.value;
|
||||
};
|
||||
|
||||
@@ -104,9 +107,9 @@ const setBlendModeFromSelect = function(evt) {
|
||||
* This method resets the globalCompositeOperation to the default value of
|
||||
* 'source-over' and it is bound to the postcompose event of the layers.
|
||||
*
|
||||
* @param {module:ol/render/Event~RenderEvent} evt The render event.
|
||||
* @param {ol.render.Event} evt The render event.
|
||||
*/
|
||||
const resetBlendModeFromSelect = function(evt) {
|
||||
var resetBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = 'source-over';
|
||||
};
|
||||
|
||||
@@ -114,9 +117,9 @@ const resetBlendModeFromSelect = function(evt) {
|
||||
/**
|
||||
* Bind the pre- and postcompose handlers to the passed layer.
|
||||
*
|
||||
* @param {module:ol/layer/Vector} layer The layer to bind the handlers to.
|
||||
* @param {ol.layer.Vector} layer The layer to bind the handlers to.
|
||||
*/
|
||||
const bindLayerListeners = function(layer) {
|
||||
var bindLayerListeners = function(layer) {
|
||||
layer.on('precompose', setBlendModeFromSelect);
|
||||
layer.on('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
@@ -125,9 +128,9 @@ const bindLayerListeners = function(layer) {
|
||||
/**
|
||||
* Unind the pre- and postcompose handlers to the passed layers.
|
||||
*
|
||||
* @param {module:ol/layer/Vector} layer The layer to unbind the handlers from.
|
||||
* @param {ol.layer.Vector} layer The layer to unbind the handlers from.
|
||||
*/
|
||||
const unbindLayerListeners = function(layer) {
|
||||
var unbindLayerListeners = function(layer) {
|
||||
layer.un('precompose', setBlendModeFromSelect);
|
||||
layer.un('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
@@ -138,8 +141,8 @@ const unbindLayerListeners = function(layer) {
|
||||
*
|
||||
* @this {HTMLInputElement}
|
||||
*/
|
||||
const affectLayerClicked = function() {
|
||||
let layer;
|
||||
var affectLayerClicked = function() {
|
||||
var layer;
|
||||
if (this.id == 'affect-red') {
|
||||
layer = redLayer;
|
||||
} else if (this.id == 'affect-green') {
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Box Selection
|
||||
shortdesc: Using a DragBox interaction to select features.
|
||||
docs: >
|
||||
<p>This example shows how to use a <code>DragBox</code> interaction to select features. Selected features are added
|
||||
to the feature overlay of a select interaction (<code>ol/interaction/Select</code>) for highlighting.</p>
|
||||
to the feature overlay of a select interaction (<code>ol.interaction.Select</code>) for highlighting.</p>
|
||||
<p>Use <code>Ctrl+Drag</code> (<code>Command+Drag</code> on Mac) to draw boxes.</p>
|
||||
tags: "DragBox, feature, selection, box"
|
||||
---
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {platformModifierKeyOnly} from '../src/ol/events/condition.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import {DragBox, Select} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.interaction.DragBox');
|
||||
goog.require('ol.interaction.Select');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
var vectorSource = new ol.source.Vector({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
format: new ol.format.GeoJSON()
|
||||
});
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new VectorLayer({
|
||||
new ol.layer.Vector({
|
||||
source: vectorSource
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
// a normal select interaction to handle click
|
||||
const select = new Select();
|
||||
var select = new ol.interaction.Select();
|
||||
map.addInteraction(select);
|
||||
|
||||
const selectedFeatures = select.getFeatures();
|
||||
var selectedFeatures = select.getFeatures();
|
||||
|
||||
// a DragBox interaction used to select features by drawing boxes
|
||||
const dragBox = new DragBox({
|
||||
condition: platformModifierKeyOnly
|
||||
var dragBox = new ol.interaction.DragBox({
|
||||
condition: ol.events.condition.platformModifierKeyOnly
|
||||
});
|
||||
|
||||
map.addInteraction(dragBox);
|
||||
@@ -45,7 +48,7 @@ map.addInteraction(dragBox);
|
||||
dragBox.on('boxend', function() {
|
||||
// features that intersect the box are added to the collection of
|
||||
// selected features
|
||||
const extent = dragBox.getGeometry().getExtent();
|
||||
var extent = dragBox.getGeometry().getExtent();
|
||||
vectorSource.forEachFeatureIntersectingExtent(extent, function(feature) {
|
||||
selectedFeatures.push(feature);
|
||||
});
|
||||
@@ -56,10 +59,10 @@ dragBox.on('boxstart', function() {
|
||||
selectedFeatures.clear();
|
||||
});
|
||||
|
||||
const infoBox = document.getElementById('info');
|
||||
var infoBox = document.getElementById('info');
|
||||
|
||||
selectedFeatures.on(['add', 'remove'], function() {
|
||||
const names = selectedFeatures.getArray().map(function(feature) {
|
||||
var names = selectedFeatures.getArray().map(function(feature) {
|
||||
return feature.get('name');
|
||||
});
|
||||
if (names.length > 0) {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-8730000, 5930000],
|
||||
rotation: Math.PI / 5,
|
||||
zoom: 8
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {getWidth} from '../src/ol/extent.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import {DEVICE_PIXEL_RATIO} from '../src/ol/has.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
var canvas = document.createElement('canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
// Gradient and pattern are in canvas pixel space, so we adjust for the
|
||||
// renderer's pixel ratio
|
||||
const pixelRatio = DEVICE_PIXEL_RATIO;
|
||||
var pixelRatio = ol.has.DEVICE_PIXEL_RATIO;
|
||||
|
||||
// Generate a rainbow gradient
|
||||
function gradient(feature, resolution) {
|
||||
const extent = feature.getGeometry().getExtent();
|
||||
var extent = feature.getGeometry().getExtent();
|
||||
// Gradient starts on the left edge of each feature, and ends on the right.
|
||||
// Coordinate origin is the top-left corner of the extent of the geometry, so
|
||||
// we just divide the geometry's extent width by resolution and multiply with
|
||||
// pixelRatio to match the renderer's pixel coordinate system.
|
||||
const grad = context.createLinearGradient(0, 0,
|
||||
getWidth(extent) / resolution * pixelRatio, 0);
|
||||
var grad = context.createLinearGradient(0, 0,
|
||||
ol.extent.getWidth(extent) / resolution * pixelRatio, 0);
|
||||
grad.addColorStop(0, 'red');
|
||||
grad.addColorStop(1 / 6, 'orange');
|
||||
grad.addColorStop(2 / 6, 'yellow');
|
||||
@@ -35,7 +37,7 @@ function gradient(feature, resolution) {
|
||||
}
|
||||
|
||||
// Generate a canvasPattern with two circles on white background
|
||||
const pattern = (function() {
|
||||
var pattern = (function() {
|
||||
canvas.width = 11 * pixelRatio;
|
||||
canvas.height = 11 * pixelRatio;
|
||||
// white background
|
||||
@@ -55,10 +57,10 @@ const pattern = (function() {
|
||||
}());
|
||||
|
||||
// Generate style for gradient or pattern fill
|
||||
const fill = new Fill();
|
||||
const style = new Style({
|
||||
var fill = new ol.style.Fill();
|
||||
var style = new ol.style.Style({
|
||||
fill: fill,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#333',
|
||||
width: 2
|
||||
})
|
||||
@@ -68,33 +70,33 @@ const style = new Style({
|
||||
* The styling function for the vector layer, will return an array of styles
|
||||
* which either contains the aboove gradient or pattern.
|
||||
*
|
||||
* @param {module:ol/Feature~Feature} feature The feature to style.
|
||||
* @param {ol.Feature} feature The feature to style.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {module:ol/style/Style} The style to use for the feature.
|
||||
* @return {ol.style.Style} The style to use for the feature.
|
||||
*/
|
||||
const getStackedStyle = function(feature, resolution) {
|
||||
const id = feature.getId();
|
||||
var getStackedStyle = function(feature, resolution) {
|
||||
var id = feature.getId();
|
||||
fill.setColor(id > 'J' ? gradient(feature, resolution) : pattern);
|
||||
return style;
|
||||
};
|
||||
|
||||
// Create a vector layer that makes use of the style function above…
|
||||
const vectorLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
var vectorLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
format: new ol.format.GeoJSON()
|
||||
}),
|
||||
style: getStackedStyle
|
||||
});
|
||||
|
||||
// … finally create a map with that layer.
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
vectorLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: fromLonLat([7, 52]),
|
||||
view: new ol.View({
|
||||
center: ol.proj.fromLonLat([7, 52]),
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import {OSM, TileDebug} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.TileDebug');
|
||||
|
||||
|
||||
const osmSource = new OSM();
|
||||
const map = new Map({
|
||||
var osmSource = new ol.source.OSM();
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
new ol.layer.Tile({
|
||||
source: osmSource
|
||||
}),
|
||||
new TileLayer({
|
||||
source: new TileDebug({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileDebug({
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: osmSource.getTileGrid()
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
}),
|
||||
view: new View({
|
||||
center: fromLonLat([-0.1275, 51.507222]),
|
||||
view: new ol.View({
|
||||
center: ol.proj.transform(
|
||||
[-0.1275, 51.507222], 'EPSG:4326', 'EPSG:3857'),
|
||||
zoom: 10
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {CartoDB, OSM} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.CartoDB');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
const mapConfig = {
|
||||
var mapConfig = {
|
||||
'layers': [{
|
||||
'type': 'cartodb',
|
||||
'options': {
|
||||
@@ -14,22 +15,22 @@ const mapConfig = {
|
||||
}]
|
||||
};
|
||||
|
||||
const cartoDBSource = new CartoDB({
|
||||
var cartoDBSource = new ol.source.CartoDB({
|
||||
account: 'documentation',
|
||||
config: mapConfig
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new TileLayer({
|
||||
new ol.layer.Tile({
|
||||
source: cartoDBSource
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -1,51 +1,56 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
const source = new VectorSource({
|
||||
var source = new ol.source.Vector({
|
||||
url: 'data/geojson/switzerland.geojson',
|
||||
format: new GeoJSON()
|
||||
format: new ol.format.GeoJSON()
|
||||
});
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
var style = new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1
|
||||
}),
|
||||
image: new CircleStyle({
|
||||
image: new ol.style.Circle({
|
||||
radius: 5,
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
});
|
||||
const vectorLayer = new VectorLayer({
|
||||
var vectorLayer = new ol.layer.Vector({
|
||||
source: source,
|
||||
style: style
|
||||
});
|
||||
const view = new View({
|
||||
var view = new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
});
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
vectorLayer
|
||||
],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
@@ -53,40 +58,40 @@ const map = new Map({
|
||||
view: view
|
||||
});
|
||||
|
||||
const zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest');
|
||||
var zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest');
|
||||
zoomtoswitzerlandbest.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
var feature = source.getFeatures()[0];
|
||||
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150], constrainResolution: false});
|
||||
}, false);
|
||||
|
||||
const zoomtoswitzerlandconstrained =
|
||||
var zoomtoswitzerlandconstrained =
|
||||
document.getElementById('zoomtoswitzerlandconstrained');
|
||||
zoomtoswitzerlandconstrained.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
var feature = source.getFeatures()[0];
|
||||
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150]});
|
||||
}, false);
|
||||
|
||||
const zoomtoswitzerlandnearest =
|
||||
var zoomtoswitzerlandnearest =
|
||||
document.getElementById('zoomtoswitzerlandnearest');
|
||||
zoomtoswitzerlandnearest.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
var feature = source.getFeatures()[0];
|
||||
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150], nearest: true});
|
||||
}, false);
|
||||
|
||||
const zoomtolausanne = document.getElementById('zoomtolausanne');
|
||||
var zoomtolausanne = document.getElementById('zoomtolausanne');
|
||||
zoomtolausanne.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[1];
|
||||
const point = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
var feature = source.getFeatures()[1];
|
||||
var point = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
|
||||
view.fit(point, {padding: [170, 50, 30, 150], minResolution: 50});
|
||||
}, false);
|
||||
|
||||
const centerlausanne = document.getElementById('centerlausanne');
|
||||
var centerlausanne = document.getElementById('centerlausanne');
|
||||
centerlausanne.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[1];
|
||||
const point = /** @type {module:ol/geom/Point~Point} */ (feature.getGeometry());
|
||||
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
||||
var feature = source.getFeatures()[1];
|
||||
var point = /** @type {ol.geom.Point} */ (feature.getGeometry());
|
||||
var size = /** @type {ol.Size} */ (map.getSize());
|
||||
view.centerOn(point.getCoordinates(), size, [570, 500]);
|
||||
}, false);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Smoothing lines using Chaikins algorithm
|
||||
shortdesc: This uses Chaikins algorithm to smooth drawn lines.
|
||||
docs: >
|
||||
This example uses the npm package [`chaikin-smooth`](https://www.npmjs.com/package/chaikin-smooth) which
|
||||
implements [Chaikins algorithm](http://graphics.cs.ucdavis.edu/education/CAGDNotes/Chaikins-Algorithm/Chaikins-Algorithm.html)
|
||||
to smooth drawn lines.
|
||||
|
||||
Start by drawing on the map. Once you finish a drawing, the feature's geometry will be smoothed
|
||||
as configured via the form elements.
|
||||
tags: "smooth, smoothing, chaikin"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<form class="form-inline">
|
||||
<label for="shall-smoothen">Smooth drawn geometry?</label>
|
||||
<input id="shall-smoothen" type="checkbox" checked><br>
|
||||
<label for="iterations">Number of smoothings</label>
|
||||
<input style="width: 250px;" type="range" id="iterations" min="2" max="10" step="1" value="5">
|
||||
</form>
|
||||
@@ -1,54 +0,0 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import Draw from '../src/ol/interaction/Draw.js';
|
||||
|
||||
import smooth from 'chaikin-smooth';
|
||||
|
||||
function makeSmooth(path, numIterations) {
|
||||
numIterations = Math.min(Math.max(numIterations, 1), 10);
|
||||
while (numIterations > 0) {
|
||||
path = smooth(path);
|
||||
numIterations--;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
const vectorSource = new VectorSource({});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
opacity: 0.5
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: vectorSource
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [1078373.5950, 6871994.5910],
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
const shallSmoothen = document.getElementById('shall-smoothen');
|
||||
const numIterations = document.getElementById('iterations');
|
||||
|
||||
const draw = new Draw({
|
||||
source: vectorSource,
|
||||
type: 'LineString'
|
||||
});
|
||||
map.addInteraction(draw);
|
||||
draw.on('drawend', function(event) {
|
||||
if (!shallSmoothen.checked) {
|
||||
return;
|
||||
}
|
||||
const feat = event.feature;
|
||||
const geometry = feat.getGeometry();
|
||||
const coords = geometry.getCoordinates();
|
||||
const smoothened = makeSmooth(coords, parseInt(numIterations.value, 10) || 5);
|
||||
geometry.setCoordinates(smoothened);
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Clustered Features
|
||||
shortdesc: Example of using ol/source/Cluster.
|
||||
shortdesc: Example of using ol.source.Cluster.
|
||||
docs: >
|
||||
This example shows how to do clustering on point features.
|
||||
tags: "cluster, vector"
|
||||
|
||||
@@ -1,51 +1,58 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {Cluster, OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Cluster');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.style.Text');
|
||||
|
||||
|
||||
const distance = document.getElementById('distance');
|
||||
var distance = document.getElementById('distance');
|
||||
|
||||
const count = 20000;
|
||||
const features = new Array(count);
|
||||
const e = 4500000;
|
||||
for (let i = 0; i < count; ++i) {
|
||||
const coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
|
||||
features[i] = new Feature(new Point(coordinates));
|
||||
var count = 20000;
|
||||
var features = new Array(count);
|
||||
var e = 4500000;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
|
||||
features[i] = new ol.Feature(new ol.geom.Point(coordinates));
|
||||
}
|
||||
|
||||
const source = new VectorSource({
|
||||
var source = new ol.source.Vector({
|
||||
features: features
|
||||
});
|
||||
|
||||
const clusterSource = new Cluster({
|
||||
var clusterSource = new ol.source.Cluster({
|
||||
distance: parseInt(distance.value, 10),
|
||||
source: source
|
||||
});
|
||||
|
||||
const styleCache = {};
|
||||
const clusters = new VectorLayer({
|
||||
var styleCache = {};
|
||||
var clusters = new ol.layer.Vector({
|
||||
source: clusterSource,
|
||||
style: function(feature) {
|
||||
const size = feature.get('features').length;
|
||||
let style = styleCache[size];
|
||||
var size = feature.get('features').length;
|
||||
var style = styleCache[size];
|
||||
if (!style) {
|
||||
style = new Style({
|
||||
image: new CircleStyle({
|
||||
style = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 10,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#fff'
|
||||
}),
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: '#3399CC'
|
||||
})
|
||||
}),
|
||||
text: new Text({
|
||||
text: new ol.style.Text({
|
||||
text: size.toString(),
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: '#fff'
|
||||
})
|
||||
})
|
||||
@@ -56,14 +63,14 @@ const clusters = new VectorLayer({
|
||||
}
|
||||
});
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, clusters],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
// NOCOMPILE
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import ImageLayer from '../src/ol/layer/Image.js';
|
||||
import {Raster as RasterSource, Stamen} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.source.Raster');
|
||||
goog.require('ol.source.Stamen');
|
||||
|
||||
|
||||
/**
|
||||
* Color manipulation functions below are adapted from
|
||||
* https://github.com/d3/d3-color.
|
||||
*/
|
||||
const Xn = 0.950470;
|
||||
const Yn = 1;
|
||||
const Zn = 1.088830;
|
||||
const t0 = 4 / 29;
|
||||
const t1 = 6 / 29;
|
||||
const t2 = 3 * t1 * t1;
|
||||
const t3 = t1 * t1 * t1;
|
||||
const twoPi = 2 * Math.PI;
|
||||
var Xn = 0.950470;
|
||||
var Yn = 1;
|
||||
var Zn = 1.088830;
|
||||
var t0 = 4 / 29;
|
||||
var t1 = 6 / 29;
|
||||
var t2 = 3 * t1 * t1;
|
||||
var t3 = t1 * t1 * t1;
|
||||
var twoPi = 2 * Math.PI;
|
||||
|
||||
|
||||
/**
|
||||
@@ -25,23 +26,23 @@ const twoPi = 2 * Math.PI;
|
||||
* @return {Array.<number>} A pixel in HCL space.
|
||||
*/
|
||||
function rgb2hcl(pixel) {
|
||||
const red = rgb2xyz(pixel[0]);
|
||||
const green = rgb2xyz(pixel[1]);
|
||||
const blue = rgb2xyz(pixel[2]);
|
||||
var red = rgb2xyz(pixel[0]);
|
||||
var green = rgb2xyz(pixel[1]);
|
||||
var blue = rgb2xyz(pixel[2]);
|
||||
|
||||
const x = xyz2lab(
|
||||
(0.4124564 * red + 0.3575761 * green + 0.1804375 * blue) / Xn);
|
||||
const y = xyz2lab(
|
||||
(0.2126729 * red + 0.7151522 * green + 0.0721750 * blue) / Yn);
|
||||
const z = xyz2lab(
|
||||
(0.0193339 * red + 0.1191920 * green + 0.9503041 * blue) / Zn);
|
||||
var x = xyz2lab(
|
||||
(0.4124564 * red + 0.3575761 * green + 0.1804375 * blue) / Xn);
|
||||
var y = xyz2lab(
|
||||
(0.2126729 * red + 0.7151522 * green + 0.0721750 * blue) / Yn);
|
||||
var z = xyz2lab(
|
||||
(0.0193339 * red + 0.1191920 * green + 0.9503041 * blue) / Zn);
|
||||
|
||||
const l = 116 * y - 16;
|
||||
const a = 500 * (x - y);
|
||||
const b = 200 * (y - z);
|
||||
var l = 116 * y - 16;
|
||||
var a = 500 * (x - y);
|
||||
var b = 200 * (y - z);
|
||||
|
||||
const c = Math.sqrt(a * a + b * b);
|
||||
let h = Math.atan2(b, a);
|
||||
var c = Math.sqrt(a * a + b * b);
|
||||
var h = Math.atan2(b, a);
|
||||
if (h < 0) {
|
||||
h += twoPi;
|
||||
}
|
||||
@@ -60,16 +61,16 @@ function rgb2hcl(pixel) {
|
||||
* @return {Array.<number>} A pixel in RGB space.
|
||||
*/
|
||||
function hcl2rgb(pixel) {
|
||||
const h = pixel[0];
|
||||
const c = pixel[1];
|
||||
const l = pixel[2];
|
||||
var h = pixel[0];
|
||||
var c = pixel[1];
|
||||
var l = pixel[2];
|
||||
|
||||
const a = Math.cos(h) * c;
|
||||
const b = Math.sin(h) * c;
|
||||
var a = Math.cos(h) * c;
|
||||
var b = Math.sin(h) * c;
|
||||
|
||||
let y = (l + 16) / 116;
|
||||
let x = isNaN(a) ? y : y + a / 500;
|
||||
let z = isNaN(b) ? y : y - b / 200;
|
||||
var y = (l + 16) / 116;
|
||||
var x = isNaN(a) ? y : y + a / 500;
|
||||
var z = isNaN(b) ? y : y - b / 200;
|
||||
|
||||
y = Yn * lab2xyz(y);
|
||||
x = Xn * lab2xyz(x);
|
||||
@@ -99,15 +100,15 @@ function xyz2rgb(x) {
|
||||
12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
|
||||
}
|
||||
|
||||
const raster = new RasterSource({
|
||||
sources: [new Stamen({
|
||||
var raster = new ol.source.Raster({
|
||||
sources: [new ol.source.Stamen({
|
||||
layer: 'watercolor',
|
||||
transition: 0
|
||||
})],
|
||||
operation: function(pixels, data) {
|
||||
const hcl = rgb2hcl(pixels[0]);
|
||||
var hcl = rgb2hcl(pixels[0]);
|
||||
|
||||
let h = hcl[0] + Math.PI * data.hue / 180;
|
||||
var h = hcl[0] + Math.PI * data.hue / 180;
|
||||
if (h < 0) {
|
||||
h += twoPi;
|
||||
} else if (h > twoPi) {
|
||||
@@ -138,33 +139,33 @@ const raster = new RasterSource({
|
||||
}
|
||||
});
|
||||
|
||||
const controls = {};
|
||||
var controls = {};
|
||||
|
||||
raster.on('beforeoperations', function(event) {
|
||||
const data = event.data;
|
||||
for (const id in controls) {
|
||||
var data = event.data;
|
||||
for (var id in controls) {
|
||||
data[id] = Number(controls[id].value);
|
||||
}
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ImageLayer({
|
||||
new ol.layer.Image({
|
||||
source: raster
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 2500000],
|
||||
zoom: 2,
|
||||
maxZoom: 18
|
||||
})
|
||||
});
|
||||
|
||||
const controlIds = ['hue', 'chroma', 'lightness'];
|
||||
var controlIds = ['hue', 'chroma', 'lightness'];
|
||||
controlIds.forEach(function(id) {
|
||||
const control = document.getElementById(id);
|
||||
const output = document.getElementById(id + 'Out');
|
||||
var control = document.getElementById(id);
|
||||
var output = document.getElementById(id + 'Out');
|
||||
control.addEventListener('input', function() {
|
||||
output.innerText = control.value;
|
||||
raster.changed();
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import {inherits} from '../src/ol/index.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls, Control} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.control.Control');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
|
||||
/**
|
||||
* Define a namespace for the application.
|
||||
*/
|
||||
window.app = {};
|
||||
const app = window.app;
|
||||
var app = window.app;
|
||||
|
||||
|
||||
//
|
||||
@@ -20,35 +21,35 @@ const app = window.app;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {module:ol/control/Control~Control}
|
||||
* @extends {ol.control.Control}
|
||||
* @param {Object=} opt_options Control options.
|
||||
*/
|
||||
app.RotateNorthControl = function(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
var options = opt_options || {};
|
||||
|
||||
const button = document.createElement('button');
|
||||
var button = document.createElement('button');
|
||||
button.innerHTML = 'N';
|
||||
|
||||
const this_ = this;
|
||||
const handleRotateNorth = function() {
|
||||
var this_ = this;
|
||||
var handleRotateNorth = function() {
|
||||
this_.getMap().getView().setRotation(0);
|
||||
};
|
||||
|
||||
button.addEventListener('click', handleRotateNorth, false);
|
||||
button.addEventListener('touchstart', handleRotateNorth, false);
|
||||
|
||||
const element = document.createElement('div');
|
||||
var element = document.createElement('div');
|
||||
element.className = 'rotate-north ol-unselectable ol-control';
|
||||
element.appendChild(button);
|
||||
|
||||
Control.call(this, {
|
||||
ol.control.Control.call(this, {
|
||||
element: element,
|
||||
target: options.target
|
||||
});
|
||||
|
||||
};
|
||||
inherits(app.RotateNorthControl, Control);
|
||||
ol.inherits(app.RotateNorthControl, ol.control.Control);
|
||||
|
||||
|
||||
//
|
||||
@@ -56,8 +57,8 @@ inherits(app.RotateNorthControl, Control);
|
||||
//
|
||||
|
||||
|
||||
const map = new Map({
|
||||
controls: defaultControls({
|
||||
var map = new ol.Map({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
@@ -65,12 +66,12 @@ const map = new Map({
|
||||
new app.RotateNorthControl()
|
||||
]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 3,
|
||||
rotation: 1
|
||||
|
||||
9
examples/custom-icon.html
Normal file
9
examples/custom-icon.html
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Custom Icon
|
||||
shortdesc: Example using a custom attribution icon object
|
||||
docs: >
|
||||
This example creates a custom element for the attribution icon
|
||||
tags: "icon, element"
|
||||
---
|
||||
<div id="map" class="map"><div id="popup"></div></div>
|
||||
27
examples/custom-icon.js
Normal file
27
examples/custom-icon.js
Normal file
@@ -0,0 +1,27 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
var logoElement = document.createElement('a');
|
||||
logoElement.href = 'https://www.osgeo.org/';
|
||||
logoElement.target = '_blank';
|
||||
|
||||
var logoImage = document.createElement('img');
|
||||
logoImage.src = 'https://www.osgeo.org/sites/all/themes/osgeo/logo.png';
|
||||
|
||||
logoElement.appendChild(logoImage);
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
}),
|
||||
logo: logoElement
|
||||
});
|
||||
@@ -3,8 +3,8 @@ layout: example.html
|
||||
title: Custom Interactions
|
||||
shortdesc: Example of a custom interaction.
|
||||
docs: >
|
||||
This example demonstrates creating a custom interaction by subclassing `ol/interaction/Pointer`.
|
||||
Note that the built in interaction `ol/interaction/Translate` might be a better option for moving features.
|
||||
This example demonstrates creating a custom interaction by subclassing `ol.interaction.Pointer`.
|
||||
Note that the built in interaction `ol.interaction.Translate` might be a better option for moving features.
|
||||
tags: "drag, feature, vector, editing, custom, interaction"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
import {inherits} from '../src/ol/index.js';
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {LineString, Point, Polygon} from '../src/ol/geom.js';
|
||||
import {defaults as defaultInteractions, Pointer as PointerInteraction} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {TileJSON, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Fill, Icon, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.Pointer');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.TileJSON');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Icon');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
/**
|
||||
* Define a namespace for the application.
|
||||
*/
|
||||
const app = {};
|
||||
var app = {};
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {module:ol/interaction/Pointer}
|
||||
* @extends {ol.interaction.Pointer}
|
||||
*/
|
||||
app.Drag = function() {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
ol.interaction.Pointer.call(this, {
|
||||
handleDownEvent: app.Drag.prototype.handleDownEvent,
|
||||
handleDragEvent: app.Drag.prototype.handleDragEvent,
|
||||
handleMoveEvent: app.Drag.prototype.handleMoveEvent,
|
||||
@@ -29,7 +37,7 @@ app.Drag = function() {
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {module:ol~Pixel}
|
||||
* @type {ol.Pixel}
|
||||
* @private
|
||||
*/
|
||||
this.coordinate_ = null;
|
||||
@@ -41,7 +49,7 @@ app.Drag = function() {
|
||||
this.cursor_ = 'pointer';
|
||||
|
||||
/**
|
||||
* @type {module:ol/Feature~Feature}
|
||||
* @type {ol.Feature}
|
||||
* @private
|
||||
*/
|
||||
this.feature_ = null;
|
||||
@@ -53,20 +61,20 @@ app.Drag = function() {
|
||||
this.previousCursor_ = undefined;
|
||||
|
||||
};
|
||||
inherits(app.Drag, PointerInteraction);
|
||||
ol.inherits(app.Drag, ol.interaction.Pointer);
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
|
||||
* @param {ol.MapBrowserEvent} evt Map browser event.
|
||||
* @return {boolean} `true` to start the drag sequence.
|
||||
*/
|
||||
app.Drag.prototype.handleDownEvent = function(evt) {
|
||||
const map = evt.map;
|
||||
var map = evt.map;
|
||||
|
||||
const feature = map.forEachFeatureAtPixel(evt.pixel,
|
||||
function(feature) {
|
||||
return feature;
|
||||
});
|
||||
var feature = map.forEachFeatureAtPixel(evt.pixel,
|
||||
function(feature) {
|
||||
return feature;
|
||||
});
|
||||
|
||||
if (feature) {
|
||||
this.coordinate_ = evt.coordinate;
|
||||
@@ -78,13 +86,13 @@ app.Drag.prototype.handleDownEvent = function(evt) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
|
||||
* @param {ol.MapBrowserEvent} evt Map browser event.
|
||||
*/
|
||||
app.Drag.prototype.handleDragEvent = function(evt) {
|
||||
const deltaX = evt.coordinate[0] - this.coordinate_[0];
|
||||
const deltaY = evt.coordinate[1] - this.coordinate_[1];
|
||||
var deltaX = evt.coordinate[0] - this.coordinate_[0];
|
||||
var deltaY = evt.coordinate[1] - this.coordinate_[1];
|
||||
|
||||
const geometry = this.feature_.getGeometry();
|
||||
var geometry = this.feature_.getGeometry();
|
||||
geometry.translate(deltaX, deltaY);
|
||||
|
||||
this.coordinate_[0] = evt.coordinate[0];
|
||||
@@ -93,16 +101,16 @@ app.Drag.prototype.handleDragEvent = function(evt) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Event.
|
||||
* @param {ol.MapBrowserEvent} evt Event.
|
||||
*/
|
||||
app.Drag.prototype.handleMoveEvent = function(evt) {
|
||||
if (this.cursor_) {
|
||||
const map = evt.map;
|
||||
const feature = map.forEachFeatureAtPixel(evt.pixel,
|
||||
function(feature) {
|
||||
return feature;
|
||||
});
|
||||
const element = evt.map.getTargetElement();
|
||||
var map = evt.map;
|
||||
var feature = map.forEachFeatureAtPixel(evt.pixel,
|
||||
function(feature) {
|
||||
return feature;
|
||||
});
|
||||
var element = evt.map.getTargetElement();
|
||||
if (feature) {
|
||||
if (element.style.cursor != this.cursor_) {
|
||||
this.previousCursor_ = element.style.cursor;
|
||||
@@ -126,48 +134,48 @@ app.Drag.prototype.handleUpEvent = function() {
|
||||
};
|
||||
|
||||
|
||||
const pointFeature = new Feature(new Point([0, 0]));
|
||||
var pointFeature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||
|
||||
const lineFeature = new Feature(
|
||||
new LineString([[-1e7, 1e6], [-1e6, 3e6]]));
|
||||
var lineFeature = new ol.Feature(
|
||||
new ol.geom.LineString([[-1e7, 1e6], [-1e6, 3e6]]));
|
||||
|
||||
const polygonFeature = new Feature(
|
||||
new Polygon([[[-3e6, -1e6], [-3e6, 1e6],
|
||||
[-1e6, 1e6], [-1e6, -1e6], [-3e6, -1e6]]]));
|
||||
var polygonFeature = new ol.Feature(
|
||||
new ol.geom.Polygon([[[-3e6, -1e6], [-3e6, 1e6],
|
||||
[-1e6, 1e6], [-1e6, -1e6], [-3e6, -1e6]]]));
|
||||
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([new app.Drag()]),
|
||||
var map = new ol.Map({
|
||||
interactions: ol.interaction.defaults().extend([new app.Drag()]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new TileJSON({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileJSON({
|
||||
url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure'
|
||||
})
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [pointFeature, lineFeature, polygonFeature]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
|
||||
anchor: [0.5, 46],
|
||||
anchorXUnits: 'fraction',
|
||||
anchorYUnits: 'pixels',
|
||||
opacity: 0.95,
|
||||
src: 'data/icon.png'
|
||||
})),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
width: 3,
|
||||
color: [255, 0, 0, 1]
|
||||
}),
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: [0, 0, 255, 0.6]
|
||||
})
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ docs: >
|
||||
<p>The example loads TopoJSON geometries and uses d3 (<code>d3.geo.path</code>) to render these geometries to a canvas element that is then used as the image of an OpenLayers image layer.</p>
|
||||
tags: "d3"
|
||||
resources:
|
||||
- https://unpkg.com/d3@4.12.0/build/d3.js
|
||||
- https://unpkg.com/topojson@3.0.2/dist/topojson.js
|
||||
- https://d3js.org/d3.v3.min.js
|
||||
- https://d3js.org/topojson.v1.min.js
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
88
examples/d3.js
vendored
88
examples/d3.js
vendored
@@ -1,85 +1,91 @@
|
||||
// NOCOMPILE
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {getWidth, getCenter} from '../src/ol/extent.js';
|
||||
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {fromLonLat, toLonLat} from '../src/ol/proj.js';
|
||||
import {ImageCanvas as ImageCanvasSource, Stamen} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.ImageCanvas');
|
||||
goog.require('ol.source.Stamen');
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new Stamen({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.Stamen({
|
||||
layer: 'watercolor'
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: fromLonLat([-97, 38]),
|
||||
view: new ol.View({
|
||||
center: ol.proj.fromLonLat([-97, 38]),
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Load the topojson data and create an ol/layer/Image for that data.
|
||||
* Load the topojson data and create an ol.layer.Image for that data.
|
||||
*/
|
||||
d3.json('data/topojson/us.json', function(error, us) {
|
||||
const features = topojson.feature(us, us.objects.counties);
|
||||
var features = topojson.feature(us, us.objects.counties);
|
||||
|
||||
/**
|
||||
* This function uses d3 to render the topojson features to a canvas.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/size~Size} size Size.
|
||||
* @param {module:ol/proj/Projection~Projection} projection Projection.
|
||||
* @param {ol.Size} size Size.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {HTMLCanvasElement} A canvas element.
|
||||
*/
|
||||
const canvasFunction = function(extent, resolution, pixelRatio, size, projection) {
|
||||
const canvasWidth = size[0];
|
||||
const canvasHeight = size[1];
|
||||
var canvasFunction = function(extent, resolution, pixelRatio,
|
||||
size, projection) {
|
||||
var canvasWidth = size[0];
|
||||
var canvasHeight = size[1];
|
||||
|
||||
const canvas = d3.select(document.createElement('canvas'));
|
||||
var canvas = d3.select(document.createElement('canvas'));
|
||||
canvas.attr('width', canvasWidth).attr('height', canvasHeight);
|
||||
|
||||
const context = canvas.node().getContext('2d');
|
||||
var context = canvas.node().getContext('2d');
|
||||
|
||||
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
|
||||
let d3Path = d3.geoPath().projection(d3Projection);
|
||||
var d3Projection = d3.geo.mercator().scale(1).translate([0, 0]);
|
||||
var d3Path = d3.geo.path().projection(d3Projection);
|
||||
|
||||
const pixelBounds = d3Path.bounds(features);
|
||||
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
|
||||
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
|
||||
var pixelBounds = d3Path.bounds(features);
|
||||
var pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
|
||||
var pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
|
||||
|
||||
const geoBounds = d3.geoBounds(features);
|
||||
const geoBoundsLeftBottom = fromLonLat(geoBounds[0], projection);
|
||||
const geoBoundsRightTop = fromLonLat(geoBounds[1], projection);
|
||||
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
|
||||
var geoBounds = d3.geo.bounds(features);
|
||||
var geoBoundsLeftBottom = ol.proj.transform(
|
||||
geoBounds[0], 'EPSG:4326', projection);
|
||||
var geoBoundsRightTop = ol.proj.transform(
|
||||
geoBounds[1], 'EPSG:4326', projection);
|
||||
var geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
|
||||
if (geoBoundsWidth < 0) {
|
||||
geoBoundsWidth += getWidth(projection.getExtent());
|
||||
geoBoundsWidth += ol.extent.getWidth(projection.getExtent());
|
||||
}
|
||||
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
|
||||
var geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
|
||||
|
||||
const widthResolution = geoBoundsWidth / pixelBoundsWidth;
|
||||
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
|
||||
const r = Math.max(widthResolution, heightResolution);
|
||||
const scale = r / (resolution / pixelRatio);
|
||||
var widthResolution = geoBoundsWidth / pixelBoundsWidth;
|
||||
var heightResolution = geoBoundsHeight / pixelBoundsHeight;
|
||||
var r = Math.max(widthResolution, heightResolution);
|
||||
var scale = r / (resolution / pixelRatio);
|
||||
|
||||
const center = toLonLat(getCenter(extent), projection);
|
||||
var center = ol.proj.transform(ol.extent.getCenter(extent),
|
||||
projection, 'EPSG:4326');
|
||||
d3Projection.scale(scale).center(center)
|
||||
.translate([canvasWidth / 2, canvasHeight / 2]);
|
||||
.translate([canvasWidth / 2, canvasHeight / 2]);
|
||||
d3Path = d3Path.projection(d3Projection).context(context);
|
||||
d3Path(features);
|
||||
context.stroke();
|
||||
|
||||
return canvas.node();
|
||||
return canvas[0][0];
|
||||
};
|
||||
|
||||
const layer = new ImageLayer({
|
||||
source: new ImageCanvasSource({
|
||||
var layer = new ol.layer.Image({
|
||||
source: new ol.source.ImageCanvas({
|
||||
canvasFunction: canvasFunction,
|
||||
projection: 'EPSG:3857'
|
||||
})
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
// NOCOMPILE
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {toRadians} from '../src/ol/math.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.math');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
const view = new View({
|
||||
var projection = ol.proj.get('EPSG:3857');
|
||||
var view = new ol.View({
|
||||
center: [0, 0],
|
||||
projection: projection,
|
||||
extent: projection.getExtent(),
|
||||
zoom: 2
|
||||
});
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
@@ -30,15 +34,15 @@ function el(id) {
|
||||
}
|
||||
|
||||
|
||||
const gn = new GyroNorm();
|
||||
var gn = new GyroNorm();
|
||||
|
||||
gn.init().then(function() {
|
||||
gn.start(function(event) {
|
||||
const center = view.getCenter();
|
||||
const resolution = view.getResolution();
|
||||
const alpha = toRadians(event.do.beta);
|
||||
const beta = toRadians(event.do.beta);
|
||||
const gamma = toRadians(event.do.gamma);
|
||||
var center = view.getCenter();
|
||||
var resolution = view.getResolution();
|
||||
var alpha = ol.math.toRadians(event.do.beta);
|
||||
var beta = ol.math.toRadians(event.do.beta);
|
||||
var gamma = ol.math.toRadians(event.do.gamma);
|
||||
|
||||
el('alpha').innerText = alpha + ' [rad]';
|
||||
el('beta').innerText = beta + ' [rad]';
|
||||
|
||||
@@ -3,11 +3,10 @@ layout: example.html
|
||||
title: Drag-and-Drop Image Vector
|
||||
shortdesc: Example of using the drag-and-drop interaction with image vector rendering.
|
||||
docs: >
|
||||
Example of using the drag-and-drop interaction with an `ol/layer/Vector` with `renderMode: 'image'``. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
|
||||
Example of using the drag-and-drop interaction with an `ol.layer.Vector` with `renderMode: 'image'``. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
|
||||
tags: "drag-and-drop-image-vector, gpx, geojson, igc, kml, topojson, vector, image"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="info"> </div>
|
||||
|
||||
@@ -1,71 +1,81 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
|
||||
import {defaults as defaultInteractions, DragAndDrop} from '../src/ol/interaction.js';
|
||||
import {Vector as VectorLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {BingMaps, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.format.GPX');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.format.IGC');
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.format.TopoJSON');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.DragAndDrop');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.BingMaps');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
const defaultStyle = {
|
||||
'Point': new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
var defaultStyle = {
|
||||
'Point': new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,255,0,0.5)'
|
||||
}),
|
||||
radius: 5,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#ff0',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
}),
|
||||
'LineString': new Style({
|
||||
stroke: new Stroke({
|
||||
'LineString': new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#f00',
|
||||
width: 3
|
||||
})
|
||||
}),
|
||||
'Polygon': new Style({
|
||||
fill: new Fill({
|
||||
'Polygon': new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,255,255,0.5)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#0ff',
|
||||
width: 1
|
||||
})
|
||||
}),
|
||||
'MultiPoint': new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
'MultiPoint': new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,0,255,0.5)'
|
||||
}),
|
||||
radius: 5,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#f0f',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
}),
|
||||
'MultiLineString': new Style({
|
||||
stroke: new Stroke({
|
||||
'MultiLineString': new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#0f0',
|
||||
width: 3
|
||||
})
|
||||
}),
|
||||
'MultiPolygon': new Style({
|
||||
fill: new Fill({
|
||||
'MultiPolygon': new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,255,0.5)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#00f',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
const styleFunction = function(feature, resolution) {
|
||||
const featureStyleFunction = feature.getStyleFunction();
|
||||
var styleFunction = function(feature, resolution) {
|
||||
var featureStyleFunction = feature.getStyleFunction();
|
||||
if (featureStyleFunction) {
|
||||
return featureStyleFunction.call(feature, resolution);
|
||||
} else {
|
||||
@@ -73,38 +83,38 @@ const styleFunction = function(feature, resolution) {
|
||||
}
|
||||
};
|
||||
|
||||
const dragAndDropInteraction = new DragAndDrop({
|
||||
var dragAndDropInteraction = new ol.interaction.DragAndDrop({
|
||||
formatConstructors: [
|
||||
GPX,
|
||||
GeoJSON,
|
||||
IGC,
|
||||
KML,
|
||||
TopoJSON
|
||||
ol.format.GPX,
|
||||
ol.format.GeoJSON,
|
||||
ol.format.IGC,
|
||||
ol.format.KML,
|
||||
ol.format.TopoJSON
|
||||
]
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([dragAndDropInteraction]),
|
||||
var map = new ol.Map({
|
||||
interactions: ol.interaction.defaults().extend([dragAndDropInteraction]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new BingMaps({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.BingMaps({
|
||||
imagerySet: 'Aerial',
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
dragAndDropInteraction.on('addfeatures', function(event) {
|
||||
const vectorSource = new VectorSource({
|
||||
var vectorSource = new ol.source.Vector({
|
||||
features: event.features
|
||||
});
|
||||
map.addLayer(new VectorLayer({
|
||||
map.addLayer(new ol.layer.Vector({
|
||||
renderMode: 'image',
|
||||
source: vectorSource,
|
||||
style: styleFunction
|
||||
@@ -112,14 +122,14 @@ dragAndDropInteraction.on('addfeatures', function(event) {
|
||||
map.getView().fit(vectorSource.getExtent());
|
||||
});
|
||||
|
||||
const displayFeatureInfo = function(pixel) {
|
||||
const features = [];
|
||||
var displayFeatureInfo = function(pixel) {
|
||||
var features = [];
|
||||
map.forEachFeatureAtPixel(pixel, function(feature) {
|
||||
features.push(feature);
|
||||
});
|
||||
if (features.length > 0) {
|
||||
const info = [];
|
||||
let i, ii;
|
||||
var info = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
info.push(features[i].get('name'));
|
||||
}
|
||||
@@ -133,7 +143,7 @@ map.on('pointermove', function(evt) {
|
||||
if (evt.dragging) {
|
||||
return;
|
||||
}
|
||||
const pixel = map.getEventPixel(evt.originalEvent);
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ docs: >
|
||||
Example of using the drag-and-drop interaction. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. There is no projection transform support, so this will only work with data in EPSG:4326 and EPSG:3857.
|
||||
tags: "drag-and-drop, gpx, geojson, igc, kml, topojson"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="info"> </div>
|
||||
|
||||
@@ -1,71 +1,81 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
|
||||
import {defaults as defaultInteractions, DragAndDrop} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {BingMaps, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.format.GPX');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.format.IGC');
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.format.TopoJSON');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.DragAndDrop');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.BingMaps');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
const defaultStyle = {
|
||||
'Point': new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
var defaultStyle = {
|
||||
'Point': new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,255,0,0.5)'
|
||||
}),
|
||||
radius: 5,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#ff0',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
}),
|
||||
'LineString': new Style({
|
||||
stroke: new Stroke({
|
||||
'LineString': new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#f00',
|
||||
width: 3
|
||||
})
|
||||
}),
|
||||
'Polygon': new Style({
|
||||
fill: new Fill({
|
||||
'Polygon': new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,255,255,0.5)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#0ff',
|
||||
width: 1
|
||||
})
|
||||
}),
|
||||
'MultiPoint': new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
'MultiPoint': new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,0,255,0.5)'
|
||||
}),
|
||||
radius: 5,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#f0f',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
}),
|
||||
'MultiLineString': new Style({
|
||||
stroke: new Stroke({
|
||||
'MultiLineString': new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#0f0',
|
||||
width: 3
|
||||
})
|
||||
}),
|
||||
'MultiPolygon': new Style({
|
||||
fill: new Fill({
|
||||
'MultiPolygon': new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,255,0.5)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#00f',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
const styleFunction = function(feature, resolution) {
|
||||
const featureStyleFunction = feature.getStyleFunction();
|
||||
var styleFunction = function(feature, resolution) {
|
||||
var featureStyleFunction = feature.getStyleFunction();
|
||||
if (featureStyleFunction) {
|
||||
return featureStyleFunction.call(feature, resolution);
|
||||
} else {
|
||||
@@ -73,52 +83,52 @@ const styleFunction = function(feature, resolution) {
|
||||
}
|
||||
};
|
||||
|
||||
const dragAndDropInteraction = new DragAndDrop({
|
||||
var dragAndDropInteraction = new ol.interaction.DragAndDrop({
|
||||
formatConstructors: [
|
||||
GPX,
|
||||
GeoJSON,
|
||||
IGC,
|
||||
KML,
|
||||
TopoJSON
|
||||
ol.format.GPX,
|
||||
ol.format.GeoJSON,
|
||||
ol.format.IGC,
|
||||
ol.format.KML,
|
||||
ol.format.TopoJSON
|
||||
]
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([dragAndDropInteraction]),
|
||||
var map = new ol.Map({
|
||||
interactions: ol.interaction.defaults().extend([dragAndDropInteraction]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new BingMaps({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.BingMaps({
|
||||
imagerySet: 'Aerial',
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
dragAndDropInteraction.on('addfeatures', function(event) {
|
||||
const vectorSource = new VectorSource({
|
||||
var vectorSource = new ol.source.Vector({
|
||||
features: event.features
|
||||
});
|
||||
map.addLayer(new VectorLayer({
|
||||
map.addLayer(new ol.layer.Vector({
|
||||
source: vectorSource,
|
||||
style: styleFunction
|
||||
}));
|
||||
map.getView().fit(vectorSource.getExtent());
|
||||
});
|
||||
|
||||
const displayFeatureInfo = function(pixel) {
|
||||
const features = [];
|
||||
var displayFeatureInfo = function(pixel) {
|
||||
var features = [];
|
||||
map.forEachFeatureAtPixel(pixel, function(feature) {
|
||||
features.push(feature);
|
||||
});
|
||||
if (features.length > 0) {
|
||||
const info = [];
|
||||
let i, ii;
|
||||
var info = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
info.push(features[i].get('name'));
|
||||
}
|
||||
@@ -132,7 +142,7 @@ map.on('pointermove', function(evt) {
|
||||
if (evt.dragging) {
|
||||
return;
|
||||
}
|
||||
const pixel = map.getEventPixel(evt.originalEvent);
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultInteractions, DragRotateAndZoom} from '../src/ol/interaction.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.DragRotateAndZoom');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([
|
||||
new DragRotateAndZoom()
|
||||
var map = new ol.Map({
|
||||
interactions: ol.interaction.defaults().extend([
|
||||
new ol.interaction.DragRotateAndZoom()
|
||||
]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Draw and Modify Features
|
||||
shortdesc: Example of using the ol/interaction/Draw interaction together with the ol/interaction/Modify interaction.
|
||||
shortdesc: Example of using the ol.interaction.Draw interaction together with the ol.interaction.Modify interaction.
|
||||
docs: >
|
||||
Example of using the ol/interaction/Draw interaction together with the ol/interaction/Modify interaction.
|
||||
Example of using the ol.interaction.Draw interaction together with the ol.interaction.Modify interaction.
|
||||
tags: "draw, edit, modify, vector, featureoverlay"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,56 +1,63 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Draw, Modify, Snap} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.interaction.Modify');
|
||||
goog.require('ol.interaction.Snap');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const source = new VectorSource();
|
||||
const vector = new VectorLayer({
|
||||
var source = new ol.source.Vector();
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source,
|
||||
style: new Style({
|
||||
fill: new Fill({
|
||||
style: new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255, 255, 255, 0.2)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#ffcc33',
|
||||
width: 2
|
||||
}),
|
||||
image: new CircleStyle({
|
||||
image: new ol.style.Circle({
|
||||
radius: 7,
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: '#ffcc33'
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
const modify = new Modify({source: source});
|
||||
var modify = new ol.interaction.Modify({source: source});
|
||||
map.addInteraction(modify);
|
||||
|
||||
let draw, snap; // global so we can remove them later
|
||||
const typeSelect = document.getElementById('type');
|
||||
var draw, snap; // global so we can remove them later
|
||||
var typeSelect = document.getElementById('type');
|
||||
|
||||
function addInteractions() {
|
||||
draw = new Draw({
|
||||
draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: typeSelect.value
|
||||
});
|
||||
map.addInteraction(draw);
|
||||
snap = new Snap({source: source});
|
||||
snap = new ol.interaction.Snap({source: source});
|
||||
map.addInteraction(snap);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Draw Features
|
||||
shortdesc: Example of using the ol/interaction/Draw interaction.
|
||||
shortdesc: Example of using the ol.interaction.Draw interaction.
|
||||
docs: >
|
||||
Example of using the Draw interaction. Select a geometry type from the
|
||||
dropdown above to start drawing. To finish drawing, click the last
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Draw from '../src/ol/interaction/Draw.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const source = new VectorSource({wrapX: false});
|
||||
var source = new ol.source.Vector({wrapX: false});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
const typeSelect = document.getElementById('type');
|
||||
var typeSelect = document.getElementById('type');
|
||||
|
||||
let draw; // global so we can remove it later
|
||||
var draw; // global so we can remove it later
|
||||
function addInteraction() {
|
||||
const value = typeSelect.value;
|
||||
var value = typeSelect.value;
|
||||
if (value !== 'None') {
|
||||
draw = new Draw({
|
||||
draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: typeSelect.value
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Freehand Drawing
|
||||
shortdesc: Example using the ol/interaction/Draw interaction in freehand mode.
|
||||
shortdesc: Example using the ol.interaction.Draw interaction in freehand mode.
|
||||
docs: >
|
||||
This example demonstrates the `ol/interaction/Draw` in freehand mode. During
|
||||
This example demonstrates the `ol.interaction.Draw` in freehand mode. During
|
||||
freehand drawing, points are added while dragging. Set `freehand: true` to
|
||||
enable freehand mode. Note that freehand mode can be conditionally enabled
|
||||
by using the `freehandCondition` option. For example to toggle freehand mode
|
||||
with the `Shift` key, use `freehandCondition: shiftKeyOnly`.
|
||||
with the `Shift` key, use `freehandCondition: ol.events.condition.shiftKeyOnly`.
|
||||
tags: "draw, edit, freehand, vector"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Draw from '../src/ol/interaction/Draw.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const source = new VectorSource({wrapX: false});
|
||||
var source = new ol.source.Vector({wrapX: false});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
const typeSelect = document.getElementById('type');
|
||||
var typeSelect = document.getElementById('type');
|
||||
|
||||
let draw; // global so we can remove it later
|
||||
var draw; // global so we can remove it later
|
||||
function addInteraction() {
|
||||
const value = typeSelect.value;
|
||||
var value = typeSelect.value;
|
||||
if (value !== 'None') {
|
||||
draw = new Draw({
|
||||
draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: typeSelect.value,
|
||||
freehand: true
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Draw Shapes
|
||||
shortdesc: Using the ol/interaction/Draw to create regular shapes
|
||||
shortdesc: Using the ol.interaction.Draw to create regular shapes
|
||||
docs: >
|
||||
This demonstrates the use of the `geometryFunction` option for the
|
||||
`ol/interaction/Draw`. Select a shape type from the dropdown above to start
|
||||
`ol.interaction.Draw`. Select a shape type from the dropdown above to start
|
||||
drawing. To activate freehand drawing, hold the `Shift` key. Square drawing is
|
||||
achieved by using `type: 'Circle'` type with a `geometryFunction` that creates
|
||||
a 4-sided regular polygon instead of a circle. Box drawing uses `type: 'Circle'`
|
||||
|
||||
@@ -1,61 +1,63 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Polygon from '../src/ol/geom/Polygon.js';
|
||||
import Draw, {createRegularPolygon, createBox} from '../src/ol/interaction/Draw.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const source = new VectorSource({wrapX: false});
|
||||
var source = new ol.source.Vector({wrapX: false});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
const typeSelect = document.getElementById('type');
|
||||
var typeSelect = document.getElementById('type');
|
||||
|
||||
let draw; // global so we can remove it later
|
||||
var draw; // global so we can remove it later
|
||||
function addInteraction() {
|
||||
let value = typeSelect.value;
|
||||
var value = typeSelect.value;
|
||||
if (value !== 'None') {
|
||||
let geometryFunction;
|
||||
var geometryFunction;
|
||||
if (value === 'Square') {
|
||||
value = 'Circle';
|
||||
geometryFunction = createRegularPolygon(4);
|
||||
geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
|
||||
} else if (value === 'Box') {
|
||||
value = 'Circle';
|
||||
geometryFunction = createBox();
|
||||
geometryFunction = ol.interaction.Draw.createBox();
|
||||
} else if (value === 'Star') {
|
||||
value = 'Circle';
|
||||
geometryFunction = function(coordinates, geometry) {
|
||||
if (!geometry) {
|
||||
geometry = new Polygon(null);
|
||||
geometry = new ol.geom.Polygon(null);
|
||||
}
|
||||
const center = coordinates[0];
|
||||
const last = coordinates[1];
|
||||
const dx = center[0] - last[0];
|
||||
const dy = center[1] - last[1];
|
||||
const radius = Math.sqrt(dx * dx + dy * dy);
|
||||
const rotation = Math.atan2(dy, dx);
|
||||
const newCoordinates = [];
|
||||
const numPoints = 12;
|
||||
for (let i = 0; i < numPoints; ++i) {
|
||||
const angle = rotation + i * 2 * Math.PI / numPoints;
|
||||
const fraction = i % 2 === 0 ? 1 : 0.5;
|
||||
const offsetX = radius * fraction * Math.cos(angle);
|
||||
const offsetY = radius * fraction * Math.sin(angle);
|
||||
var center = coordinates[0];
|
||||
var last = coordinates[1];
|
||||
var dx = center[0] - last[0];
|
||||
var dy = center[1] - last[1];
|
||||
var radius = Math.sqrt(dx * dx + dy * dy);
|
||||
var rotation = Math.atan2(dy, dx);
|
||||
var newCoordinates = [];
|
||||
var numPoints = 12;
|
||||
for (var i = 0; i < numPoints; ++i) {
|
||||
var angle = rotation + i * 2 * Math.PI / numPoints;
|
||||
var fraction = i % 2 === 0 ? 1 : 0.5;
|
||||
var offsetX = radius * fraction * Math.cos(angle);
|
||||
var offsetY = radius * fraction * Math.sin(angle);
|
||||
newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
|
||||
}
|
||||
newCoordinates.push(newCoordinates[0].slice());
|
||||
@@ -63,7 +65,7 @@ function addInteraction() {
|
||||
return geometry;
|
||||
};
|
||||
}
|
||||
draw = new Draw({
|
||||
draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: value,
|
||||
geometryFunction: geometryFunction
|
||||
|
||||
@@ -1,70 +1,74 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {MultiPoint, Point} from '../src/ol/geom.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
const imageStyle = new Style({
|
||||
image: new CircleStyle({
|
||||
var imageStyle = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 5,
|
||||
snapToPixel: false,
|
||||
fill: new Fill({color: 'yellow'}),
|
||||
stroke: new Stroke({color: 'red', width: 1})
|
||||
fill: new ol.style.Fill({color: 'yellow'}),
|
||||
stroke: new ol.style.Stroke({color: 'red', width: 1})
|
||||
})
|
||||
});
|
||||
|
||||
const headInnerImageStyle = new Style({
|
||||
image: new CircleStyle({
|
||||
var headInnerImageStyle = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 2,
|
||||
snapToPixel: false,
|
||||
fill: new Fill({color: 'blue'})
|
||||
fill: new ol.style.Fill({color: 'blue'})
|
||||
})
|
||||
});
|
||||
|
||||
const headOuterImageStyle = new Style({
|
||||
image: new CircleStyle({
|
||||
var headOuterImageStyle = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 5,
|
||||
snapToPixel: false,
|
||||
fill: new Fill({color: 'black'})
|
||||
fill: new ol.style.Fill({color: 'black'})
|
||||
})
|
||||
});
|
||||
|
||||
const n = 200;
|
||||
const omegaTheta = 30000; // Rotation period in ms
|
||||
const R = 7e6;
|
||||
const r = 2e6;
|
||||
const p = 2e6;
|
||||
var n = 200;
|
||||
var omegaTheta = 30000; // Rotation period in ms
|
||||
var R = 7e6;
|
||||
var r = 2e6;
|
||||
var p = 2e6;
|
||||
map.on('postcompose', function(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
const frameState = event.frameState;
|
||||
const theta = 2 * Math.PI * frameState.time / omegaTheta;
|
||||
const coordinates = [];
|
||||
let i;
|
||||
var vectorContext = event.vectorContext;
|
||||
var frameState = event.frameState;
|
||||
var theta = 2 * Math.PI * frameState.time / omegaTheta;
|
||||
var coordinates = [];
|
||||
var i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
const t = theta + 2 * Math.PI * i / n;
|
||||
const x = (R + r) * Math.cos(t) + p * Math.cos((R + r) * t / r);
|
||||
const y = (R + r) * Math.sin(t) + p * Math.sin((R + r) * t / r);
|
||||
var t = theta + 2 * Math.PI * i / n;
|
||||
var x = (R + r) * Math.cos(t) + p * Math.cos((R + r) * t / r);
|
||||
var y = (R + r) * Math.sin(t) + p * Math.sin((R + r) * t / r);
|
||||
coordinates.push([x, y]);
|
||||
}
|
||||
vectorContext.setStyle(imageStyle);
|
||||
vectorContext.drawGeometry(new MultiPoint(coordinates));
|
||||
vectorContext.drawGeometry(new ol.geom.MultiPoint(coordinates));
|
||||
|
||||
const headPoint = new Point(coordinates[coordinates.length - 1]);
|
||||
var headPoint = new ol.geom.Point(coordinates[coordinates.length - 1]);
|
||||
|
||||
vectorContext.setStyle(headOuterImageStyle);
|
||||
vectorContext.drawGeometry(headPoint);
|
||||
|
||||
@@ -6,7 +6,7 @@ docs: >
|
||||
<p>This example parses a KML file and renders the features as clusters on a vector layer. The styling in this example is quite involved. Single earthquake locations
|
||||
(rendered as stars) have a size relative to their magnitude. Clusters have an opacity relative to the number of features in the cluster, and a size that represents
|
||||
the extent of the features that make up the cluster. When clicking or hovering on a cluster, the individual features that make up the cluster will be shown.</p>
|
||||
<p>To achieve this, we make heavy use of style functions.</p>
|
||||
<p>To achieve this, we make heavy use of style functions and <code>ol.style.Style#geometry</code>.</p>
|
||||
tags: "KML, vector, style, geometry, cluster"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,28 +1,37 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {createEmpty, getWidth, getHeight, extend} from '../src/ol/extent.js';
|
||||
import KML from '../src/ol/format/KML.js';
|
||||
import {defaults as defaultInteractions, Select} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {Cluster, Stamen, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Fill, RegularShape, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.Select');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Cluster');
|
||||
goog.require('ol.source.Stamen');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.RegularShape');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.style.Text');
|
||||
|
||||
|
||||
const earthquakeFill = new Fill({
|
||||
var earthquakeFill = new ol.style.Fill({
|
||||
color: 'rgba(255, 153, 0, 0.8)'
|
||||
});
|
||||
const earthquakeStroke = new Stroke({
|
||||
var earthquakeStroke = new ol.style.Stroke({
|
||||
color: 'rgba(255, 204, 0, 0.2)',
|
||||
width: 1
|
||||
});
|
||||
const textFill = new Fill({
|
||||
var textFill = new ol.style.Fill({
|
||||
color: '#fff'
|
||||
});
|
||||
const textStroke = new Stroke({
|
||||
var textStroke = new ol.style.Stroke({
|
||||
color: 'rgba(0, 0, 0, 0.6)',
|
||||
width: 3
|
||||
});
|
||||
const invisibleFill = new Fill({
|
||||
var invisibleFill = new ol.style.Fill({
|
||||
color: 'rgba(255, 255, 255, 0.01)'
|
||||
});
|
||||
|
||||
@@ -30,13 +39,13 @@ function createEarthquakeStyle(feature) {
|
||||
// 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
|
||||
// standards-violating <magnitude> tag in each Placemark. We extract it
|
||||
// from the Placemark's name instead.
|
||||
const name = feature.get('name');
|
||||
const magnitude = parseFloat(name.substr(2));
|
||||
const radius = 5 + 20 * (magnitude - 5);
|
||||
var name = feature.get('name');
|
||||
var magnitude = parseFloat(name.substr(2));
|
||||
var radius = 5 + 20 * (magnitude - 5);
|
||||
|
||||
return new Style({
|
||||
return new ol.style.Style({
|
||||
geometry: feature.getGeometry(),
|
||||
image: new RegularShape({
|
||||
image: new ol.style.RegularShape({
|
||||
radius1: radius,
|
||||
radius2: 3,
|
||||
points: 5,
|
||||
@@ -47,78 +56,77 @@ function createEarthquakeStyle(feature) {
|
||||
});
|
||||
}
|
||||
|
||||
let maxFeatureCount;
|
||||
let vector = null;
|
||||
const calculateClusterInfo = function(resolution) {
|
||||
var maxFeatureCount, vector;
|
||||
function calculateClusterInfo(resolution) {
|
||||
maxFeatureCount = 0;
|
||||
const features = vector.getSource().getFeatures();
|
||||
let feature, radius;
|
||||
for (let i = features.length - 1; i >= 0; --i) {
|
||||
var features = vector.getSource().getFeatures();
|
||||
var feature, radius;
|
||||
for (var i = features.length - 1; i >= 0; --i) {
|
||||
feature = features[i];
|
||||
const originalFeatures = feature.get('features');
|
||||
const extent = createEmpty();
|
||||
let j, jj;
|
||||
var originalFeatures = feature.get('features');
|
||||
var extent = ol.extent.createEmpty();
|
||||
var j, jj;
|
||||
for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
|
||||
extend(extent, originalFeatures[j].getGeometry().getExtent());
|
||||
ol.extent.extend(extent, originalFeatures[j].getGeometry().getExtent());
|
||||
}
|
||||
maxFeatureCount = Math.max(maxFeatureCount, jj);
|
||||
radius = 0.25 * (getWidth(extent) + getHeight(extent)) /
|
||||
radius = 0.25 * (ol.extent.getWidth(extent) + ol.extent.getHeight(extent)) /
|
||||
resolution;
|
||||
feature.set('radius', radius);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let currentResolution;
|
||||
var currentResolution;
|
||||
function styleFunction(feature, resolution) {
|
||||
if (resolution != currentResolution) {
|
||||
calculateClusterInfo(resolution);
|
||||
currentResolution = resolution;
|
||||
}
|
||||
let style;
|
||||
const size = feature.get('features').length;
|
||||
var style;
|
||||
var size = feature.get('features').length;
|
||||
if (size > 1) {
|
||||
style = new Style({
|
||||
image: new CircleStyle({
|
||||
style = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: feature.get('radius'),
|
||||
fill: new Fill({
|
||||
fill: new ol.style.Fill({
|
||||
color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
|
||||
})
|
||||
}),
|
||||
text: new Text({
|
||||
text: new ol.style.Text({
|
||||
text: size.toString(),
|
||||
fill: textFill,
|
||||
stroke: textStroke
|
||||
})
|
||||
});
|
||||
} else {
|
||||
const originalFeature = feature.get('features')[0];
|
||||
var originalFeature = feature.get('features')[0];
|
||||
style = createEarthquakeStyle(originalFeature);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
function selectStyleFunction(feature) {
|
||||
const styles = [new Style({
|
||||
image: new CircleStyle({
|
||||
var styles = [new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: feature.get('radius'),
|
||||
fill: invisibleFill
|
||||
})
|
||||
})];
|
||||
const originalFeatures = feature.get('features');
|
||||
let originalFeature;
|
||||
for (let i = originalFeatures.length - 1; i >= 0; --i) {
|
||||
var originalFeatures = feature.get('features');
|
||||
var originalFeature;
|
||||
for (var i = originalFeatures.length - 1; i >= 0; --i) {
|
||||
originalFeature = originalFeatures[i];
|
||||
styles.push(createEarthquakeStyle(originalFeature));
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
|
||||
vector = new VectorLayer({
|
||||
source: new Cluster({
|
||||
vector = new ol.layer.Vector({
|
||||
source: new ol.source.Cluster({
|
||||
distance: 40,
|
||||
source: new VectorSource({
|
||||
source: new ol.source.Vector({
|
||||
url: 'data/kml/2012_Earthquakes_Mag5.kml',
|
||||
format: new KML({
|
||||
format: new ol.format.KML({
|
||||
extractStyles: false
|
||||
})
|
||||
})
|
||||
@@ -126,15 +134,15 @@ vector = new VectorLayer({
|
||||
style: styleFunction
|
||||
});
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new Stamen({
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
interactions: defaultInteractions().extend([new Select({
|
||||
interactions: ol.interaction.defaults().extend([new ol.interaction.Select({
|
||||
condition: function(evt) {
|
||||
return evt.type == 'pointermove' ||
|
||||
evt.type == 'singleclick';
|
||||
@@ -142,7 +150,7 @@ const map = new Map({
|
||||
style: selectStyleFunction
|
||||
})]),
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Earthquakes with custom symbols
|
||||
shortdesc: Demonstrates the use of `toCanvas` to create custom icon symbols.
|
||||
shortdesc: Demonstrates the use of `ol.render.toCanvas` to create custom icon symbols.
|
||||
docs: >
|
||||
This example parses a KML file and renders the features as a vector layer. The layer is given a <code>style</code> that renders earthquake locations with a custom lightning symbol and a size relative to their magnitude.
|
||||
tags: "KML, vector, style, canvas, symbol"
|
||||
|
||||
@@ -1,42 +1,47 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import KML from '../src/ol/format/KML.js';
|
||||
import Polygon from '../src/ol/geom/Polygon.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {toContext} from '../src/ol/render.js';
|
||||
import Stamen from '../src/ol/source/Stamen.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Fill, Icon, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.render');
|
||||
goog.require('ol.source.Stamen');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Icon');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
const symbol = [[0, 0], [4, 2], [6, 0], [10, 5], [6, 3], [4, 5], [0, 0]];
|
||||
let scale;
|
||||
const scaleFunction = function(coordinate) {
|
||||
var symbol = [[0, 0], [4, 2], [6, 0], [10, 5], [6, 3], [4, 5], [0, 0]];
|
||||
var scale;
|
||||
var scaleFunction = function(coordinate) {
|
||||
return [coordinate[0] * scale, coordinate[1] * scale];
|
||||
};
|
||||
|
||||
const styleCache = {};
|
||||
const styleFunction = function(feature) {
|
||||
var styleCache = {};
|
||||
var styleFunction = function(feature) {
|
||||
// 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
|
||||
// standards-violating <magnitude> tag in each Placemark. We extract it from
|
||||
// the Placemark's name instead.
|
||||
const name = feature.get('name');
|
||||
const magnitude = parseFloat(name.substr(2));
|
||||
const size = parseInt(10 + 40 * (magnitude - 5), 10);
|
||||
var name = feature.get('name');
|
||||
var magnitude = parseFloat(name.substr(2));
|
||||
var size = parseInt(10 + 40 * (magnitude - 5), 10);
|
||||
scale = size / 10;
|
||||
let style = styleCache[size];
|
||||
var style = styleCache[size];
|
||||
if (!style) {
|
||||
const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
|
||||
const vectorContext = toContext(
|
||||
/** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
|
||||
{size: [size, size], pixelRatio: 1});
|
||||
vectorContext.setStyle(new Style({
|
||||
fill: new Fill({color: 'rgba(255, 153, 0, 0.4)'}),
|
||||
stroke: new Stroke({color: 'rgba(255, 204, 0, 0.2)', width: 2})
|
||||
var canvas =
|
||||
/** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
|
||||
var vectorContext = ol.render.toContext(
|
||||
/** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
|
||||
{size: [size, size], pixelRatio: 1});
|
||||
vectorContext.setStyle(new ol.style.Style({
|
||||
fill: new ol.style.Fill({color: 'rgba(255, 153, 0, 0.4)'}),
|
||||
stroke: new ol.style.Stroke({color: 'rgba(255, 204, 0, 0.2)', width: 2})
|
||||
}));
|
||||
vectorContext.drawGeometry(new Polygon([symbol.map(scaleFunction)]));
|
||||
style = new Style({
|
||||
image: new Icon({
|
||||
vectorContext.drawGeometry(new ol.geom.Polygon([symbol.map(scaleFunction)]));
|
||||
style = new ol.style.Style({
|
||||
image: new ol.style.Icon({
|
||||
img: canvas,
|
||||
imgSize: [size, size],
|
||||
rotation: 1.2
|
||||
@@ -47,26 +52,26 @@ const styleFunction = function(feature) {
|
||||
return style;
|
||||
};
|
||||
|
||||
const vector = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
url: 'data/kml/2012_Earthquakes_Mag5.kml',
|
||||
format: new KML({
|
||||
format: new ol.format.KML({
|
||||
extractStyles: false
|
||||
})
|
||||
}),
|
||||
style: styleFunction
|
||||
});
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new Stamen({
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls, ScaleLine} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import TileWMS from '../src/ol/source/TileWMS.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.control.ScaleLine');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.TileWMS');
|
||||
|
||||
|
||||
const layers = [
|
||||
new TileLayer({
|
||||
source: new TileWMS({
|
||||
var layers = [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileWMS({
|
||||
url: 'https://ahocevar.com/geoserver/wms',
|
||||
params: {
|
||||
'LAYERS': 'ne:NE1_HR_LC_SR_W_DR',
|
||||
@@ -17,15 +18,15 @@ const layers = [
|
||||
})
|
||||
];
|
||||
|
||||
const map = new Map({
|
||||
controls: defaultControls().extend([
|
||||
new ScaleLine({
|
||||
var map = new ol.Map({
|
||||
controls: ol.control.defaults().extend([
|
||||
new ol.control.ScaleLine({
|
||||
units: 'degrees'
|
||||
})
|
||||
]),
|
||||
layers: layers,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
projection: 'EPSG:4326',
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
// NOCOMPILE
|
||||
// this example uses FileSaver.js for which we don't have an externs file.
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
format: new ol.format.GeoJSON()
|
||||
})
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
}),
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
@@ -33,7 +35,7 @@ const map = new Map({
|
||||
|
||||
document.getElementById('export-png').addEventListener('click', function() {
|
||||
map.once('postcompose', function(event) {
|
||||
const canvas = event.context.canvas;
|
||||
var canvas = event.context.canvas;
|
||||
if (navigator.msSaveBlob) {
|
||||
navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
|
||||
} else {
|
||||
|
||||
@@ -1,46 +1,47 @@
|
||||
// NOCOMPILE
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import WKT from '../src/ol/format/WKT.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {unByKey} from '../src/ol/Observable.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.format.WKT');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM()
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
const format = new WKT();
|
||||
const feature = format.readFeature(
|
||||
'POLYGON((10.689697265625 -25.0927734375, 34.595947265625 ' +
|
||||
var format = new ol.format.WKT();
|
||||
var feature = format.readFeature(
|
||||
'POLYGON((10.689697265625 -25.0927734375, 34.595947265625 ' +
|
||||
'-20.1708984375, 38.814697265625 -35.6396484375, 13.502197265625 ' +
|
||||
'-39.1552734375, 10.689697265625 -25.0927734375))');
|
||||
feature.getGeometry().transform('EPSG:4326', 'EPSG:3857');
|
||||
|
||||
const vector = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [feature]
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
}),
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
const dims = {
|
||||
var dims = {
|
||||
a0: [1189, 841],
|
||||
a1: [841, 594],
|
||||
a2: [594, 420],
|
||||
@@ -49,75 +50,61 @@ const dims = {
|
||||
a5: [210, 148]
|
||||
};
|
||||
|
||||
let loading = 0;
|
||||
let loaded = 0;
|
||||
var loading = 0;
|
||||
var loaded = 0;
|
||||
|
||||
const exportButton = document.getElementById('export-pdf');
|
||||
var exportButton = document.getElementById('export-pdf');
|
||||
|
||||
exportButton.addEventListener('click', function() {
|
||||
|
||||
exportButton.disabled = true;
|
||||
document.body.style.cursor = 'progress';
|
||||
|
||||
const format = document.getElementById('format').value;
|
||||
const resolution = document.getElementById('resolution').value;
|
||||
const dim = dims[format];
|
||||
const width = Math.round(dim[0] * resolution / 25.4);
|
||||
const height = Math.round(dim[1] * resolution / 25.4);
|
||||
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
||||
const extent = map.getView().calculateExtent(size);
|
||||
var format = document.getElementById('format').value;
|
||||
var resolution = document.getElementById('resolution').value;
|
||||
var dim = dims[format];
|
||||
var width = Math.round(dim[0] * resolution / 25.4);
|
||||
var height = Math.round(dim[1] * resolution / 25.4);
|
||||
var size = /** @type {ol.Size} */ (map.getSize());
|
||||
var extent = map.getView().calculateExtent(size);
|
||||
|
||||
const source = raster.getSource();
|
||||
var source = raster.getSource();
|
||||
|
||||
const tileLoadStart = function() {
|
||||
var tileLoadStart = function() {
|
||||
++loading;
|
||||
};
|
||||
|
||||
let timer;
|
||||
let keys = [];
|
||||
|
||||
function tileLoadEndFactory(canvas) {
|
||||
return () => {
|
||||
++loaded;
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
if (loading === loaded) {
|
||||
timer = window.setTimeout(() => {
|
||||
loading = 0;
|
||||
loaded = 0;
|
||||
const data = canvas.toDataURL('image/jpeg');
|
||||
const pdf = new jsPDF('landscape', undefined, format);
|
||||
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
|
||||
pdf.save('map.pdf');
|
||||
keys.forEach(unByKey);
|
||||
keys = [];
|
||||
map.setSize(size);
|
||||
map.getView().fit(extent, {size});
|
||||
map.renderSync();
|
||||
exportButton.disabled = false;
|
||||
document.body.style.cursor = 'auto';
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
}
|
||||
var tileLoadEnd = function() {
|
||||
++loaded;
|
||||
if (loading === loaded) {
|
||||
var canvas = this;
|
||||
window.setTimeout(function() {
|
||||
loading = 0;
|
||||
loaded = 0;
|
||||
var data = canvas.toDataURL('image/png');
|
||||
var pdf = new jsPDF('landscape', undefined, format);
|
||||
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
|
||||
pdf.save('map.pdf');
|
||||
source.un('tileloadstart', tileLoadStart);
|
||||
source.un('tileloadend', tileLoadEnd, canvas);
|
||||
source.un('tileloaderror', tileLoadEnd, canvas);
|
||||
map.setSize(size);
|
||||
map.getView().fit(extent);
|
||||
map.renderSync();
|
||||
exportButton.disabled = false;
|
||||
document.body.style.cursor = 'auto';
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
map.once('postcompose', function(event) {
|
||||
const canvas = event.context.canvas;
|
||||
const tileLoadEnd = tileLoadEndFactory(canvas);
|
||||
keys = [
|
||||
source.on('tileloadstart', tileLoadStart),
|
||||
source.on('tileloadend', tileLoadEnd),
|
||||
source.on('tileloaderror', tileLoadEnd)
|
||||
];
|
||||
tileLoadEnd();
|
||||
source.on('tileloadstart', tileLoadStart);
|
||||
source.on('tileloadend', tileLoadEnd, event.context.canvas);
|
||||
source.on('tileloaderror', tileLoadEnd, event.context.canvas);
|
||||
});
|
||||
|
||||
const printSize = [width, height];
|
||||
map.setSize(printSize);
|
||||
map.getView().fit(extent, {size: printSize});
|
||||
loaded = -1;
|
||||
map.setSize([width, height]);
|
||||
map.getView().fit(extent);
|
||||
map.renderSync();
|
||||
|
||||
}, false);
|
||||
|
||||
@@ -1,45 +1,47 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {platformModifierKeyOnly} from '../src/ol/events/condition.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import ExtentInteraction from '../src/ol/interaction/Extent.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.interaction.Extent');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
var vectorSource = new ol.source.Vector({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
format: new ol.format.GeoJSON()
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
}),
|
||||
new VectorLayer({
|
||||
new ol.layer.Vector({
|
||||
source: vectorSource
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
const extent = new ExtentInteraction({
|
||||
condition: platformModifierKeyOnly
|
||||
var extent = new ol.interaction.Extent({
|
||||
condition: ol.events.condition.platformModifierKeyOnly
|
||||
});
|
||||
map.addInteraction(extent);
|
||||
extent.setActive(false);
|
||||
|
||||
//Enable interaction by holding shift
|
||||
window.addEventListener('keydown', function(event) {
|
||||
this.addEventListener('keydown', function(event) {
|
||||
if (event.keyCode == 16) {
|
||||
extent.setActive(true);
|
||||
}
|
||||
});
|
||||
window.addEventListener('keyup', function(event) {
|
||||
this.addEventListener('keyup', function(event) {
|
||||
if (event.keyCode == 16) {
|
||||
extent.setActive(false);
|
||||
}
|
||||
|
||||
@@ -1,72 +1,77 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import {unByKey} from '../src/ol/Observable.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||
import {easeOut} from '../src/ol/easing.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Stroke, Style} from '../src/ol/style.js';
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.Observable');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.control');
|
||||
goog.require('ol.easing');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
const map = new Map({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM({
|
||||
wrapX: false
|
||||
})
|
||||
})
|
||||
],
|
||||
controls: defaultControls({
|
||||
controls: ol.control.defaults({
|
||||
attributionOptions: {
|
||||
collapsible: false
|
||||
}
|
||||
}),
|
||||
target: 'map',
|
||||
view: new View({
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
})
|
||||
});
|
||||
|
||||
const source = new VectorSource({
|
||||
var source = new ol.source.Vector({
|
||||
wrapX: false
|
||||
});
|
||||
const vector = new VectorLayer({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source
|
||||
});
|
||||
map.addLayer(vector);
|
||||
|
||||
function addRandomFeature() {
|
||||
const x = Math.random() * 360 - 180;
|
||||
const y = Math.random() * 180 - 90;
|
||||
const geom = new Point(fromLonLat([x, y]));
|
||||
const feature = new Feature(geom);
|
||||
var x = Math.random() * 360 - 180;
|
||||
var y = Math.random() * 180 - 90;
|
||||
var geom = new ol.geom.Point(ol.proj.transform([x, y],
|
||||
'EPSG:4326', 'EPSG:3857'));
|
||||
var feature = new ol.Feature(geom);
|
||||
source.addFeature(feature);
|
||||
}
|
||||
|
||||
const duration = 3000;
|
||||
var duration = 3000;
|
||||
function flash(feature) {
|
||||
const start = new Date().getTime();
|
||||
const listenerKey = map.on('postcompose', animate);
|
||||
var start = new Date().getTime();
|
||||
var listenerKey;
|
||||
|
||||
function animate(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
const frameState = event.frameState;
|
||||
const flashGeom = feature.getGeometry().clone();
|
||||
const elapsed = frameState.time - start;
|
||||
const elapsedRatio = elapsed / duration;
|
||||
var vectorContext = event.vectorContext;
|
||||
var frameState = event.frameState;
|
||||
var flashGeom = feature.getGeometry().clone();
|
||||
var elapsed = frameState.time - start;
|
||||
var elapsedRatio = elapsed / duration;
|
||||
// radius will be 5 at start and 30 at end.
|
||||
const radius = easeOut(elapsedRatio) * 25 + 5;
|
||||
const opacity = easeOut(1 - elapsedRatio);
|
||||
var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5;
|
||||
var opacity = ol.easing.easeOut(1 - elapsedRatio);
|
||||
|
||||
const style = new Style({
|
||||
image: new CircleStyle({
|
||||
var style = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: radius,
|
||||
snapToPixel: false,
|
||||
stroke: new Stroke({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgba(255, 0, 0, ' + opacity + ')',
|
||||
width: 0.25 + opacity
|
||||
})
|
||||
@@ -76,12 +81,13 @@ function flash(feature) {
|
||||
vectorContext.setStyle(style);
|
||||
vectorContext.drawGeometry(flashGeom);
|
||||
if (elapsed > duration) {
|
||||
unByKey(listenerKey);
|
||||
ol.Observable.unByKey(listenerKey);
|
||||
return;
|
||||
}
|
||||
// tell OpenLayers to continue postcompose animation
|
||||
map.render();
|
||||
}
|
||||
listenerKey = map.on('postcompose', animate);
|
||||
}
|
||||
|
||||
source.on('addfeature', function(e) {
|
||||
|
||||
@@ -8,8 +8,7 @@ docs: >
|
||||
is being used.
|
||||
tags: "animation, feature, postcompose, polyline"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<label for="speed">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user