Compare commits
138 Commits
v3.0.0-gam
...
v3.0.0-gam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f468239e71 | ||
|
|
4b8ceca8eb | ||
|
|
10ffc8953b | ||
|
|
d846fbc0b4 | ||
|
|
f5bb790509 | ||
|
|
9fd5c1370e | ||
|
|
caa0b568ad | ||
|
|
7bbd27e68e | ||
|
|
2b0284a342 | ||
|
|
234cff4de5 | ||
|
|
1daf36956c | ||
|
|
42f953d08d | ||
|
|
e5a0e736ca | ||
|
|
2365e73bef | ||
|
|
9bd1ab78fc | ||
|
|
9c70a49fb0 | ||
|
|
9f19569144 | ||
|
|
9de010c791 | ||
|
|
c25b1e939e | ||
|
|
d50f40dcce | ||
|
|
280a7c520f | ||
|
|
31c9f5806e | ||
|
|
ba8077010a | ||
|
|
c1f7db9611 | ||
|
|
a314203e12 | ||
|
|
a43c546667 | ||
|
|
a71714e8b6 | ||
|
|
16cdd35f6d | ||
|
|
c1d49a8cef | ||
|
|
b945147950 | ||
|
|
b29195639f | ||
|
|
b2e345c407 | ||
|
|
7fbc4e3bff | ||
|
|
d3e575339b | ||
|
|
9bcafc0fab | ||
|
|
8b7f80c64e | ||
|
|
64c03d0f9c | ||
|
|
e81e030dcd | ||
|
|
288c997322 | ||
|
|
1d22113420 | ||
|
|
962b94444c | ||
|
|
a8961877e8 | ||
|
|
8cf48eac4f | ||
|
|
7b7788973b | ||
|
|
ddfe11042b | ||
|
|
8e106a2c98 | ||
|
|
8d805c6403 | ||
|
|
3f1f450d5c | ||
|
|
a9d68a1899 | ||
|
|
e593e5fb60 | ||
|
|
74dbd2b3e5 | ||
|
|
aa4ee80033 | ||
|
|
fa7ff506fc | ||
|
|
eb71e8e92d | ||
|
|
82b921ff06 | ||
|
|
fee4c79757 | ||
|
|
73951394f9 | ||
|
|
434bf0bf42 | ||
|
|
9838687d88 | ||
|
|
cee5b81ec2 | ||
|
|
71b2bf73de | ||
|
|
02a2c5aceb | ||
|
|
dbb72f5080 | ||
|
|
b4f6baa613 | ||
|
|
e9c6e58663 | ||
|
|
737e063937 | ||
|
|
4dc601f30d | ||
|
|
28a23a11b5 | ||
|
|
3ac7cb58af | ||
|
|
346ff9c186 | ||
|
|
4dccb32545 | ||
|
|
ad272a1b3a | ||
|
|
b0c0d077c9 | ||
|
|
12d94e1405 | ||
|
|
10aa2019e7 | ||
|
|
2b1c96a7ea | ||
|
|
c9d44fe842 | ||
|
|
e56f759574 | ||
|
|
6a0d08eafd | ||
|
|
b77af6d416 | ||
|
|
b7b5de659b | ||
|
|
60f1874766 | ||
|
|
0b9936107d | ||
|
|
7ca069de39 | ||
|
|
8383f60fcf | ||
|
|
aa9dab092a | ||
|
|
38b36a09bd | ||
|
|
b96fb6ad3a | ||
|
|
1cbedadf48 | ||
|
|
1657ed2d23 | ||
|
|
7a26966c8d | ||
|
|
685265e1db | ||
|
|
9e3b46762b | ||
|
|
1e7dc5cd32 | ||
|
|
4abc887f5d | ||
|
|
fe8a72dce5 | ||
|
|
0bd9be547d | ||
|
|
aecaa52cb1 | ||
|
|
4f7073d7aa | ||
|
|
4de2520109 | ||
|
|
4aa76977d2 | ||
|
|
fe1131b850 | ||
|
|
a2e7432e42 | ||
|
|
d7f4a06f61 | ||
|
|
f57a364534 | ||
|
|
bd08bfe6c8 | ||
|
|
313e313f7a | ||
|
|
9131512598 | ||
|
|
307ee09988 | ||
|
|
3e2350b2a0 | ||
|
|
29d581bbee | ||
|
|
aa85318d78 | ||
|
|
97f9527f41 | ||
|
|
4c03b3b35c | ||
|
|
621aafbdde | ||
|
|
cc9acef01f | ||
|
|
5cd202d50b | ||
|
|
be09368359 | ||
|
|
3259b1078c | ||
|
|
7286c29fbc | ||
|
|
847440f30a | ||
|
|
f5830cc8e5 | ||
|
|
5010596ec0 | ||
|
|
db431ebdc6 | ||
|
|
df2c14b7af | ||
|
|
c93e80a14a | ||
|
|
543250c88a | ||
|
|
59fe635b46 | ||
|
|
753727c15f | ||
|
|
96ec96c4d5 | ||
|
|
046ae42b38 | ||
|
|
a6f921d443 | ||
|
|
3e23da7c83 | ||
|
|
aa4dbde841 | ||
|
|
8c1ad54bd8 | ||
|
|
3b8e182856 | ||
|
|
521cbfb1b0 | ||
|
|
b396773183 |
307
CONTRIBUTING.md
307
CONTRIBUTING.md
@@ -4,18 +4,301 @@ Thanks for your interest in contributing to OpenLayers 3.
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Our preferred means of receiving contributions is through [pull
|
||||
requests](https://help.github.com/articles/using-pull-requests).
|
||||
Our preferred means of receiving contributions is through [pull requests](https://help.github.com/articles/using-pull-requests). Make sure
|
||||
that your pull request follows our pull request guidelines below before submitting it.
|
||||
|
||||
See the [Developer
|
||||
Guide](https://github.com/openlayers/ol3/wiki/Developer-Guide) to get started
|
||||
with OpenLayers 3 development. This guide provides information you should know
|
||||
before creating pull requests.
|
||||
This page describes what you need to know to contribute code to ol3 as a developer.
|
||||
|
||||
Note that, 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](http://www.openlayers.org/ccla.txt). If you are
|
||||
## Contributor License Agreement
|
||||
|
||||
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).
|
||||
Contributor License Agreement](https://docs.google.com/spreadsheet/viewform?formkey=dGNNVUJEMXF2dERTU0FXM3JjNVBQblE6MQ).
|
||||
|
||||
## Setting up development environment
|
||||
|
||||
You will obviously start by
|
||||
[forking](https://github.com/openlayers/ol3/fork_select) the ol3 repository.
|
||||
|
||||
### Travis CI
|
||||
|
||||
The Travis CI hook is enabled on the Github repository. This means every pull request
|
||||
is run through a full test suite to ensure it compiles and passes the tests. Failing
|
||||
pull requests will not be merged.
|
||||
|
||||
Although not mandatory, it is also recommended to set up Travis CI for your ol3 fork.
|
||||
For that go to your ol3 fork's Service Hooks page and set up the Travis hook.
|
||||
Then every time you push to your fork, the test suite will be run. This means
|
||||
errors can be caught before creating a pull request. For those making
|
||||
small or occasional contributions, this may be enough to check that your contributions
|
||||
are ok; in this case, you do not need to install the build tools on your local environment
|
||||
as described below.
|
||||
|
||||
### Development dependencies
|
||||
|
||||
The minimum requirements are:
|
||||
|
||||
* Git
|
||||
* [Node.js](http://nodejs.org/)
|
||||
* Python 2.6 or 2.7 with a couple of extra modules (see below)
|
||||
* Java 7 (JRE and JDK)
|
||||
|
||||
The executables `git`, `java`, `jar`, and `python` should be in your `PATH`.
|
||||
|
||||
You can check your configuration by running:
|
||||
|
||||
$ ./build.py checkdeps
|
||||
|
||||
To install the Node.js dependencies run
|
||||
|
||||
$ npm install
|
||||
|
||||
To install the extra Python modules, run:
|
||||
|
||||
$ sudo pip install -r requirements.txt
|
||||
or
|
||||
|
||||
$ cat requirements.txt | sudo xargs easy_install
|
||||
|
||||
depending on your OS and Python installation.
|
||||
|
||||
## Working with the build tool
|
||||
|
||||
As an ol3 developer you will need to use the `build.py` Python script. This is
|
||||
the script to use to run the linter, the compiler, the tests, etc. Windows users
|
||||
can use `build.cmd` which is a thin wrapper around `build.py`.
|
||||
|
||||
The `build.py` script is equivalent to a Makefile. It is actually based on
|
||||
[pake](https://github.com/twpayne/pake/), which is a simple implementation of
|
||||
`make` in Python.
|
||||
|
||||
The usage of the script is:
|
||||
|
||||
$ ./build.py <target>
|
||||
|
||||
where `<target>` is the name of the build target you want to execute. For
|
||||
example:
|
||||
|
||||
$ ./build.py 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 ol3's [Travis configuration file](https://github.com/openlayers/ol3/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:
|
||||
|
||||
$ ./build.py 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:
|
||||
|
||||
$ ./build.py serve
|
||||
|
||||
Then, just point your browser <http://localhost:3000/examples> in your browser. For example <http://localhost:3000/examples/side-by-side.html>.
|
||||
|
||||
Run examples against the `ol.js` standalone build:
|
||||
|
||||
The examples can also be run against the `ol.js` standalone lib, just like the examples
|
||||
[hosted](http://openlayers.github.com/ol3/master/examples/) on GitHub. Start by
|
||||
executing the `host-examples` build target:
|
||||
|
||||
$ ./build.py host-examples
|
||||
|
||||
After running `host-examples` you can now open the examples index page in the browser, for example: <http://localhost/~elemoine/ol3/build/hosted/master/examples/>. (This assumes that the `hosted` directory is a web directory, served by Apache for example.)
|
||||
|
||||
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 in a browser start the dev server (`./build.py serve`) and open <http://localhost:3000/test/index.html> in the browser.
|
||||
|
||||
To run the tests on the console (headless testing with PhantomJS) use the `test` target:
|
||||
|
||||
$ ./build.py test
|
||||
|
||||
See also the test-specific [README](../blob/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:
|
||||
|
||||
$ ./build.py 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
|
||||
|
||||
Adding functionality often implies adding one or several examples. This
|
||||
section provides explanations related to adding examples.
|
||||
|
||||
The examples are located in the `examples` directory. Adding a new example
|
||||
implies creating two files in this directory, an `.html` file and a `.js` file.
|
||||
See `examples/simple.html` and `examples/simple.js` for instance.
|
||||
|
||||
The `.html` file needs to include a script tag with
|
||||
`loader.js?id=<example_name>` as its `src`. For example, if the two files for
|
||||
the example are `myexample.js` and `myexample.html` then the script tag's `src`
|
||||
should be set to `myexample`.
|
||||
|
||||
You can use `simple.js` and `simple.html` as templates for new examples.
|
||||
|
||||
### Use of the `goog` namespace in examples
|
||||
|
||||
Short story: the ol3 examples should not use the `goog` namespace, except
|
||||
for `goog.require`.
|
||||
|
||||
Longer story: we want that the ol3 examples work in multiple modes, with the
|
||||
standalone lib (which has implications of the symbols and properties we
|
||||
export), and compiled together with the ol3 library.
|
||||
|
||||
Compiling the examples together with the library makes it mandatory to declare dependencies with `goog.require` statements.
|
||||
|
||||
## Pull request guidelines
|
||||
|
||||
Your pull request must:
|
||||
|
||||
* Follow OpenLayers 3's coding style.
|
||||
|
||||
* Pass the integration tests run automatically by the Travis Continuous
|
||||
Integration system.
|
||||
|
||||
* Address a single issue or add a single item of functionality.
|
||||
|
||||
* Contain a clean history of small, incremental, logically separate commits,
|
||||
with no merge commits.
|
||||
|
||||
* Use clear commit messages.
|
||||
|
||||
* Be possible to merge automatically.
|
||||
|
||||
|
||||
### The `check` build target
|
||||
|
||||
It is strongly recommended that you run
|
||||
|
||||
$ ./build.py 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 3's coding style
|
||||
|
||||
OpenLayers 3 follows [Google's JavaScript Style
|
||||
Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).
|
||||
This is checked using the [Closure
|
||||
Linter](https://developers.google.com/closure/utilities/) in strict mode. You
|
||||
can run the linter locally on your machine before committing using the `lint`
|
||||
target to `build.py`:
|
||||
|
||||
$ ./build.py lint
|
||||
|
||||
In addition to fixing problems identified by the linter, please also follow the
|
||||
style of the existing OpenLayers 3 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.
|
||||
|
||||
|
||||
### 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 3 style and does not break tests or examples. You
|
||||
can run the integration tests locally using the `ci` target:
|
||||
|
||||
$ ./build.py ci
|
||||
|
||||
|
||||
### Address a single issue or add a single item of functionality
|
||||
|
||||
Please submit separate pull requests for separate issues. This allows each to
|
||||
be reviewed on its own merits.
|
||||
|
||||
|
||||
### Contain a clean history of small, incremental, logically separate commits, with no merge commits
|
||||
|
||||
The commit history explains to the reviewer the series of modifications to the
|
||||
code that you have made and breaks the overall contribution into a series of
|
||||
easily-understandable chunks. Any individual commit should not add more than
|
||||
one new class or one new function. Do not submit commits that change thousands
|
||||
of lines or that contain more than one distinct logical change. Trivial
|
||||
commits, e.g. to fix lint errors, should be merged into the commit that
|
||||
introduced the error. See the [Atomic Commit Convention on Wikipedia](http://en.wikipedia.org/wiki/Atomic_commit#Atomic_Commit_Convention) for more detail.
|
||||
|
||||
`git apply --patch` and `git rebase` can help you create a clean commit
|
||||
history.
|
||||
[Reviewboard.org](http://www.reviewboard.org/docs/codebase/dev/git/clean-commits/)
|
||||
and [Pro GIT](http://git-scm.com/book/en/Git-Tools-Rewriting-History) have
|
||||
explain how to use them.
|
||||
|
||||
|
||||
### Use clear commit messages
|
||||
|
||||
Commit messages should be short, begin with a verb in the imperative, and
|
||||
contain no trailing punctuation. We follow
|
||||
http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
||||
for the formatting of commit messages.
|
||||
|
||||
Git commit message should look like:
|
||||
|
||||
Header line: explaining the commit in one line
|
||||
|
||||
Body of commit message is a few lines of text, explaining things
|
||||
in more detail, possibly giving some background about the issue
|
||||
being fixed, etc etc.
|
||||
|
||||
The body of the commit message can be several paragraphs, and
|
||||
please do proper word-wrap and keep columns shorter than about
|
||||
74 characters or so. That way "git log" will show things
|
||||
nicely even when it's indented.
|
||||
|
||||
Further paragraphs come after blank lines.
|
||||
|
||||
Please keep the header line short, no more than 50 characters.
|
||||
|
||||
### Be possible to merge automatically
|
||||
|
||||
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.
|
||||
|
||||
@@ -30,7 +30,7 @@ Interactions for [vector features](ol.Feature.html)
|
||||
<br>[Formats](ol.format.Feature.html) for reading/writing vector data
|
||||
<br>[ol.format.WMSCapabilities](ol.format.WMSCapabilities.html)</td></tr>
|
||||
<tr><th>Projections</th><th>2-way bindings</th><th>Other components</th></tr>
|
||||
<tr><td><p>All coordinates and extents need to be provided in view projection (default: [EPSG:3857](ol.proj.EPSG3857.html)). To transform, use [ol.proj.transform()](ol.proj.html#transform) and [ol.extent.applyTransform()](ol.extent.html#applyTransform).</p>
|
||||
<tr><td><p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform, use [ol.proj.transform()](ol.proj.html#transform) and [ol.proj.transformExtent()](ol.proj.html#transformExtent).</p>
|
||||
[ol.proj](ol.proj.html)</td>
|
||||
<td><p>[Objects](ol.Object.html) can be kept in sync using the [bindTo()](ol.Object.html#bindTo) method.</p>
|
||||
<p>A [DOM Input](ol.dom.Input.html) class is available to bind Object properties to HTML Input elements.</p></td>
|
||||
|
||||
@@ -72,7 +72,6 @@ function includeAugments(doclet) {
|
||||
}
|
||||
|
||||
var api = [];
|
||||
var augments = {};
|
||||
var classes = {};
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
@@ -19,7 +19,7 @@ exports.handlers = {
|
||||
|
||||
parseComplete: function(e) {
|
||||
var doclets = e.doclets;
|
||||
var eventClass, doclet, i, ii, j, jj, event, fires;
|
||||
var doclet, i, ii, j, jj, event, fires;
|
||||
for (i = 0, ii = doclets.length - 1; i < ii; ++i) {
|
||||
doclet = doclets[i];
|
||||
if (doclet.fires) {
|
||||
|
||||
@@ -87,7 +87,7 @@ exports.handlers = {
|
||||
for (l = candidates.length - 1; l >= 0; --l) {
|
||||
candidate = candidates[l];
|
||||
if (candidate && !candidate.inheritdoc) {
|
||||
stability = candidate.stability || incompleteDoclet.stability
|
||||
stability = candidate.stability || incompleteDoclet.stability;
|
||||
if (stability) {
|
||||
incompleteDoclet.stability = stability;
|
||||
for (key in candidate) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
var util = require('util');
|
||||
exports.defineTags = function(dictionary) {
|
||||
|
||||
var classTag = dictionary.lookUp('class');
|
||||
|
||||
@@ -44,7 +44,7 @@ exports.handlers = {
|
||||
if (!cls.fires) {
|
||||
cls.fires = [];
|
||||
}
|
||||
var event = 'ol.ObjectEvent#event:change:' + name.toLowerCase();
|
||||
event = 'ol.ObjectEvent#event:change:' + name.toLowerCase();
|
||||
if (cls.fires.indexOf(event) == -1) {
|
||||
cls.fires.push(event);
|
||||
}
|
||||
|
||||
@@ -79,14 +79,6 @@ function addSignatureTypes(f) {
|
||||
f.signature = (f.signature || '') + '<span class="type-signature">'+(types.length? ' :'+types.join('|') : '')+' </span>';
|
||||
}
|
||||
|
||||
function addAttribs(f) {
|
||||
var attribs = helper.getAttribs(f);
|
||||
|
||||
if (attribs.length) {
|
||||
f.attribs = '<span class="type-signature ' + (attribs[0] === 'static' ? 'static' : '') + '">' + htmlsafe(attribs.length ? attribs.join(',') : '') + ' </span>';
|
||||
}
|
||||
}
|
||||
|
||||
function shortenPaths(files, commonPrefix) {
|
||||
// always use forward slashes
|
||||
var regexp = new RegExp('\\\\', 'g');
|
||||
@@ -198,11 +190,19 @@ function attachModuleSymbols(doclets, modules) {
|
||||
*/
|
||||
function buildNav(members) {
|
||||
var nav = [];
|
||||
|
||||
if (members.namespaces.length) {
|
||||
_.each(members.namespaces, function (v) {
|
||||
// exclude 'olx' from sidebar
|
||||
if (v.longname.indexOf('olx') !== 0) {
|
||||
// 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,
|
||||
@@ -225,13 +225,7 @@ function buildNav(members) {
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (members.classes.length) {
|
||||
_.each(members.classes, function (v) {
|
||||
// ignore interfaces
|
||||
if (v.interface !== true) {
|
||||
if (v.kind == 'class') {
|
||||
nav.push({
|
||||
type: 'class',
|
||||
longname: v.longname,
|
||||
@@ -255,9 +249,8 @@ function buildNav(members) {
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return nav;
|
||||
}
|
||||
|
||||
@@ -404,7 +397,6 @@ exports.publish = function(taffyData, opts, tutorials) {
|
||||
if ( needsSignature(doclet) ) {
|
||||
addSignatureParams(doclet);
|
||||
addSignatureReturns(doclet);
|
||||
addAttribs(doclet);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -414,12 +406,10 @@ exports.publish = function(taffyData, opts, tutorials) {
|
||||
|
||||
if (doclet.kind === 'member') {
|
||||
addSignatureTypes(doclet);
|
||||
addAttribs(doclet);
|
||||
}
|
||||
|
||||
if (doclet.kind === 'constant') {
|
||||
addSignatureTypes(doclet);
|
||||
addAttribs(doclet);
|
||||
doclet.kind = 'member';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,7 +15,6 @@ var self = this;
|
||||
<?js if (item.type === 'namespace' &&
|
||||
(item.members.length + item.typedefs.length + item.methods.length +
|
||||
item.events.length > 0)) { ?>
|
||||
<span class="static">static</span>
|
||||
<?js } ?>
|
||||
</span>
|
||||
<ul class="members itemMembers">
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
* This loader is used for the hosted examples. It is used in place of the
|
||||
* development loader (examples/loader.js).
|
||||
*
|
||||
* ol.js, ol-simple.js, ol-whitespace.js, and ol-deps.js are built
|
||||
* by OL3's build.py script. They are located in the ../build/ directory,
|
||||
* relatively to this script.
|
||||
* The ol.js, ol-debug.js, and ol-deps.js scripts are built by OL3's
|
||||
* build.py script. They are located in the ../build/ directory, relative to
|
||||
* this script.
|
||||
*
|
||||
* The script must be named loader.js.
|
||||
*
|
||||
@@ -54,20 +54,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
var oljs = 'ol.js', mode;
|
||||
if ('mode' in pageParams) {
|
||||
mode = pageParams.mode.toLowerCase();
|
||||
if (mode == 'debug') {
|
||||
mode = 'raw';
|
||||
}
|
||||
if (mode != 'advanced' && mode != 'raw') {
|
||||
oljs = 'ol-' + mode + '.js';
|
||||
}
|
||||
}
|
||||
var raw = pageParams.mode && pageParams.mode.toLowerCase() === 'raw';
|
||||
|
||||
var scriptId = encodeURIComponent(scriptParams.id);
|
||||
if (mode != 'raw') {
|
||||
document.write('<scr' + 'ipt type="text/javascript" src="../build/' + oljs + '"></scr' + 'ipt>');
|
||||
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>');
|
||||
|
||||
78
build.py
78
build.py
@@ -16,10 +16,9 @@ from pake import ifind, main, output, rule, target, variables, virtual, which
|
||||
if sys.platform == 'win32':
|
||||
|
||||
win = {
|
||||
'CLEANCSS': './node_modules/.bin/cleancss',
|
||||
'GIT': 'git.exe',
|
||||
'GJSLINT': 'gjslint.exe',
|
||||
'JAVA': 'java.exe',
|
||||
'JAR': 'jar.exe',
|
||||
'JSDOC': './node_modules/.bin/jsdoc',
|
||||
'JSHINT': './node_modules/.bin/jshint',
|
||||
'PYTHON': 'python.exe',
|
||||
@@ -28,24 +27,6 @@ if sys.platform == 'win32':
|
||||
|
||||
sys_dir = os.environ.get('SYSTEMDRIVE')
|
||||
program_files = os.environ.get('PROGRAMFILES')
|
||||
java_home = os.environ.get('JAVA_HOME')
|
||||
|
||||
if not java_home:
|
||||
# Following lines choose sensible defaults to guess JAVA_HOME in
|
||||
# 32/64bit Program Files folder opting for the most current version.
|
||||
search_term = os.path.join(sys_dir, os.sep, 'Program Files*', 'Java', 'jdk*')
|
||||
found_jdks = sorted(glob.glob(search_term), key=lambda x: x[-8:])
|
||||
if found_jdks:
|
||||
java_home = found_jdks[-1]
|
||||
|
||||
if java_home:
|
||||
if not which(win['JAVA']):
|
||||
win['JAVA'] = os.path.join(java_home, 'bin', 'java.exe')
|
||||
if not which(win['JAR']):
|
||||
win['JAR'] = os.path.join(java_home, 'bin', 'jar.exe')
|
||||
elif not which(win['JAVA']):
|
||||
win['JAVA'] = os.path.join(program_files,
|
||||
'Java', 'jre7', 'bin', 'java.exe')
|
||||
|
||||
if not which(win['GIT']):
|
||||
win['GIT'] = os.path.join(program_files, 'Git', 'cmd', 'git.exe')
|
||||
@@ -70,11 +51,10 @@ if sys.platform == 'win32':
|
||||
setattr(variables, program, path)
|
||||
|
||||
else:
|
||||
variables.CLEANCSS = './node_modules/.bin/cleancss'
|
||||
variables.GIT = 'git'
|
||||
variables.GJSLINT = 'gjslint'
|
||||
variables.JSHINT = './node_modules/.bin/jshint'
|
||||
variables.JAVA = 'java'
|
||||
variables.JAR = 'jar'
|
||||
variables.JSDOC = './node_modules/.bin/jsdoc'
|
||||
variables.PYTHON = 'python'
|
||||
variables.PHANTOMJS = './node_modules/.bin/phantomjs'
|
||||
@@ -82,12 +62,10 @@ else:
|
||||
variables.BRANCH = output(
|
||||
'%(GIT)s', 'rev-parse', '--abbrev-ref', 'HEAD').strip()
|
||||
|
||||
EXECUTABLES = [variables.GIT, variables.GJSLINT, variables.JAVA, variables.JAR,
|
||||
EXECUTABLES = [variables.CLEANCSS, variables.GIT, variables.GJSLINT,
|
||||
variables.JSDOC, variables.JSHINT, variables.PYTHON,
|
||||
variables.PHANTOMJS]
|
||||
|
||||
EXPORTS = 'build/exports.js'
|
||||
|
||||
EXAMPLES = [path
|
||||
for path in ifind('examples')
|
||||
if path.endswith('.html')
|
||||
@@ -145,23 +123,22 @@ def report_sizes(t):
|
||||
virtual('default', 'build')
|
||||
|
||||
|
||||
virtual('ci', 'lint', 'jshint', 'build', 'build-all',
|
||||
'test', 'build/examples/all.combined.js', 'check-examples', 'apidoc')
|
||||
virtual('ci', 'lint', 'jshint', 'build', 'test',
|
||||
'build/examples/all.combined.js', 'check-examples', 'apidoc')
|
||||
|
||||
|
||||
virtual('build', 'build/ol.css', 'build/ol.js',
|
||||
'build/ol-simple.js', 'build/ol-whitespace.js')
|
||||
virtual('build', 'build/ol.css', 'build/ol.js', 'build/ol-debug.js')
|
||||
|
||||
|
||||
virtual('check', 'lint', 'jshint', 'build/ol-all.js', 'test')
|
||||
virtual('check', 'lint', 'jshint', 'test')
|
||||
|
||||
|
||||
virtual('todo', 'fixme')
|
||||
|
||||
|
||||
@target('build/ol.css', 'build/ol.js')
|
||||
@target('build/ol.css', 'css/ol.css')
|
||||
def build_ol_css(t):
|
||||
t.touch()
|
||||
t.output('%(CLEANCSS)s', 'css/ol.css')
|
||||
|
||||
|
||||
@target('build/ol.js', SRC, SHADER_SRC, 'buildcfg/ol.json')
|
||||
@@ -170,31 +147,12 @@ def build_ol_new_js(t):
|
||||
report_sizes(t)
|
||||
|
||||
|
||||
@target('build/ol-simple.js', SRC, SHADER_SRC, 'buildcfg/ol-simple.json')
|
||||
def build_ol_simple_js(t):
|
||||
t.run('node', 'tasks/build.js', 'buildcfg/ol-simple.json', 'build/ol-simple.js')
|
||||
@target('build/ol-debug.js', SRC, SHADER_SRC, 'buildcfg/ol-debug.json')
|
||||
def build_ol_debug_js(t):
|
||||
t.run('node', 'tasks/build.js', 'buildcfg/ol-debug.json', 'build/ol-debug.js')
|
||||
report_sizes(t)
|
||||
|
||||
|
||||
@target('build/ol-whitespace.js', SRC, SHADER_SRC, 'buildcfg/ol-whitespace.json')
|
||||
def build_ol_whitespace_js(t):
|
||||
t.run('node', 'tasks/build.js', 'buildcfg/ol-whitespace.json', 'build/ol-whitespace.js')
|
||||
report_sizes(t)
|
||||
|
||||
|
||||
virtual('build-all', 'build/ol-all.js')
|
||||
|
||||
|
||||
@target('build/ol-all.js', SRC, SHADER_SRC, 'buildcfg/ol-all.json')
|
||||
def build_ol_all_js(t):
|
||||
t.run('node', 'tasks/build.js', 'buildcfg/ol-all.json', 'build/ol-all.js')
|
||||
|
||||
|
||||
@target(EXPORTS, SRC)
|
||||
def build_exports_js(t):
|
||||
t.run('node', 'tasks/generate-exports.js', EXPORTS)
|
||||
|
||||
|
||||
for glsl_src in GLSL_SRC:
|
||||
def shader_src_helper(glsl_src):
|
||||
@target(glsl_src.replace('.glsl', 'shader.js'), glsl_src,
|
||||
@@ -353,7 +311,7 @@ virtual('lint', 'build/lint-timestamp', 'build/check-requires-timestamp',
|
||||
'build/check-whitespace-timestamp')
|
||||
|
||||
|
||||
@target('build/lint-timestamp', SRC, EXPORTS, EXAMPLES_SRC, SPEC, precious=True)
|
||||
@target('build/lint-timestamp', SRC, EXAMPLES_SRC, SPEC, precious=True)
|
||||
def build_lint_src_timestamp(t):
|
||||
t.run('%(GJSLINT)s',
|
||||
'--jslint_error=all',
|
||||
@@ -365,7 +323,7 @@ def build_lint_src_timestamp(t):
|
||||
|
||||
virtual('jshint', 'build/jshint-timestamp')
|
||||
|
||||
@target('build/jshint-timestamp', SRC, EXPORTS, EXAMPLES_SRC, SPEC,
|
||||
@target('build/jshint-timestamp', SRC, EXAMPLES_SRC, SPEC,
|
||||
precious=True)
|
||||
def build_jshint_timestamp(t):
|
||||
t.run(variables.JSHINT, '--verbose', t.newer(t.dependencies))
|
||||
@@ -535,7 +493,7 @@ def build_check_requires_timestamp(t):
|
||||
t.touch()
|
||||
|
||||
|
||||
@target('build/check-whitespace-timestamp', SRC, EXPORTS, EXAMPLES_SRC,
|
||||
@target('build/check-whitespace-timestamp', SRC, EXAMPLES_SRC,
|
||||
SPEC, JSDOC_SRC, precious=True)
|
||||
def build_check_whitespace_timestamp(t):
|
||||
CR_RE = re.compile(r'\r')
|
||||
@@ -572,8 +530,7 @@ virtual('apidoc', 'build/jsdoc-%(BRANCH)s-timestamp' % vars(variables))
|
||||
|
||||
|
||||
@target('build/jsdoc-%(BRANCH)s-timestamp' % vars(variables), 'host-resources',
|
||||
EXPORTS, SRC, SHADER_SRC,
|
||||
ifind('apidoc/template'))
|
||||
SRC, SHADER_SRC, ifind('apidoc/template'))
|
||||
def jsdoc_BRANCH_timestamp(t):
|
||||
t.run('%(JSDOC)s', 'apidoc/index.md', '-c', 'apidoc/conf.json',
|
||||
'-d', 'build/hosted/%(BRANCH)s/apidoc')
|
||||
@@ -637,8 +594,7 @@ def host_examples(t):
|
||||
split_example_file(example, examples_dir % vars(variables))
|
||||
t.cp_r('examples/data', examples_dir + '/data')
|
||||
t.cp('bin/loader_hosted_examples.js', examples_dir + '/loader.js')
|
||||
t.cp('build/ol.js', 'build/ol-simple.js', 'build/ol-whitespace.js',
|
||||
build_dir)
|
||||
t.cp('build/ol.js', 'build/ol-debug.js', build_dir)
|
||||
t.cp('build/ol.css', css_dir)
|
||||
t.cp('examples/index.html', 'examples/example-list.js',
|
||||
'examples/example-list.xml', 'examples/Jugl.js',
|
||||
|
||||
@@ -48,7 +48,6 @@ exports.publish = function(data, opts) {
|
||||
name: doc.longname,
|
||||
kind: doc.kind,
|
||||
description: doc.classdesc || doc.description,
|
||||
extends: doc.augments,
|
||||
path: path.join(doc.meta.path, doc.meta.filename)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"src": ["src/**/*.js"],
|
||||
"compile": {
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/geojson.js",
|
||||
"externs/oli.js",
|
||||
"externs/olx.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js",
|
||||
"externs/vbarray.js"
|
||||
],
|
||||
"define": [
|
||||
"goog.dom.ASSUME_STANDARDS_MODE=true",
|
||||
"goog.DEBUG=false"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"accessControls",
|
||||
"ambiguousFunctionDecl",
|
||||
"checkEventfulObjectDisposal",
|
||||
"checkRegExp",
|
||||
"checkStructDictInheritance",
|
||||
"checkTypes",
|
||||
"checkVars",
|
||||
"const",
|
||||
"constantProperty",
|
||||
"deprecated",
|
||||
"duplicateMessage",
|
||||
"es3",
|
||||
"externsValidation",
|
||||
"fileoverviewTags",
|
||||
"globalThis",
|
||||
"internetExplorerChecks",
|
||||
"invalidCasts",
|
||||
"misplacedTypeAnnotation",
|
||||
"missingGetCssName",
|
||||
"missingProperties",
|
||||
"missingProvide",
|
||||
"missingRequire",
|
||||
"missingReturn",
|
||||
"newCheckTypes",
|
||||
"nonStandardJsDocs",
|
||||
"suspiciousCode",
|
||||
"strictModuleDepCheck",
|
||||
"typeInvalidation",
|
||||
"undefinedNames",
|
||||
"undefinedVars",
|
||||
"unknownDefines",
|
||||
"uselessCode",
|
||||
"visibility"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"es5Strict"
|
||||
],
|
||||
"compilation_level": "ADVANCED",
|
||||
"output_wrapper": "// OpenLayers 3. See http://ol3.js.org/\n(function(){%output%})();",
|
||||
"use_types_for_optimization": true
|
||||
}
|
||||
}
|
||||
3
buildcfg/ol-debug.json
Normal file
3
buildcfg/ol-debug.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"exports": ["*"]
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"src": ["src/**/*.js"],
|
||||
"compile": {
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/geojson.js",
|
||||
"externs/oli.js",
|
||||
"externs/olx.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js",
|
||||
"externs/vbarray.js"
|
||||
],
|
||||
"define": [
|
||||
"goog.dom.ASSUME_STANDARDS_MODE=true",
|
||||
"goog.DEBUG=false"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"accessControls",
|
||||
"ambiguousFunctionDecl",
|
||||
"checkEventfulObjectDisposal",
|
||||
"checkRegExp",
|
||||
"checkStructDictInheritance",
|
||||
"checkTypes",
|
||||
"checkVars",
|
||||
"const",
|
||||
"constantProperty",
|
||||
"deprecated",
|
||||
"duplicateMessage",
|
||||
"es3",
|
||||
"externsValidation",
|
||||
"fileoverviewTags",
|
||||
"globalThis",
|
||||
"internetExplorerChecks",
|
||||
"invalidCasts",
|
||||
"misplacedTypeAnnotation",
|
||||
"missingGetCssName",
|
||||
"missingProperties",
|
||||
"missingProvide",
|
||||
"missingRequire",
|
||||
"missingReturn",
|
||||
"newCheckTypes",
|
||||
"nonStandardJsDocs",
|
||||
"suspiciousCode",
|
||||
"strictModuleDepCheck",
|
||||
"typeInvalidation",
|
||||
"undefinedNames",
|
||||
"undefinedVars",
|
||||
"unknownDefines",
|
||||
"uselessCode",
|
||||
"visibility"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"es5Strict"
|
||||
],
|
||||
"compilation_level": "SIMPLE",
|
||||
"output_wrapper": "%output%",
|
||||
"use_types_for_optimization": false,
|
||||
"manage_closure_dependencies": true
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"src": ["src/**/*.js"],
|
||||
"compile": {
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
"externs/closure-compiler.js",
|
||||
"externs/geojson.js",
|
||||
"externs/oli.js",
|
||||
"externs/olx.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js",
|
||||
"externs/topojson.js",
|
||||
"externs/vbarray.js"
|
||||
],
|
||||
"define": [
|
||||
"goog.dom.ASSUME_STANDARDS_MODE=true",
|
||||
"goog.DEBUG=false"
|
||||
],
|
||||
"jscomp_error": [
|
||||
"accessControls",
|
||||
"ambiguousFunctionDecl",
|
||||
"checkEventfulObjectDisposal",
|
||||
"checkRegExp",
|
||||
"checkStructDictInheritance",
|
||||
"checkTypes",
|
||||
"checkVars",
|
||||
"const",
|
||||
"constantProperty",
|
||||
"deprecated",
|
||||
"duplicateMessage",
|
||||
"es3",
|
||||
"externsValidation",
|
||||
"fileoverviewTags",
|
||||
"globalThis",
|
||||
"internetExplorerChecks",
|
||||
"invalidCasts",
|
||||
"misplacedTypeAnnotation",
|
||||
"missingGetCssName",
|
||||
"missingProperties",
|
||||
"missingProvide",
|
||||
"missingRequire",
|
||||
"missingReturn",
|
||||
"newCheckTypes",
|
||||
"nonStandardJsDocs",
|
||||
"suspiciousCode",
|
||||
"strictModuleDepCheck",
|
||||
"typeInvalidation",
|
||||
"undefinedNames",
|
||||
"undefinedVars",
|
||||
"unknownDefines",
|
||||
"uselessCode",
|
||||
"visibility"
|
||||
],
|
||||
"extra_annotation_name": [
|
||||
"api", "observable"
|
||||
],
|
||||
"jscomp_off": [
|
||||
"es5Strict"
|
||||
],
|
||||
"compilation_level": "WHITESPACE_ONLY",
|
||||
"output_wrapper": "var CLOSURE_DEPS = false;\n%output%",
|
||||
"use_types_for_optimization": false,
|
||||
"manage_closure_dependencies": true
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"exports": ["*"],
|
||||
"src": ["src/**/*.js"],
|
||||
"compile": {
|
||||
"externs": [
|
||||
"externs/bingmaps.js",
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
# Build configs
|
||||
|
||||
This directory includes configuration files (json) for the tasks/build.js
|
||||
build script.
|
||||
|
||||
Notes:
|
||||
|
||||
`use_types_for_optimization` is set to `false` for the SIMPLE and WHITESPACE
|
||||
builds. If it was set to `true` we would get function names like
|
||||
`ol_control_Control_prototype$setMap` in the compiled code when using the
|
||||
SIMPLE compilation. `use_types_for_optimization` is only appropriate for
|
||||
ADVANCED compilation. To be sure we also don't set it for WHITESPACE.
|
||||
This directory includes configuration files (json) for the build scripts in tasks/.
|
||||
|
||||
10
css/ol.css
10
css/ol.css
@@ -219,6 +219,9 @@ button.ol-full-screen-true:after {
|
||||
.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);
|
||||
}
|
||||
@@ -229,10 +232,17 @@ button.ol-full-screen-true:after {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ It is also designed such that major new features, such as displaying 3D maps, or
|
||||
OL3 is based on Google's Closure Tools. It makes heavy use of parts of the [__Closure Library__](https://developers.google.com/closure/library/). Using this to handle basics like DOM or event handling means the developers can concentrate on mapping functionality, and be sure that the underlying software is well-tested and cross-browser. Closure Library is specially designed to be optimized by the [__Closure Compiler__](https://developers.google.com/closure/compiler/). The 'advanced' optimizations that this provides offers a level of compression that far exceeds anything else available. OL3 has been designed to make full use of this.
|
||||
|
||||
## Public API
|
||||
Using the advanced optimizations of the Closure Compiler means that properties and methods are renamed – `longMeaningfulName` might become `xB` – and so are effectively unusable in applications using the library. To be usable, they have to be explicitly `exported`. This means the exported names, those not renamed, effectively become the public API of the library. These __exportable__ properties and methods are marked in the source, and documented in the [API docs](../apidoc). This is the officially supported API of the library. A build containing all these exportable names is known as a __full build__. A hosted version of this is available, which can be used by any application.
|
||||
Using the advanced optimizations of the Closure Compiler means that properties and methods are renamed – `longMeaningfulName` might become `xB` – and so are effectively unusable in applications using the library. To be usable, they have to be explicitly `exported`. This means the exported names, those not renamed, effectively become the public API of the library. These __exportable__ properties and methods are marked in the source, and documented in the [API docs](../../apidoc). This is the officially supported API of the library. A build containing all these exportable names is known as a __full build__. A hosted version of this is available, which can be used by any application.
|
||||
|
||||
Although Closure library functions are widely used within OL3, none of them are exported. You will see references to them (they are all in the `goog` namespace) in the API docs, but these are for information only. You can use the Closure library in your own applications if you like, but this is not required.
|
||||
|
||||
@@ -35,10 +35,10 @@ OL3 uses a similar object hierarchy to the Closure library. There is a top-level
|
||||
* simple objects containing static properties and methods, such as `ol.animation`; these also have a lower-case initial
|
||||
* types, which have an upper-case initial. These are mainly 'classes', which here means a constructor function with prototypal inheritance, such as `ol.Map` or `ol.layer.Vector` (the Vector class within the layer namespace). There are however other, simpler, types, such as `ol.Extent`, which is an array.
|
||||
|
||||
In the API docs, the index on the left lists the namespaces and simple objects first, followed by the classes.
|
||||
|
||||
Class namespaces, such as `ol.layer` have a base class type with the same name, such as `ol.layer.Layer`. These are mainly abstract classes, from which the other subclasses inherit.
|
||||
|
||||
Source files are similarly organised, with a directory for each class namespace. Names are however all lower-case, and the subclasses repeat the superclass type in their name, for example, `ol/layer/vectorlayer.js`.
|
||||
|
||||
The naming structure means that there are sometimes 2 objects with the same name but different initial, such as `ol.feature`, a simple object with static functions to be used with features, and `ol.Feature`, a class used to instantiate new features. These two objects are however stored in the same file, in this case, `ol/feature.js`
|
||||
|
||||
OL3 follows the convention that the names of private properties and methods, that is, those that are not part of the API, end in an underscore. In general, instance properties are private and accessed using accessors.
|
||||
176
examples/data/geojson/countries-110m.geojson
Normal file
176
examples/data/geojson/countries-110m.geojson
Normal file
File diff suppressed because one or more lines are too long
@@ -31,7 +31,7 @@ if ('download' in exportPNGElement) {
|
||||
var canvas = event.context.canvas;
|
||||
exportPNGElement.href = canvas.toDataURL('image/png');
|
||||
});
|
||||
map.render();
|
||||
map.renderSync();
|
||||
}, false);
|
||||
} else {
|
||||
var info = document.getElementById('no-download');
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
<div id="no-download" class="alert alert-error" style="display: none">
|
||||
The "Export GPX" functionality requires a browser that supports the
|
||||
<a href="http://caniuse.com/#feat=download">link download</a> attribute.
|
||||
</div>
|
||||
<a id="export-gpx" class="btn" download="map.gpx"><i class="icon-download"></i>Export GPX</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.format.GPX');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.BingMaps');
|
||||
goog.require('ol.source.GPX');
|
||||
goog.require('ol.style.Circle');
|
||||
@@ -9,6 +11,8 @@ goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
var projection = ol.proj.get('EPSG:3857');
|
||||
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.BingMaps({
|
||||
imagerySet: 'Aerial',
|
||||
@@ -45,7 +49,7 @@ var style = {
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.GPX({
|
||||
projection: 'EPSG:3857',
|
||||
projection: projection,
|
||||
url: 'data/gpx/fells_loop.gpx'
|
||||
}),
|
||||
style: function(feature, resolution) {
|
||||
@@ -89,3 +93,30 @@ $(map.getViewport()).on('mousemove', function(evt) {
|
||||
map.on('click', function(evt) {
|
||||
displayFeatureInfo(evt.pixel);
|
||||
});
|
||||
|
||||
var exportGPXElement = document.getElementById('export-gpx');
|
||||
if ('download' in exportGPXElement) {
|
||||
var vectorSource = /** @type {ol.source.Vector} */ (vector.getSource());
|
||||
exportGPXElement.addEventListener('click', function(e) {
|
||||
if (!exportGPXElement.href) {
|
||||
var features = [];
|
||||
vectorSource.forEachFeature(function(feature) {
|
||||
var clone = feature.clone();
|
||||
clone.getGeometry().transform(projection, 'EPSG:4326');
|
||||
features.push(clone);
|
||||
});
|
||||
var node = new ol.format.GPX().writeFeatures(features);
|
||||
var string = new XMLSerializer().serializeToString(
|
||||
/** @type {Node} */ (node));
|
||||
var base64 = exampleNS.strToBase64(string);
|
||||
exportGPXElement.href =
|
||||
'data:gpx+xml;base64,' + base64;
|
||||
}
|
||||
}, false);
|
||||
} else {
|
||||
var info = document.getElementById('no-download');
|
||||
/**
|
||||
* display error message
|
||||
*/
|
||||
info.style.display = '';
|
||||
}
|
||||
|
||||
51
examples/graticule.html
Normal file
51
examples/graticule.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Graticule example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span12">
|
||||
<h4 id="title">Graticule example</h4>
|
||||
<p id="shortdesc">This example shows how to add a graticule overlay to a map.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="graticule.js" target="_blank">graticule.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">graticule</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=graticule" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
25
examples/graticule.js
Normal file
25
examples/graticule.js
Normal file
@@ -0,0 +1,25 @@
|
||||
goog.require('ol.Graticule');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
})
|
||||
],
|
||||
renderer: 'canvas',
|
||||
target: 'map',
|
||||
view: new ol.View({
|
||||
center: ol.proj.transform([4.8, 47.75], 'EPSG:4326', 'EPSG:3857'),
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
// Create the graticule component
|
||||
var graticule = new ol.Graticule();
|
||||
graticule.setMap(map);
|
||||
@@ -15,6 +15,7 @@ var bounds = [
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.Image({
|
||||
extent: bounds,
|
||||
source: new ol.source.MapGuide({
|
||||
projection: 'EPSG:4326',
|
||||
url: agentUrl,
|
||||
@@ -24,8 +25,7 @@ var map = new ol.Map({
|
||||
MAPDEFINITION: mdf,
|
||||
FORMAT: 'PNG'
|
||||
},
|
||||
ratio: 2,
|
||||
extent: bounds
|
||||
ratio: 2
|
||||
})
|
||||
})
|
||||
],
|
||||
|
||||
52
examples/sphere-mollweide.html
Normal file
52
examples/sphere-mollweide.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Sphere Mollweide example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span12">
|
||||
<h4 id="title">Sphere Mollweide example</h4>
|
||||
<p id="shortdesc">Example of a Sphere Mollweide map with a Graticule component.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="sphere-mollweide.js" target="_blank">sphere-mollweide.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">graticule, Mollweide, projection, proj4js</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.2.1/proj4.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=sphere-mollweide" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
42
examples/sphere-mollweide.js
Normal file
42
examples/sphere-mollweide.js
Normal file
@@ -0,0 +1,42 @@
|
||||
goog.require('ol.Graticule');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.GeoJSON');
|
||||
|
||||
|
||||
proj4.defs('ESRI:53009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +a=6371000 ' +
|
||||
'+b=6371000 +units=m +no_defs');
|
||||
|
||||
// Configure the Sphere Mollweide projection object with an extent,
|
||||
// and a world extent. These are required for the Graticule.
|
||||
var sphereMollweideProjection = ol.proj.get('ESRI:53009');
|
||||
sphereMollweideProjection.setExtent([
|
||||
-9009954.605703328, -9009954.605703328,
|
||||
9009954.605703328, 9009954.605703328]);
|
||||
sphereMollweideProjection.setWorldExtent([-179, -90, 179, 90]);
|
||||
|
||||
var map = new ol.Map({
|
||||
keyboardEventTarget: document,
|
||||
layers: [
|
||||
new ol.layer.Vector({
|
||||
source: new ol.source.GeoJSON({
|
||||
projection: sphereMollweideProjection,
|
||||
url: 'data/geojson/countries-110m.geojson'
|
||||
})
|
||||
})
|
||||
],
|
||||
renderer: 'canvas',
|
||||
target: 'map',
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
projection: sphereMollweideProjection,
|
||||
resolutions: [65536, 32768, 16384, 8192, 4096, 2048],
|
||||
zoom: 0
|
||||
})
|
||||
});
|
||||
|
||||
var graticule = new ol.Graticule({
|
||||
map: map
|
||||
});
|
||||
@@ -44,6 +44,7 @@ ol.proj.addCoordinateTransforms('EPSG:4326', projection,
|
||||
var extent = [420000, 30000, 900000, 350000];
|
||||
var layers = [
|
||||
new ol.layer.Tile({
|
||||
extent: extent,
|
||||
source: new ol.source.TileWMS({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
@@ -57,11 +58,11 @@ var layers = [
|
||||
'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
|
||||
'FORMAT': 'image/jpeg'
|
||||
},
|
||||
extent: extent,
|
||||
serverType: 'mapserver'
|
||||
})
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
extent: extent,
|
||||
source: new ol.source.TileWMS({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
@@ -72,7 +73,6 @@ var layers = [
|
||||
'National parks / geo.admin.ch</a>'
|
||||
})],
|
||||
params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'},
|
||||
extent: extent,
|
||||
serverType: 'mapserver'
|
||||
})
|
||||
})
|
||||
|
||||
@@ -12,6 +12,10 @@ goog.require('ol.source.ImageWMS');
|
||||
// known to Proj4js if it is unknown to OpenLayers, and registers functions to
|
||||
// transform between all registered projections.
|
||||
// EPSG:21781 is known to Proj4js because its definition was loaded in the html.
|
||||
// Note that we are getting the projection object here to set the extent. If
|
||||
// you do not need this, you do not have to use ol.proj.get(); simply use the
|
||||
// string code in the view projection below and the transforms will be
|
||||
// registered transparently.
|
||||
var projection = ol.proj.get('EPSG:21781');
|
||||
// The extent is used to determine zoom level 0. Recommended values for a
|
||||
// projection's validity extent can be found at http://epsg.io/.
|
||||
@@ -20,6 +24,7 @@ projection.setExtent([485869.5728, 76443.1884, 837076.5648, 299941.7864]);
|
||||
var extent = [420000, 30000, 900000, 350000];
|
||||
var layers = [
|
||||
new ol.layer.Image({
|
||||
extent: extent,
|
||||
source: new ol.source.ImageWMS({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
@@ -33,11 +38,11 @@ var layers = [
|
||||
'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
|
||||
'FORMAT': 'image/jpeg'
|
||||
},
|
||||
serverType: /** @type {ol.source.wms.ServerType} */ ('mapserver'),
|
||||
extent: extent
|
||||
serverType: /** @type {ol.source.wms.ServerType} */ ('mapserver')
|
||||
})
|
||||
}),
|
||||
new ol.layer.Image({
|
||||
extent: extent,
|
||||
source: new ol.source.ImageWMS({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
@@ -48,8 +53,7 @@ var layers = [
|
||||
'National parks / geo.admin.ch</a>'
|
||||
})],
|
||||
params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'},
|
||||
serverType: /** @type {ol.source.wms.ServerType} */ ('mapserver'),
|
||||
extent: extent
|
||||
serverType: /** @type {ol.source.wms.ServerType} */ ('mapserver')
|
||||
})
|
||||
})
|
||||
];
|
||||
|
||||
@@ -11,11 +11,11 @@ var layers = [
|
||||
source: new ol.source.MapQuest({layer: 'sat'})
|
||||
}),
|
||||
new ol.layer.Image({
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
source: new ol.source.ImageWMS({
|
||||
url: 'http://demo.opengeo.org/geoserver/wms',
|
||||
params: {'LAYERS': 'topp:states'},
|
||||
serverType: 'geoserver',
|
||||
extent: [-13884991, 2870341, -7455066, 6338219]
|
||||
serverType: 'geoserver'
|
||||
})
|
||||
})
|
||||
];
|
||||
|
||||
@@ -42,8 +42,10 @@ var layers = [
|
||||
];
|
||||
|
||||
// A minimal projection object is configured with only the SRS code and the map
|
||||
// units. No client side coordinate transforms are possible with such a
|
||||
// projection object.
|
||||
// units. No client-side coordinate transforms are possible with such a
|
||||
// projection object. Requesting tiles only needs the code together with a
|
||||
// tile grid of Cartesian coordinates; it does not matter how those
|
||||
// coordinates relate to latitude or longitude.
|
||||
var projection = new ol.proj.Projection({
|
||||
code: 'EPSG:21781',
|
||||
units: 'm'
|
||||
|
||||
@@ -10,10 +10,10 @@ var layers = [
|
||||
source: new ol.source.MapQuest({layer: 'sat'})
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
|
||||
url: 'http://demo.opengeo.org/geoserver/wms',
|
||||
params: {'LAYERS': 'topp:states', 'TILED': true},
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
serverType: 'geoserver'
|
||||
}))
|
||||
})
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>WMTS HiDPI example</title>
|
||||
<style>
|
||||
.map {
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ var urls = [
|
||||
var hiDPI = ol.BrowserFeature.DEVICE_PIXEL_RATIO > 1;
|
||||
|
||||
var source = new ol.source.WMTS({
|
||||
extent: [977844.377599999, 5837774.6617, 1915609.8654, 6295560.8122],
|
||||
projection: 'EPSG:3857',
|
||||
layer: hiDPI ? 'bmaphidpi' : 'geolandbasemap',
|
||||
tilePixelRatio: hiDPI ? 2 : 1,
|
||||
@@ -64,6 +63,7 @@ var source = new ol.source.WMTS({
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
extent: [977844.377599999, 5837774.6617, 1915609.8654, 6295560.8122],
|
||||
source: source
|
||||
})
|
||||
],
|
||||
|
||||
@@ -35,6 +35,7 @@ var map = new ol.Map({
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
opacity: 0.7,
|
||||
extent: projectionExtent,
|
||||
source: new ol.source.WMTS({
|
||||
attributions: [attribution],
|
||||
url: 'http://services.arcgisonline.com/arcgis/rest/' +
|
||||
@@ -48,7 +49,6 @@ var map = new ol.Map({
|
||||
resolutions: resolutions,
|
||||
matrixIds: matrixIds
|
||||
}),
|
||||
extent: projectionExtent,
|
||||
style: 'default'
|
||||
})
|
||||
})
|
||||
|
||||
424
externs/olx.js
424
externs/olx.js
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -17,23 +17,24 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.10",
|
||||
"htmlparser2": "~3.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"closure-util": "0.19.0",
|
||||
"expect.js": "~0.3.1",
|
||||
"fs-extra": "~0.8.1",
|
||||
"graceful-fs": "~3.0.2",
|
||||
"jquery": "~2.1.1",
|
||||
"htmlparser2": "~3.7.1",
|
||||
"jsdoc": "~3.3.0-alpha9",
|
||||
"nomnom": "~1.6.2",
|
||||
"temp": "~0.7.0",
|
||||
"walk": "~2.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-css": "^2.2.7",
|
||||
"expect.js": "~0.3.1",
|
||||
"jquery": "~2.1.1",
|
||||
"jshint": "~2.5.1",
|
||||
"mocha": "~1.20.1",
|
||||
"mocha-phantomjs": "~3.5.0",
|
||||
"nomnom": "~1.6.2",
|
||||
"phantomjs": "~1.9.7-5",
|
||||
"proj4": "~2.2.1",
|
||||
"sinon": "~1.10.2",
|
||||
"temp": "~0.7.0",
|
||||
"walk": "~2.3.3"
|
||||
"sinon": "~1.10.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,15 @@ ol.CollectionProperty = {
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Adds methods to standard Array; changes (add/remove) to the Collection
|
||||
* trigger events. Because a Collection is itself an {@link ol.Object}, it
|
||||
* can be bound to any other Object or Collection such that a change in one
|
||||
* will automatically be reflected in the other.
|
||||
* An expanded version of standard JS Array, adding convenience methods for
|
||||
* manipulation. Add and remove changes to the Collection trigger a Collection
|
||||
* event. Note that this does not cover changes to the objects _within_ the
|
||||
* Collection; they trigger events on the appropriate object, not on the
|
||||
* Collection as a whole.
|
||||
*
|
||||
* Because a Collection is itself an {@link ol.Object}, it can be bound to any
|
||||
* other Object or Collection such that a change in one will automatically be
|
||||
* reflected in the other.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
|
||||
@@ -18,6 +18,7 @@ goog.require('ol');
|
||||
* red, green, and blue should be integers in the range 0..255 inclusive.
|
||||
* alpha should be a float in the range 0..1 inclusive.
|
||||
* @typedef {Array.<number>}
|
||||
* @api
|
||||
*/
|
||||
ol.Color;
|
||||
|
||||
|
||||
3
src/ol/color/color.jsdoc
Normal file
3
src/ol/color/color.jsdoc
Normal file
@@ -0,0 +1,3 @@
|
||||
/**
|
||||
* @namespace ol.color
|
||||
*/
|
||||
@@ -4,7 +4,7 @@ goog.provide('ol.control.Attribution');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.dom.classes');
|
||||
goog.require('goog.dom.classlist');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.object');
|
||||
@@ -96,7 +96,8 @@ ol.control.Attribution = function(opt_options) {
|
||||
*/
|
||||
this.labelSpan_ = label;
|
||||
var button = goog.dom.createDom(goog.dom.TagName.BUTTON, {
|
||||
'class': 'ol-has-tooltip'
|
||||
'class': 'ol-has-tooltip',
|
||||
'type': 'button'
|
||||
}, this.labelSpan_);
|
||||
goog.dom.appendChild(button, tip);
|
||||
|
||||
@@ -158,8 +159,7 @@ goog.inherits(ol.control.Attribution, ol.control.Control);
|
||||
* @param {?olx.FrameState} frameState Frame state.
|
||||
* @return {Array.<Object.<string, ol.Attribution>>} Attributions.
|
||||
*/
|
||||
ol.control.Attribution.prototype.getSourceAttributions =
|
||||
function(frameState) {
|
||||
ol.control.Attribution.prototype.getSourceAttributions = function(frameState) {
|
||||
var i, ii, j, jj, tileRanges, source, sourceAttribution,
|
||||
sourceAttributionKey, sourceAttributions, sourceKey;
|
||||
var layerStatesArray = frameState.layerStatesArray;
|
||||
@@ -273,6 +273,12 @@ ol.control.Attribution.prototype.updateElement_ = function(frameState) {
|
||||
goog.style.setElementShown(this.element, renderVisible);
|
||||
this.renderedVisible_ = renderVisible;
|
||||
}
|
||||
if (renderVisible &&
|
||||
goog.object.isEmpty(this.attributionElementRenderedVisible_)) {
|
||||
goog.dom.classlist.add(this.element, 'ol-logo-only');
|
||||
} else {
|
||||
goog.dom.classlist.remove(this.element, 'ol-logo-only');
|
||||
}
|
||||
|
||||
this.insertLogos_(frameState);
|
||||
|
||||
@@ -347,7 +353,7 @@ ol.control.Attribution.prototype.handlePointerUp_ = function(pointerEvent) {
|
||||
* @private
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleToggle_ = function() {
|
||||
goog.dom.classes.toggle(this.element, 'ol-collapsed');
|
||||
goog.dom.classlist.toggle(this.element, 'ol-collapsed');
|
||||
goog.dom.setTextContent(this.labelSpan_,
|
||||
(this.collapsed_) ? this.collapseLabel_ : this.label_);
|
||||
this.collapsed_ = !this.collapsed_;
|
||||
@@ -355,7 +361,7 @@ ol.control.Attribution.prototype.handleToggle_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True is the widget is collapsible.
|
||||
* @return {boolean} True if the widget is collapsible.
|
||||
* @api
|
||||
*/
|
||||
ol.control.Attribution.prototype.getCollapsible = function() {
|
||||
@@ -364,7 +370,7 @@ ol.control.Attribution.prototype.getCollapsible = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} collapsible True is the widget is collapsible.
|
||||
* @param {boolean} collapsible True if the widget is collapsible.
|
||||
* @api
|
||||
*/
|
||||
ol.control.Attribution.prototype.setCollapsible = function(collapsible) {
|
||||
@@ -372,7 +378,7 @@ ol.control.Attribution.prototype.setCollapsible = function(collapsible) {
|
||||
return;
|
||||
}
|
||||
this.collapsible_ = collapsible;
|
||||
goog.dom.classes.toggle(this.element, 'ol-uncollapsible');
|
||||
goog.dom.classlist.toggle(this.element, 'ol-uncollapsible');
|
||||
if (!collapsible && this.collapsed_) {
|
||||
this.handleToggle_();
|
||||
}
|
||||
@@ -380,7 +386,7 @@ ol.control.Attribution.prototype.setCollapsible = function(collapsible) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} collapsed True is the widget is collapsed.
|
||||
* @param {boolean} collapsed True if the widget is collapsed.
|
||||
* @api
|
||||
*/
|
||||
ol.control.Attribution.prototype.setCollapsed = function(collapsed) {
|
||||
@@ -392,7 +398,7 @@ ol.control.Attribution.prototype.setCollapsed = function(collapsed) {
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True is the widget is collapsed.
|
||||
* @return {boolean} True if the widget is collapsed.
|
||||
* @api
|
||||
*/
|
||||
ol.control.Attribution.prototype.getCollapsed = function() {
|
||||
|
||||
@@ -12,8 +12,9 @@ goog.require('ol.Object');
|
||||
* @classdesc
|
||||
* A control is a visible widget with a DOM element in a fixed position on the
|
||||
* screen. They can involve user input (buttons), or be informational only;
|
||||
* the position is determined using CSS. By default these are part of the map
|
||||
* container, but can use any outside DOM element.
|
||||
* the position is determined using CSS. By default these are placed in the
|
||||
* container with CSS class name `ol-overlaycontainer-stopevent`, but can use
|
||||
* any outside DOM element.
|
||||
*
|
||||
* This is the base class for controls. You can use it for simple custom
|
||||
* controls by creating the element with listeners, creating an instance:
|
||||
|
||||
@@ -7,7 +7,6 @@ goog.require('ol.control.Zoom');
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Set of controls included in maps by default. Unless configured otherwise,
|
||||
* this returns a collection containing an instance of each of the following
|
||||
* controls:
|
||||
|
||||
@@ -43,9 +43,12 @@ ol.control.ScaleLineUnits = {
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A control displaying rough x-axis distances.
|
||||
* By default it will show in the bottom left portion of the map, but this can
|
||||
* be changed by using the css selector `.ol-scale-line`.
|
||||
* A control displaying rough x-axis distances, calculated for the center of the
|
||||
* viewport.
|
||||
* No scale line will be shown when the x-axis distance cannot be calculated in
|
||||
* the view projection (e.g. at or beyond the poles in EPSG:4326).
|
||||
* By default the scale line will show in the bottom left portion of the map,
|
||||
* but this can be changed by using the css selector `.ol-scale-line`.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.control.Control}
|
||||
@@ -304,7 +307,11 @@ ol.control.ScaleLine.prototype.updateElement_ = function() {
|
||||
count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] *
|
||||
Math.pow(10, Math.floor(i / 3));
|
||||
width = Math.round(count / pointResolution);
|
||||
if (width >= this.minWidth_) {
|
||||
if (isNaN(width)) {
|
||||
goog.style.setElementShown(this.element_, false);
|
||||
this.renderedVisible_ = false;
|
||||
return;
|
||||
} else if (width >= this.minWidth_) {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
|
||||
@@ -36,9 +36,15 @@ ol.CoordinateArray;
|
||||
* Add `delta` to `coordinate`. `coordinate` is modified in place and returned
|
||||
* by the function.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* ol.coordinate.add(coord, [-2, 4]);
|
||||
* // coord is now [5.85, 51.983333]
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @param {ol.Coordinate} delta Delta.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
* @return {ol.Coordinate} The input coordinate adjusted by the given delta.
|
||||
* @api
|
||||
*/
|
||||
ol.coordinate.add = function(coordinate, delta) {
|
||||
@@ -88,6 +94,23 @@ ol.coordinate.closestOnSegment = function(coordinate, segment) {
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@link ol.CoordinateFormatType} function that can be used to format
|
||||
* a {ol.Coordinate} to a string.
|
||||
*
|
||||
* Example without specifying the fractional digits:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var stringifyFunc = ol.coordinate.createStringXY();
|
||||
* var out = stringifyFunc(coord);
|
||||
* // out is now '8, 48'
|
||||
*
|
||||
* Example with explicitly specifying 2 fractional digits:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var stringifyFunc = ol.coordinate.createStringXY(2);
|
||||
* var out = stringifyFunc(coord);
|
||||
* // out is now '7.85, 47.98'
|
||||
*
|
||||
* @param {number=} opt_fractionDigits The number of digits to include
|
||||
* after the decimal point. Default is `0`.
|
||||
* @return {ol.CoordinateFormatType} Coordinate format.
|
||||
@@ -122,6 +145,24 @@ ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres) {
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the given {@link ol.Coordinate} to a string using the given string
|
||||
* template. The strings `{x}` and `{y}` in the template will be replaced with
|
||||
* the first and second coordinate values respectively.
|
||||
*
|
||||
* Example without specifying the fractional digits:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var template = 'Coordinate is ({x}|{y}).';
|
||||
* var out = ol.coordinate.format(coord, template);
|
||||
* // out is now 'Coordinate is (8|48).'
|
||||
*
|
||||
* Example explicitly specifying the fractional digits:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var template = 'Coordinate is ({x}|{y}).';
|
||||
* var out = ol.coordinate.format(coord, template, 2);
|
||||
* // out is now 'Coordinate is (7.85|47.98).'
|
||||
*
|
||||
* @param {ol.Coordinate|undefined} coordinate Coordinate.
|
||||
* @param {string} template A template string with `{x}` and `{y}` placeholders
|
||||
* that will be replaced by first and second coordinate values.
|
||||
@@ -162,6 +203,13 @@ ol.coordinate.equals = function(coordinate1, coordinate2) {
|
||||
* Rotate `coordinate` by `angle`. `coordinate` is modified in place and
|
||||
* returned by the function.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var rotateRadians = Math.PI / 2; // 90 degrees
|
||||
* ol.coordinate.rotate(coord, rotateRadians);
|
||||
* // coord is now [-47.983333, 7.85]
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @param {number} angle Angle in radian.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
@@ -182,6 +230,13 @@ ol.coordinate.rotate = function(coordinate, angle) {
|
||||
* Scale `coordinate` by `scale`. `coordinate` is modified in place and returned
|
||||
* by the function.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var scale = 1.2;
|
||||
* ol.coordinate.scale(coord, scale);
|
||||
* // coord is now [9.42, 57.5799996]
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @param {number} scale Scale factor.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
@@ -234,6 +289,12 @@ ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) {
|
||||
|
||||
|
||||
/**
|
||||
* Example:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var out = ol.coordinate.toStringHDMS(coord);
|
||||
* // out is now '47° 59′ 0″ N 7° 51′ 0″ E'
|
||||
*
|
||||
* @param {ol.Coordinate|undefined} coordinate Coordinate.
|
||||
* @return {string} Hemisphere, degrees, minutes and seconds.
|
||||
* @api
|
||||
@@ -249,6 +310,18 @@ ol.coordinate.toStringHDMS = function(coordinate) {
|
||||
|
||||
|
||||
/**
|
||||
* Example without specifying fractional digits:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var out = ol.coordinate.toStringXY(coord);
|
||||
* // out is now '8, 48'
|
||||
*
|
||||
* Example explicitly specifying 1 fractional digit:
|
||||
*
|
||||
* var coord = [7.85, 47.983333];
|
||||
* var out = ol.coordinate.toStringXY(coord, 1);
|
||||
* // out is now '7.8, 48.0'
|
||||
*
|
||||
* @param {ol.Coordinate|undefined} coordinate Coordinate.
|
||||
* @param {number=} opt_fractionDigits The number of digits to include
|
||||
* after the decimal point. Default is `0`.
|
||||
@@ -262,6 +335,15 @@ ol.coordinate.toStringXY = function(coordinate, opt_fractionDigits) {
|
||||
|
||||
/**
|
||||
* Create an ol.Coordinate from an Array and take into account axis order.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* var northCoord = ol.coordinate.fromProjectedArray([1, 2], 'n');
|
||||
* // northCoord is now [2, 1]
|
||||
*
|
||||
* var eastCoord = ol.coordinate.fromProjectedArray([1, 2], 'e');
|
||||
* // eastCoord is now [1, 2]
|
||||
*
|
||||
* @param {Array} array The array with coordinates.
|
||||
* @param {string} axis the axis info.
|
||||
* @return {ol.Coordinate} The coordinate created.
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
goog.provide('ol.ellipsoid.BESSEL1841');
|
||||
|
||||
goog.require('ol.Ellipsoid');
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Ellipsoid}
|
||||
*/
|
||||
ol.ellipsoid.BESSEL1841 = new ol.Ellipsoid(6377397.155, 1 / 299.15281285);
|
||||
@@ -50,6 +50,7 @@ ol.events.condition.altShiftKeysOnly = function(mapBrowserEvent) {
|
||||
* Always true.
|
||||
* @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
|
||||
* @return {boolean} True.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
ol.events.condition.always = goog.functions.TRUE;
|
||||
@@ -79,6 +80,7 @@ ol.events.condition.mouseMove = function(mapBrowserEvent) {
|
||||
* Always false.
|
||||
* @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
|
||||
* @return {boolean} False.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
ol.events.condition.never = goog.functions.FALSE;
|
||||
|
||||
@@ -418,7 +418,11 @@ ol.extent.extendXY = function(extent, x, y) {
|
||||
* @return {number} Area.
|
||||
*/
|
||||
ol.extent.getArea = function(extent) {
|
||||
return ol.extent.getWidth(extent) * ol.extent.getHeight(extent);
|
||||
var area = 0;
|
||||
if (!ol.extent.isEmpty(extent)) {
|
||||
area = ol.extent.getWidth(extent) * ol.extent.getHeight(extent);
|
||||
}
|
||||
return area;
|
||||
};
|
||||
|
||||
|
||||
@@ -511,11 +515,44 @@ ol.extent.getHeight = function(extent) {
|
||||
* @return {number} Intersection area.
|
||||
*/
|
||||
ol.extent.getIntersectionArea = function(extent1, extent2) {
|
||||
var minX = Math.max(extent1[0], extent2[0]);
|
||||
var minY = Math.max(extent1[1], extent2[1]);
|
||||
var maxX = Math.min(extent1[2], extent2[2]);
|
||||
var maxY = Math.min(extent1[3], extent2[3]);
|
||||
return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
|
||||
var intersection = ol.extent.getIntersection(extent1, extent2);
|
||||
return ol.extent.getArea(intersection);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the intersection of two extents.
|
||||
* @param {ol.Extent} extent1 Extent 1.
|
||||
* @param {ol.Extent} extent2 Extent 2.
|
||||
* @param {ol.Extent=} opt_extent Optional extent to populate with intersection.
|
||||
* @return {ol.Extent} Intersecting extent.
|
||||
*/
|
||||
ol.extent.getIntersection = function(extent1, extent2, opt_extent) {
|
||||
var intersection = goog.isDef(opt_extent) ?
|
||||
opt_extent : ol.extent.createEmpty();
|
||||
if (ol.extent.intersects(extent1, extent2)) {
|
||||
if (extent1[0] > extent2[0]) {
|
||||
intersection[0] = extent1[0];
|
||||
} else {
|
||||
intersection[0] = extent2[0];
|
||||
}
|
||||
if (extent1[1] > extent2[1]) {
|
||||
intersection[1] = extent1[1];
|
||||
} else {
|
||||
intersection[1] = extent2[1];
|
||||
}
|
||||
if (extent1[2] < extent2[2]) {
|
||||
intersection[2] = extent1[2];
|
||||
} else {
|
||||
intersection[2] = extent2[2];
|
||||
}
|
||||
if (extent1[3] < extent2[3]) {
|
||||
intersection[3] = extent1[3];
|
||||
} else {
|
||||
intersection[3] = extent2[3];
|
||||
}
|
||||
}
|
||||
return intersection;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,18 +17,46 @@ goog.require('ol.style.Style');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A vector object for geographical features with a geometry and other
|
||||
* A vector object for geographic features with a geometry and other
|
||||
* attribute properties, similar to the features in vector file formats like
|
||||
* GeoJSON.
|
||||
*
|
||||
* Features can be styled individually or use the style of their vector layer.
|
||||
* Note that attribute properties are set as {@link ol.Object} properties on the
|
||||
* feature object, so they are observable, and have get/set accessors.
|
||||
* Note that attribute properties are set as {@link ol.Object} properties on
|
||||
* the feature object, so they are observable, and have get/set accessors.
|
||||
*
|
||||
* Typically, a feature has a single geometry property. You can set the
|
||||
* geometry using the `setGeometry` method and get it with `getGeometry`.
|
||||
* It is possible to store more than one geometry on a feature using attribute
|
||||
* properties. By default, the geometry used for rendering is identified by
|
||||
* the property name `geometry`. If you want to use another geometry property
|
||||
* for rendering, use the `setGeometryName` method to change the attribute
|
||||
* property associated with the geometry for the feature. For example:
|
||||
*
|
||||
* ```js
|
||||
* var feature = new ol.Feature({
|
||||
* geometry: new ol.geom.Polygon(polyCoords),
|
||||
* labelPoint: new ol.geom.Point(labelCoords),
|
||||
* name: 'My Polygon'
|
||||
* });
|
||||
*
|
||||
* // get the polygon geometry
|
||||
* var poly = feature.getGeometry();
|
||||
*
|
||||
* // Render the feature as a point using the coordinates from labelPoint
|
||||
* feature.setGeometryName('labelPoint');
|
||||
*
|
||||
* // get the point geometry
|
||||
* var point = feature.getGeometry();
|
||||
* ```
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
* @fires change Triggered when the geometry or style of the feature changes.
|
||||
* @param {ol.geom.Geometry|Object.<string, *>=} opt_geometryOrProperties
|
||||
* Geometry or properties.
|
||||
* You may pass a Geometry object directly, or an object literal
|
||||
* containing properties. If you pass an object literal, you may
|
||||
* include a Geometry associated with a `geometry` key.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature = function(opt_geometryOrProperties) {
|
||||
@@ -109,8 +137,12 @@ ol.Feature.prototype.clone = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.Geometry|undefined} Geometry.
|
||||
* @return {ol.geom.Geometry|undefined} Returns the Geometry associated
|
||||
* with this feature using the current geometry name property. By
|
||||
* default, this is `geometry` but it may be changed by calling
|
||||
* `setGeometryName`.
|
||||
* @api
|
||||
* @observable
|
||||
*/
|
||||
ol.Feature.prototype.getGeometry = function() {
|
||||
return /** @type {ol.geom.Geometry|undefined} */ (
|
||||
@@ -132,7 +164,9 @@ ol.Feature.prototype.getId = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Geometry property name.
|
||||
* @return {string} Get the property name associated with the geometry for
|
||||
* this feature. By default, this is `geometry` but it may be changed by
|
||||
* calling `setGeometryName`.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.getGeometryName = function() {
|
||||
@@ -142,7 +176,9 @@ ol.Feature.prototype.getGeometryName = function() {
|
||||
|
||||
/**
|
||||
* @return {ol.style.Style|Array.<ol.style.Style>|
|
||||
* ol.feature.FeatureStyleFunction} User provided style.
|
||||
* ol.feature.FeatureStyleFunction} Return the style provided in the
|
||||
* constructor options or the last call to setStyle in the same format
|
||||
* that it was provided in.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.getStyle = function() {
|
||||
@@ -151,7 +187,8 @@ ol.Feature.prototype.getStyle = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.feature.FeatureStyleFunction|undefined} Style function.
|
||||
* @return {ol.feature.FeatureStyleFunction|undefined} Return a function
|
||||
* representing the current style of this feature.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.getStyleFunction = function() {
|
||||
@@ -185,8 +222,12 @@ ol.Feature.prototype.handleGeometryChanged_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.Geometry|undefined} geometry Geometry.
|
||||
* @param {ol.geom.Geometry|undefined} geometry Set the geometry for this
|
||||
* feature. This will update the property associated with the current
|
||||
* geometry property name. By default, this is `geometry` but it can be
|
||||
* changed by calling `setGeometryName`.
|
||||
* @api
|
||||
* @observable
|
||||
*/
|
||||
ol.Feature.prototype.setGeometry = function(geometry) {
|
||||
this.set(this.geometryName_, geometry);
|
||||
@@ -199,7 +240,7 @@ goog.exportProperty(
|
||||
|
||||
/**
|
||||
* @param {ol.style.Style|Array.<ol.style.Style>|
|
||||
* ol.feature.FeatureStyleFunction} style Feature style.
|
||||
* ol.feature.FeatureStyleFunction} style Set the style for this feature.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.setStyle = function(style) {
|
||||
@@ -210,7 +251,9 @@ ol.Feature.prototype.setStyle = function(style) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|string|undefined} id Id.
|
||||
* @param {number|string|undefined} id Set a unique id for this feature.
|
||||
* The id may be used to retrieve a feature from a vector source with the
|
||||
* {@link ol.source.Vector#getFeatureById} method.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.setId = function(id) {
|
||||
@@ -220,7 +263,8 @@ ol.Feature.prototype.setId = function(id) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} name Geometry property name.
|
||||
* @param {string} name Set the property name from which this feature's
|
||||
* geometry will be fetched when calling `getGeometry`.
|
||||
* @api
|
||||
*/
|
||||
ol.Feature.prototype.setGeometryName = function(name) {
|
||||
@@ -247,69 +291,6 @@ ol.Feature.prototype.setGeometryName = function(name) {
|
||||
ol.feature.FeatureStyleFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Default style function for features.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {Array.<ol.style.Style>} Style.
|
||||
* @this {ol.Feature}
|
||||
*/
|
||||
ol.feature.defaultFeatureStyleFunction = function(resolution) {
|
||||
var fill = new ol.style.Fill({
|
||||
color: 'rgba(255,255,255,0.4)'
|
||||
});
|
||||
var stroke = new ol.style.Stroke({
|
||||
color: '#3399CC',
|
||||
width: 1.25
|
||||
});
|
||||
var styles = [
|
||||
new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: fill,
|
||||
stroke: stroke,
|
||||
radius: 5
|
||||
}),
|
||||
fill: fill,
|
||||
stroke: stroke
|
||||
})
|
||||
];
|
||||
|
||||
// now that we've run it the first time,
|
||||
// replace the function with a constant version
|
||||
ol.feature.defaultFeatureStyleFunction =
|
||||
/** @type {function(this:ol.Feature):Array.<ol.style.Style>} */(
|
||||
function(resolution) {
|
||||
return styles;
|
||||
});
|
||||
|
||||
return styles;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A function that takes an {@link ol.Feature} and a `{number}` representing
|
||||
* the view's resolution. The function should return an array of
|
||||
* {@link ol.style.Style}. This way e.g. a vector layer can be styled.
|
||||
*
|
||||
* @typedef {function(ol.Feature, number): Array.<ol.style.Style>}
|
||||
* @api
|
||||
*/
|
||||
ol.feature.StyleFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {Array.<ol.style.Style>} Style.
|
||||
*/
|
||||
ol.feature.defaultStyleFunction = function(feature, resolution) {
|
||||
var featureStyleFunction = feature.getStyleFunction();
|
||||
if (!goog.isDef(featureStyleFunction)) {
|
||||
featureStyleFunction = ol.feature.defaultFeatureStyleFunction;
|
||||
}
|
||||
return featureStyleFunction.call(feature, resolution);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert the provided object into a feature style function. Functions passed
|
||||
* through unchanged. Arrays of ol.style.Style or single style objects wrapped
|
||||
@@ -344,39 +325,6 @@ ol.feature.createFeatureStyleFunction = function(obj) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert the provided object into a style function. Functions passed through
|
||||
* unchanged. Arrays of ol.style.Style or single style objects wrapped in a
|
||||
* new style function.
|
||||
* @param {ol.feature.StyleFunction|Array.<ol.style.Style>|ol.style.Style} obj
|
||||
* A style function, a single style, or an array of styles.
|
||||
* @return {ol.feature.StyleFunction} A style function.
|
||||
*/
|
||||
ol.feature.createStyleFunction = function(obj) {
|
||||
/**
|
||||
* @type {ol.feature.StyleFunction}
|
||||
*/
|
||||
var styleFunction;
|
||||
|
||||
if (goog.isFunction(obj)) {
|
||||
styleFunction = /** @type {ol.feature.StyleFunction} */ (obj);
|
||||
} else {
|
||||
/**
|
||||
* @type {Array.<ol.style.Style>}
|
||||
*/
|
||||
var styles;
|
||||
if (goog.isArray(obj)) {
|
||||
styles = obj;
|
||||
} else {
|
||||
goog.asserts.assertInstanceof(obj, ol.style.Style);
|
||||
styles = [obj];
|
||||
}
|
||||
styleFunction = goog.functions.constant(styles);
|
||||
}
|
||||
return styleFunction;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default styles for editing features.
|
||||
* @return {Object.<ol.geom.GeometryType, Array.<ol.style.Style>>} Styles
|
||||
|
||||
@@ -8,9 +8,9 @@ goog.require('goog.object');
|
||||
goog.require('ol.Collection');
|
||||
goog.require('ol.CollectionEventType');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.feature');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.renderer.vector');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
|
||||
@@ -63,19 +63,18 @@ ol.FeatureOverlay = function(opt_options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction}
|
||||
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
|
||||
*/
|
||||
this.style_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.feature.StyleFunction|undefined}
|
||||
* @type {ol.style.StyleFunction|undefined}
|
||||
*/
|
||||
this.styleFunction_ = undefined;
|
||||
|
||||
if (goog.isDef(options.style)) {
|
||||
this.setStyle(options.style);
|
||||
}
|
||||
this.setStyle(goog.isDef(options.style) ?
|
||||
options.style : ol.style.defaultStyleFunction);
|
||||
|
||||
if (goog.isDef(options.features)) {
|
||||
if (goog.isArray(options.features)) {
|
||||
@@ -169,7 +168,7 @@ ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) {
|
||||
}
|
||||
var styleFunction = this.styleFunction_;
|
||||
if (!goog.isDef(styleFunction)) {
|
||||
styleFunction = ol.feature.defaultStyleFunction;
|
||||
styleFunction = ol.style.defaultStyleFunction;
|
||||
}
|
||||
var replayGroup = /** @type {ol.render.IReplayGroup} */
|
||||
(event.replayGroup);
|
||||
@@ -270,13 +269,13 @@ ol.FeatureOverlay.prototype.setMap = function(map) {
|
||||
* Set the style for features. This can be a single style object, an array
|
||||
* of styles, or a function that takes a feature and resolution and returns
|
||||
* an array of styles.
|
||||
* @param {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction} style
|
||||
* @param {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction} style
|
||||
* Overlay style.
|
||||
* @api
|
||||
*/
|
||||
ol.FeatureOverlay.prototype.setStyle = function(style) {
|
||||
this.style_ = style;
|
||||
this.styleFunction_ = ol.feature.createStyleFunction(style);
|
||||
this.styleFunction_ = ol.style.createStyleFunction(style);
|
||||
this.render_();
|
||||
};
|
||||
|
||||
@@ -284,7 +283,7 @@ ol.FeatureOverlay.prototype.setStyle = function(style) {
|
||||
/**
|
||||
* Get the style for features. This returns whatever was passed to the `style`
|
||||
* option at construction or to the `setStyle` method.
|
||||
* @return {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction}
|
||||
* @return {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
|
||||
* Overlay style.
|
||||
* @api
|
||||
*/
|
||||
@@ -295,7 +294,7 @@ ol.FeatureOverlay.prototype.getStyle = function() {
|
||||
|
||||
/**
|
||||
* Get the style function.
|
||||
* @return {ol.feature.StyleFunction|undefined} Style function.
|
||||
* @return {ol.style.StyleFunction|undefined} Style function.
|
||||
* @api
|
||||
*/
|
||||
ol.FeatureOverlay.prototype.getStyleFunction = function() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
goog.provide('ol.format.GPX');
|
||||
goog.provide('ol.format.GPX.V1_1');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
@@ -794,17 +793,6 @@ ol.format.GPX.GPX_SERIALIZERS_ = ol.xml.makeStructureNS(
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.format.GPX}
|
||||
*/
|
||||
ol.format.GPX.V1_1 = function() {
|
||||
goog.base(this);
|
||||
};
|
||||
goog.inherits(ol.format.GPX.V1_1, ol.format.GPX);
|
||||
|
||||
|
||||
/**
|
||||
* Encode an array of features in the GPX format.
|
||||
*
|
||||
@@ -819,7 +807,7 @@ ol.format.GPX.prototype.writeFeatures;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.GPX.V1_1.prototype.writeFeaturesNode = function(features) {
|
||||
ol.format.GPX.prototype.writeFeaturesNode = function(features) {
|
||||
//FIXME Serialize metadata
|
||||
var gpx = ol.xml.createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');
|
||||
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
||||
|
||||
@@ -17,7 +17,8 @@ goog.require('ol.xml');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Feature format for reading and writing data in the OSMXML format.
|
||||
* Feature format for reading data in the
|
||||
* [OSMXML format](http://wiki.openstreetmap.org/wiki/OSM_XML).
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.format.XMLFeature}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
goog.provide('ol.format.WKT');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.format.TextFeature');
|
||||
goog.require('ol.geom.Geometry');
|
||||
@@ -29,7 +29,7 @@ ol.format.WKT = function(opt_options) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* Split GEOMETRYCOLLECTION into multiple features.
|
||||
* Split GeometryCollection into multiple features.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
@@ -41,132 +41,10 @@ goog.inherits(ol.format.WKT, ol.format.TextFeature);
|
||||
|
||||
|
||||
/**
|
||||
* Constants for regExes.
|
||||
* @enum {RegExp}
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.format.WKT.regExes = {
|
||||
typeStr: /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,
|
||||
spaces: /\s+/,
|
||||
parenComma: /\)\s*,\s*\(/,
|
||||
doubleParenComma: /\)\s*\)\s*,\s*\(\s*\(/,
|
||||
trimParens: /^\s*\(?(.*?)\)?\s*$/,
|
||||
geomCollection: /,\s*([A-Za-z])/g,
|
||||
removeNewLine: /[\n\r]/g
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT point.
|
||||
* @return {ol.geom.Point} Parsed point.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parsePoint_ = function(str) {
|
||||
var coords = goog.string.trim(str).split(ol.format.WKT.regExes.spaces);
|
||||
return new ol.geom.Point(goog.array.map(coords, parseFloat));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT linestring.
|
||||
* @return {ol.geom.LineString} Parsed linestring.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parseLineString_ = function(str) {
|
||||
var points = goog.string.trim(str).split(',');
|
||||
var coordinates = [];
|
||||
for (var i = 0, ii = points.length; i < ii; ++i) {
|
||||
coordinates.push(this.parsePoint_.apply(this,
|
||||
[points[i]]).getCoordinates());
|
||||
}
|
||||
return new ol.geom.LineString(coordinates);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT multipoint.
|
||||
* @return {ol.geom.MultiPoint} Parsed multipoint.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parseMultiPoint_ = function(str) {
|
||||
var point;
|
||||
var points = goog.string.trim(str).split(',');
|
||||
var geom = new ol.geom.MultiPoint(null);
|
||||
for (var i = 0, ii = points.length; i < ii; ++i) {
|
||||
point = points[i].replace(ol.format.WKT.regExes.trimParens, '$1');
|
||||
geom.appendPoint(this.parsePoint_.apply(this, [point]));
|
||||
}
|
||||
return geom;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT multilinestring.
|
||||
* @return {ol.geom.MultiLineString} Parsed multilinestring.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parseMultiLineString_ = function(str) {
|
||||
var line;
|
||||
var lines = goog.string.trim(str).split(ol.format.WKT.regExes.parenComma);
|
||||
var geom = new ol.geom.MultiLineString(null);
|
||||
for (var i = 0, ii = lines.length; i < ii; ++i) {
|
||||
line = lines[i].replace(ol.format.WKT.regExes.trimParens, '$1');
|
||||
geom.appendLineString(this.parseLineString_.apply(this, [line]));
|
||||
}
|
||||
return geom;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT polygon.
|
||||
* @return {ol.geom.Polygon} Parsed polygon.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parsePolygon_ = function(str) {
|
||||
var ring, linestring, linearring;
|
||||
var rings = goog.string.trim(str).split(ol.format.WKT.regExes.parenComma);
|
||||
var coordinates = [];
|
||||
for (var i = 0, ii = rings.length; i < ii; ++i) {
|
||||
ring = rings[i].replace(ol.format.WKT.regExes.trimParens, '$1');
|
||||
linestring = this.parseLineString_.apply(this, [ring]).getCoordinates();
|
||||
coordinates.push(linestring);
|
||||
}
|
||||
return new ol.geom.Polygon(coordinates);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT multipolygon.
|
||||
* @return {ol.geom.MultiPolygon} Parsed multipolygon.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parseMultiPolygon_ = function(str) {
|
||||
var polygon;
|
||||
var polygons = goog.string.trim(str).split(
|
||||
ol.format.WKT.regExes.doubleParenComma);
|
||||
var geom = new ol.geom.MultiPolygon(null);
|
||||
for (var i = 0, ii = polygons.length; i < ii; ++i) {
|
||||
polygon = polygons[i].replace(ol.format.WKT.regExes.trimParens, '$1');
|
||||
geom.appendPolygon(this.parsePolygon_.apply(this, [polygon]));
|
||||
}
|
||||
return geom;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str WKT geometrycollection.
|
||||
* @return {ol.geom.GeometryCollection} Parsed geometrycollection.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parseGeometryCollection_ = function(str) {
|
||||
// separate components of the collection with |
|
||||
str = str.replace(ol.format.WKT.regExes.geomCollection, '|$1');
|
||||
var wktArray = goog.string.trim(str).split('|');
|
||||
var geoms = [];
|
||||
for (var i = 0, ii = wktArray.length; i < ii; ++i) {
|
||||
geoms.push(this.parse_.apply(this, [wktArray[i]]));
|
||||
}
|
||||
return new ol.geom.GeometryCollection(geoms);
|
||||
};
|
||||
ol.format.WKT.EMPTY = 'EMPTY';
|
||||
|
||||
|
||||
/**
|
||||
@@ -174,8 +52,11 @@ ol.format.WKT.prototype.parseGeometryCollection_ = function(str) {
|
||||
* @return {string} Coordinates part of Point as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodePoint_ = function(geom) {
|
||||
ol.format.WKT.encodePointGeometry_ = function(geom) {
|
||||
var coordinates = geom.getCoordinates();
|
||||
if (goog.array.isEmpty(coordinates)) {
|
||||
return '';
|
||||
}
|
||||
return coordinates[0] + ' ' + coordinates[1];
|
||||
};
|
||||
|
||||
@@ -185,11 +66,11 @@ ol.format.WKT.prototype.encodePoint_ = function(geom) {
|
||||
* @return {string} Coordinates part of MultiPoint as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodeMultiPoint_ = function(geom) {
|
||||
ol.format.WKT.encodeMultiPointGeometry_ = function(geom) {
|
||||
var array = [];
|
||||
var components = geom.getPoints();
|
||||
for (var i = 0, ii = components.length; i < ii; ++i) {
|
||||
array.push('(' + this.encodePoint_.apply(this, [components[i]]) + ')');
|
||||
array.push('(' + ol.format.WKT.encodePointGeometry_(components[i]) + ')');
|
||||
}
|
||||
return array.join(',');
|
||||
};
|
||||
@@ -200,22 +81,22 @@ ol.format.WKT.prototype.encodeMultiPoint_ = function(geom) {
|
||||
* @return {string} Coordinates part of GeometryCollection as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodeGeometryCollection_ = function(geom) {
|
||||
ol.format.WKT.encodeGeometryCollectionGeometry_ = function(geom) {
|
||||
var array = [];
|
||||
var geoms = geom.getGeometries();
|
||||
for (var i = 0, ii = geoms.length; i < ii; ++i) {
|
||||
array.push(this.encode_.apply(this, [geoms[i]]));
|
||||
array.push(ol.format.WKT.encode_(geoms[i]));
|
||||
}
|
||||
return array.join(',');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.LineString} geom LineString geometry.
|
||||
* @param {ol.geom.LineString|ol.geom.LinearRing} geom LineString geometry.
|
||||
* @return {string} Coordinates part of LineString as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodeLineString_ = function(geom) {
|
||||
ol.format.WKT.encodeLineStringGeometry_ = function(geom) {
|
||||
var coordinates = geom.getCoordinates();
|
||||
var array = [];
|
||||
for (var i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
@@ -230,12 +111,12 @@ ol.format.WKT.prototype.encodeLineString_ = function(geom) {
|
||||
* @return {string} Coordinates part of MultiLineString as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodeMultiLineString_ = function(geom) {
|
||||
ol.format.WKT.encodeMultiLineStringGeometry_ = function(geom) {
|
||||
var array = [];
|
||||
var components = geom.getLineStrings();
|
||||
for (var i = 0, ii = components.length; i < ii; ++i) {
|
||||
array.push('(' + this.encodeLineString_.apply(this,
|
||||
[components[i]]) + ')');
|
||||
array.push('(' + ol.format.WKT.encodeLineStringGeometry_(
|
||||
components[i]) + ')');
|
||||
}
|
||||
return array.join(',');
|
||||
};
|
||||
@@ -246,12 +127,12 @@ ol.format.WKT.prototype.encodeMultiLineString_ = function(geom) {
|
||||
* @return {string} Coordinates part of Polygon as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodePolygon_ = function(geom) {
|
||||
ol.format.WKT.encodePolygonGeometry_ = function(geom) {
|
||||
var array = [];
|
||||
var rings = geom.getLinearRings();
|
||||
for (var i = 0, ii = rings.length; i < ii; ++i) {
|
||||
array.push('(' + this.encodeLineString_.apply(this,
|
||||
[rings[i]]) + ')');
|
||||
array.push('(' + ol.format.WKT.encodeLineStringGeometry_(
|
||||
rings[i]) + ')');
|
||||
}
|
||||
return array.join(',');
|
||||
};
|
||||
@@ -262,16 +143,52 @@ ol.format.WKT.prototype.encodePolygon_ = function(geom) {
|
||||
* @return {string} Coordinates part of MultiPolygon as WKT.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encodeMultiPolygon_ = function(geom) {
|
||||
ol.format.WKT.encodeMultiPolygonGeometry_ = function(geom) {
|
||||
var array = [];
|
||||
var components = geom.getPolygons();
|
||||
for (var i = 0, ii = components.length; i < ii; ++i) {
|
||||
array.push('(' + this.encodePolygon_.apply(this, [components[i]]) + ')');
|
||||
array.push('(' + ol.format.WKT.encodePolygonGeometry_(
|
||||
components[i]) + ')');
|
||||
}
|
||||
return array.join(',');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encode a geometry as WKT.
|
||||
* @param {ol.geom.Geometry} geom The geometry to encode.
|
||||
* @return {string} WKT string for the geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.encode_ = function(geom) {
|
||||
var type = geom.getType();
|
||||
var geometryEncoder = ol.format.WKT.GeometryEncoder_[type];
|
||||
goog.asserts.assert(goog.isDef(geometryEncoder));
|
||||
var enc = geometryEncoder(geom);
|
||||
type = type.toUpperCase();
|
||||
if (enc.length === 0) {
|
||||
return type + ' ' + ol.format.WKT.EMPTY;
|
||||
}
|
||||
return type + '(' + enc + ')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {Object.<string, function(ol.geom.Geometry): string>}
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.GeometryEncoder_ = {
|
||||
'Point': ol.format.WKT.encodePointGeometry_,
|
||||
'LineString': ol.format.WKT.encodeLineStringGeometry_,
|
||||
'Polygon': ol.format.WKT.encodePolygonGeometry_,
|
||||
'MultiPoint': ol.format.WKT.encodeMultiPointGeometry_,
|
||||
'MultiLineString': ol.format.WKT.encodeMultiLineStringGeometry_,
|
||||
'MultiPolygon': ol.format.WKT.encodeMultiPolygonGeometry_,
|
||||
'GeometryCollection': ol.format.WKT.encodeGeometryCollectionGeometry_
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse a WKT string.
|
||||
* @param {string} wkt WKT string.
|
||||
@@ -280,75 +197,16 @@ ol.format.WKT.prototype.encodeMultiPolygon_ = function(geom) {
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.parse_ = function(wkt) {
|
||||
wkt = wkt.replace(ol.format.WKT.regExes.removeNewLine, ' ');
|
||||
var matches = ol.format.WKT.regExes.typeStr.exec(wkt);
|
||||
var geometry;
|
||||
if (matches) {
|
||||
var type = matches[1].toLowerCase();
|
||||
var str = matches[2];
|
||||
switch (type) {
|
||||
case 'point':
|
||||
geometry = this.parsePoint_(str);
|
||||
break;
|
||||
case 'multipoint':
|
||||
geometry = this.parseMultiPoint_(str);
|
||||
break;
|
||||
case 'linestring':
|
||||
geometry = this.parseLineString_(str);
|
||||
break;
|
||||
case 'multilinestring':
|
||||
geometry = this.parseMultiLineString_(str);
|
||||
break;
|
||||
case 'polygon':
|
||||
geometry = this.parsePolygon_(str);
|
||||
break;
|
||||
case 'multipolygon':
|
||||
geometry = this.parseMultiPolygon_(str);
|
||||
break;
|
||||
case 'geometrycollection':
|
||||
geometry = this.parseGeometryCollection_(str);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Bad geometry type: ' + type);
|
||||
}
|
||||
}
|
||||
return geometry;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encode a geometry as WKT.
|
||||
* @param {ol.geom.Geometry} geom The geometry to encode.
|
||||
* @return {string} WKT string for the geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.prototype.encode_ = function(geom) {
|
||||
var type = geom.getType();
|
||||
var result = type.toUpperCase() + '(';
|
||||
if (geom instanceof ol.geom.Point) {
|
||||
result += this.encodePoint_(geom);
|
||||
} else if (geom instanceof ol.geom.MultiPoint) {
|
||||
result += this.encodeMultiPoint_(geom);
|
||||
} else if (geom instanceof ol.geom.LineString) {
|
||||
result += this.encodeLineString_(geom);
|
||||
} else if (geom instanceof ol.geom.MultiLineString) {
|
||||
result += this.encodeMultiLineString_(geom);
|
||||
} else if (geom instanceof ol.geom.Polygon) {
|
||||
result += this.encodePolygon_(geom);
|
||||
} else if (geom instanceof ol.geom.MultiPolygon) {
|
||||
result += this.encodeMultiPolygon_(geom);
|
||||
} else if (geom instanceof ol.geom.GeometryCollection) {
|
||||
result += this.encodeGeometryCollection_(geom);
|
||||
} else {
|
||||
throw new Error('Bad geometry type: ' + type);
|
||||
}
|
||||
return result + ')';
|
||||
var lexer = new ol.format.WKT.Lexer(wkt);
|
||||
var parser = new ol.format.WKT.Parser(lexer);
|
||||
return parser.parse();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Read a feature from a WKT source.
|
||||
*
|
||||
* @function
|
||||
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
|
||||
* @return {ol.Feature} Feature.
|
||||
* @api
|
||||
@@ -373,6 +231,7 @@ ol.format.WKT.prototype.readFeatureFromText = function(text) {
|
||||
/**
|
||||
* Read all features from a WKT source.
|
||||
*
|
||||
* @function
|
||||
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
|
||||
* @return {Array.<ol.Feature>} Features.
|
||||
* @api
|
||||
@@ -406,6 +265,7 @@ ol.format.WKT.prototype.readFeaturesFromText = function(text) {
|
||||
/**
|
||||
* Read a single geometry from a WKT source.
|
||||
*
|
||||
* @function
|
||||
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
|
||||
* @return {ol.geom.Geometry} Geometry.
|
||||
* @api
|
||||
@@ -432,6 +292,7 @@ ol.format.WKT.prototype.readProjectionFromText = function(text) {
|
||||
/**
|
||||
* Encode a feature as a WKT string.
|
||||
*
|
||||
* @function
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @return {ArrayBuffer|Node|Object|string} Result.
|
||||
* @api
|
||||
@@ -454,6 +315,7 @@ ol.format.WKT.prototype.writeFeatureText = function(feature) {
|
||||
/**
|
||||
* Encode an array of features as a WKT string.
|
||||
*
|
||||
* @function
|
||||
* @param {Array.<ol.Feature>} features Features.
|
||||
* @return {ArrayBuffer|Node|Object|string} Result.
|
||||
* @api
|
||||
@@ -480,6 +342,7 @@ ol.format.WKT.prototype.writeFeaturesText = function(features) {
|
||||
/**
|
||||
* Write a single geometry as a WKT string.
|
||||
*
|
||||
* @function
|
||||
* @param {ol.geom.Geometry} geometry Geometry.
|
||||
* @return {ArrayBuffer|Node|Object|string} Node.
|
||||
* @api
|
||||
@@ -491,5 +354,493 @@ ol.format.WKT.prototype.writeGeometry;
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.WKT.prototype.writeGeometryText = function(geometry) {
|
||||
return this.encode_(geometry);
|
||||
return ol.format.WKT.encode_(geometry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{type: number, value: (number|string|undefined), position: number}}
|
||||
*/
|
||||
ol.format.WKT.Token;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @enum {number}
|
||||
*/
|
||||
ol.format.WKT.TokenType = {
|
||||
TEXT: 1,
|
||||
LEFT_PAREN: 2,
|
||||
RIGHT_PAREN: 3,
|
||||
NUMBER: 4,
|
||||
COMMA: 5,
|
||||
EOF: 6
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to tokenize a WKT string.
|
||||
* @param {string} wkt WKT string.
|
||||
* @constructor
|
||||
* @protected
|
||||
*/
|
||||
ol.format.WKT.Lexer = function(wkt) {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.wkt = wkt;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.index_ = -1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} c Character.
|
||||
* @return {boolean} Whether the character is alphabetic.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.isAlpha_ = function(c) {
|
||||
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} c Character.
|
||||
* @param {boolean=} opt_decimal Whether the string number
|
||||
* contains a dot, i.e. is a decimal number.
|
||||
* @return {boolean} Whether the character is numeric.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.isNumeric_ = function(c, opt_decimal) {
|
||||
var decimal = goog.isDef(opt_decimal) ? opt_decimal : false;
|
||||
return c >= '0' && c <= '9' || c == '.' && !decimal;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} c Character.
|
||||
* @return {boolean} Whether the character is whitespace.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.isWhiteSpace_ = function(c) {
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Next string character.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.nextChar_ = function() {
|
||||
return this.wkt.charAt(++this.index_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fetch and return the next token.
|
||||
* @return {!ol.format.WKT.Token} Next string token.
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.nextToken = function() {
|
||||
var c = this.nextChar_();
|
||||
var token = {position: this.index_, value: c};
|
||||
|
||||
if (c == '(') {
|
||||
token.type = ol.format.WKT.TokenType.LEFT_PAREN;
|
||||
} else if (c == ',') {
|
||||
token.type = ol.format.WKT.TokenType.COMMA;
|
||||
} else if (c == ')') {
|
||||
token.type = ol.format.WKT.TokenType.RIGHT_PAREN;
|
||||
} else if (this.isNumeric_(c) || c == '-') {
|
||||
token.type = ol.format.WKT.TokenType.NUMBER;
|
||||
token.value = this.readNumber_();
|
||||
} else if (this.isAlpha_(c)) {
|
||||
token.type = ol.format.WKT.TokenType.TEXT;
|
||||
token.value = this.readText_();
|
||||
} else if (this.isWhiteSpace_(c)) {
|
||||
return this.nextToken();
|
||||
} else if (c === '') {
|
||||
token.type = ol.format.WKT.TokenType.EOF;
|
||||
} else {
|
||||
throw new Error('Unexpected character: ' + c);
|
||||
}
|
||||
|
||||
return token;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Numeric token value.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.readNumber_ = function() {
|
||||
var c, index = this.index_;
|
||||
var decimal = false;
|
||||
do {
|
||||
if (c == '.') {
|
||||
decimal = true;
|
||||
}
|
||||
c = this.nextChar_();
|
||||
} while (this.isNumeric_(c, decimal));
|
||||
return parseFloat(this.wkt.substring(index, this.index_--));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} String token value.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Lexer.prototype.readText_ = function() {
|
||||
var c, index = this.index_;
|
||||
do {
|
||||
c = this.nextChar_();
|
||||
} while (this.isAlpha_(c));
|
||||
return this.wkt.substring(index, this.index_--).toUpperCase();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to parse the tokens from the WKT string.
|
||||
* @param {ol.format.WKT.Lexer} lexer
|
||||
* @constructor
|
||||
* @protected
|
||||
*/
|
||||
ol.format.WKT.Parser = function(lexer) {
|
||||
|
||||
/**
|
||||
* @type {ol.format.WKT.Lexer}
|
||||
* @private
|
||||
*/
|
||||
this.lexer_ = lexer;
|
||||
|
||||
/**
|
||||
* @type {ol.format.WKT.Token}
|
||||
* @private
|
||||
*/
|
||||
this.token_;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.dimension_ = 2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fetch the next token form the lexer and replace the active token.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.consume_ = function() {
|
||||
this.token_ = this.lexer_.nextToken();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* If the given type matches the current token, consume it.
|
||||
* @param {ol.format.WKT.TokenType.<number>} type Token type.
|
||||
* @return {boolean} Whether the token matches the given type.
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.match = function(type) {
|
||||
var isMatch = this.token_.type == type;
|
||||
if (isMatch) {
|
||||
this.consume_();
|
||||
}
|
||||
return isMatch;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Try to parse the tokens provided by the lexer.
|
||||
* @return {ol.geom.Geometry|ol.geom.GeometryCollection} The geometry.
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parse = function() {
|
||||
this.consume_();
|
||||
var geometry = this.parseGeometry_();
|
||||
goog.asserts.assert(this.token_.type == ol.format.WKT.TokenType.EOF);
|
||||
return geometry;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!ol.geom.Geometry|!ol.geom.GeometryCollection} The geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseGeometry_ = function() {
|
||||
var token = this.token_;
|
||||
if (this.match(ol.format.WKT.TokenType.TEXT)) {
|
||||
var geomType = token.value;
|
||||
if (geomType == ol.geom.GeometryType.GEOMETRY_COLLECTION.toUpperCase()) {
|
||||
var geometries = this.parseGeometryCollectionText_();
|
||||
return new ol.geom.GeometryCollection(geometries);
|
||||
} else {
|
||||
var parser = ol.format.WKT.Parser.GeometryParser_[geomType];
|
||||
var ctor = ol.format.WKT.Parser.GeometryConstructor_[geomType];
|
||||
if (!goog.isDef(parser) || !goog.isDef(ctor)) {
|
||||
throw new Error('Invalid geometry type: ' + geomType);
|
||||
}
|
||||
var coordinates = parser.call(this);
|
||||
return new ctor(coordinates);
|
||||
}
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<ol.geom.Geometry>} A collection of geometries.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseGeometryCollectionText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var geometries = [];
|
||||
do {
|
||||
geometries.push(this.parseGeometry_());
|
||||
} while (this.match(ol.format.WKT.TokenType.COMMA));
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return geometries;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} All values in a point.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePointText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates = this.parsePoint_();
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return null;
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} All points in a linestring.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseLineStringText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates = this.parsePointList_();
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} All points in a polygon.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePolygonText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates = this.parseLineStringTextList_();
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} All points in a multipoint.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseMultiPointText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates;
|
||||
if (this.token_.type == ol.format.WKT.TokenType.LEFT_PAREN) {
|
||||
coordinates = this.parsePointTextList_();
|
||||
} else {
|
||||
coordinates = this.parsePointList_();
|
||||
}
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} All linestring points
|
||||
* in a multilinestring.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseMultiLineStringText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates = this.parseLineStringTextList_();
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} All polygon points in a multipolygon.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseMultiPolygonText_ = function() {
|
||||
if (this.match(ol.format.WKT.TokenType.LEFT_PAREN)) {
|
||||
var coordinates = this.parsePolygonTextList_();
|
||||
if (this.match(ol.format.WKT.TokenType.RIGHT_PAREN)) {
|
||||
return coordinates;
|
||||
}
|
||||
} else if (this.isEmptyGeometry_()) {
|
||||
return [];
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<number>} A point.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePoint_ = function() {
|
||||
var coordinates = [];
|
||||
for (var i = 0; i < this.dimension_; ++i) {
|
||||
var token = this.token_;
|
||||
if (this.match(ol.format.WKT.TokenType.NUMBER)) {
|
||||
coordinates.push(token.value);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (coordinates.length == this.dimension_) {
|
||||
return coordinates;
|
||||
}
|
||||
this.raiseError_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} An array of points.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePointList_ = function() {
|
||||
var coordinates = [this.parsePoint_()];
|
||||
if (this.match(ol.format.WKT.TokenType.COMMA)) {
|
||||
goog.array.extend(coordinates, this.parsePointList_());
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} An array of points.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePointTextList_ = function() {
|
||||
var coordinates = [this.parsePointText_()];
|
||||
if (this.match(ol.format.WKT.TokenType.COMMA)) {
|
||||
goog.array.extend(coordinates, this.parsePointTextList_());
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} An array of points.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parseLineStringTextList_ = function() {
|
||||
var coordinates = [this.parseLineStringText_()];
|
||||
if (this.match(ol.format.WKT.TokenType.COMMA)) {
|
||||
goog.array.extend(coordinates, this.parseLineStringTextList_());
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array.<!Array.<number>>} An array of points.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.parsePolygonTextList_ = function() {
|
||||
var coordinates = [this.parsePolygonText_()];
|
||||
if (this.match(ol.format.WKT.TokenType.COMMA)) {
|
||||
goog.array.extend(coordinates, this.parsePolygonTextList_());
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the token implies an empty geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.isEmptyGeometry_ = function() {
|
||||
var isEmpty = this.token_.type == ol.format.WKT.TokenType.TEXT &&
|
||||
this.token_.value == ol.format.WKT.EMPTY;
|
||||
if (isEmpty) {
|
||||
this.consume_();
|
||||
}
|
||||
return isEmpty;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.prototype.raiseError_ = function() {
|
||||
throw new Error('Unexpected `' + this.token_.value +
|
||||
'` at position ' + this.token_.position +
|
||||
' in `' + this.lexer_.wkt + '`');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {function (new:ol.geom.Geometry, Array, ol.geom.GeometryLayout.<string>=)}
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.GeometryConstructor_ = {
|
||||
'POINT': ol.geom.Point,
|
||||
'LINESTRING': ol.geom.LineString,
|
||||
'POLYGON': ol.geom.Polygon,
|
||||
'MULTIPOINT': ol.geom.MultiPoint,
|
||||
'MULTILINESTRING': ol.geom.MultiLineString,
|
||||
'MULTIPOLYGON': ol.geom.MultiPolygon
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {(function(): Array)}
|
||||
* @private
|
||||
*/
|
||||
ol.format.WKT.Parser.GeometryParser_ = {
|
||||
'POINT': ol.format.WKT.Parser.prototype.parsePointText_,
|
||||
'LINESTRING': ol.format.WKT.Parser.prototype.parseLineStringText_,
|
||||
'POLYGON': ol.format.WKT.Parser.prototype.parsePolygonText_,
|
||||
'MULTIPOINT': ol.format.WKT.Parser.prototype.parseMultiPointText_,
|
||||
'MULTILINESTRING': ol.format.WKT.Parser.prototype.parseMultiLineStringText_,
|
||||
'MULTIPOLYGON': ol.format.WKT.Parser.prototype.parseMultiPolygonText_
|
||||
};
|
||||
|
||||
180
src/ol/geom/flat/geodesicflatgeom.js
Normal file
180
src/ol/geom/flat/geodesicflatgeom.js
Normal file
@@ -0,0 +1,180 @@
|
||||
goog.provide('ol.geom.flat.geodesic');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.TransformFunction');
|
||||
goog.require('ol.math');
|
||||
goog.require('ol.proj');
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {function(number): ol.Coordinate} interpolate Interpolate function.
|
||||
* @param {ol.TransformFunction} transform Transform from longitude/latitude to
|
||||
* projected coordinates.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {Array.<number>} Flat coordinates.
|
||||
*/
|
||||
ol.geom.flat.geodesic.line_ =
|
||||
function(interpolate, transform, squaredTolerance) {
|
||||
// FIXME reduce garbage generation
|
||||
// FIXME optimize stack operations
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var flatCoordinates = [];
|
||||
|
||||
var geoA = interpolate(0);
|
||||
var geoB = interpolate(1);
|
||||
|
||||
var a = transform(geoA);
|
||||
var b = transform(geoB);
|
||||
|
||||
/** @type {Array.<ol.Coordinate>} */
|
||||
var geoStack = [geoB, geoA];
|
||||
/** @type {Array.<ol.Coordinate>} */
|
||||
var stack = [b, a];
|
||||
/** @type {Array.<number>} */
|
||||
var fractionStack = [1, 0];
|
||||
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var fractions = {};
|
||||
|
||||
var maxIterations = 1e5;
|
||||
var geoM, m, fracA, fracB, fracM, key;
|
||||
|
||||
while (--maxIterations > 0 && fractionStack.length > 0) {
|
||||
// Pop the a coordinate off the stack
|
||||
fracA = fractionStack.pop();
|
||||
geoA = geoStack.pop();
|
||||
a = stack.pop();
|
||||
// Add the a coordinate if it has not been added yet
|
||||
key = fracA.toString();
|
||||
if (!goog.object.containsKey(fractions, key)) {
|
||||
flatCoordinates.push(a[0], a[1]);
|
||||
goog.object.set(fractions, key, true);
|
||||
}
|
||||
// Pop the b coordinate off the stack
|
||||
fracB = fractionStack.pop();
|
||||
geoB = geoStack.pop();
|
||||
b = stack.pop();
|
||||
// Find the m point between the a and b coordinates
|
||||
fracM = (fracA + fracB) / 2;
|
||||
geoM = interpolate(fracM);
|
||||
m = transform(geoM);
|
||||
if (ol.math.squaredSegmentDistance(m[0], m[1], a[0], a[1],
|
||||
b[0], b[1]) < squaredTolerance) {
|
||||
// If the m point is sufficiently close to the straight line, then we
|
||||
// discard it. Just use the b coordinate and move on to the next line
|
||||
// segment.
|
||||
flatCoordinates.push(b[0], b[1]);
|
||||
key = fracB.toString();
|
||||
goog.asserts.assert(!goog.object.containsKey(fractions, key));
|
||||
goog.object.set(fractions, key, true);
|
||||
} else {
|
||||
// Otherwise, we need to subdivide the current line segment. Split it
|
||||
// into two and push the two line segments onto the stack.
|
||||
fractionStack.push(fracB, fracM, fracM, fracA);
|
||||
stack.push(b, m, m, a);
|
||||
geoStack.push(geoB, geoM, geoM, geoA);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(maxIterations > 0);
|
||||
|
||||
return flatCoordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a great-circle arcs between two lat/lon points.
|
||||
* @param {number} lon1 Longitude 1 in degrees.
|
||||
* @param {number} lat1 Latitude 1 in degrees.
|
||||
* @param {number} lon2 Longitude 2 in degrees.
|
||||
* @param {number} lat2 Latitude 2 in degrees.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {Array.<number>} Flat coordinates.
|
||||
*/
|
||||
ol.geom.flat.geodesic.greatCircleArc = function(
|
||||
lon1, lat1, lon2, lat2, projection, squaredTolerance) {
|
||||
|
||||
var geoProjection = ol.proj.get('EPSG:4326');
|
||||
|
||||
var cosLat1 = Math.cos(goog.math.toRadians(lat1));
|
||||
var sinLat1 = Math.sin(goog.math.toRadians(lat1));
|
||||
var cosLat2 = Math.cos(goog.math.toRadians(lat2));
|
||||
var sinLat2 = Math.sin(goog.math.toRadians(lat2));
|
||||
var cosDeltaLon = Math.cos(goog.math.toRadians(lon2 - lon1));
|
||||
var sinDeltaLon = Math.sin(goog.math.toRadians(lon2 - lon1));
|
||||
var d = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosDeltaLon;
|
||||
|
||||
return ol.geom.flat.geodesic.line_(
|
||||
/**
|
||||
* @param {number} frac Fraction.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
function(frac) {
|
||||
if (1 <= d) {
|
||||
return [lon2, lat2];
|
||||
}
|
||||
var D = frac * Math.acos(d);
|
||||
var cosD = Math.cos(D);
|
||||
var sinD = Math.sin(D);
|
||||
var y = sinDeltaLon * cosLat2;
|
||||
var x = cosLat1 * sinLat2 - sinLat1 * cosLat2 * cosDeltaLon;
|
||||
var theta = Math.atan2(y, x);
|
||||
var lat = Math.asin(sinLat1 * cosD + cosLat1 * sinD * Math.cos(theta));
|
||||
var lon = goog.math.toRadians(lon1) +
|
||||
Math.atan2(Math.sin(theta) * sinD * cosLat1,
|
||||
cosD - sinLat1 * Math.sin(lat));
|
||||
return [goog.math.toDegrees(lon), goog.math.toDegrees(lat)];
|
||||
}, ol.proj.getTransform(geoProjection, projection), squaredTolerance);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a meridian (line at constant longitude).
|
||||
* @param {number} lon Longitude.
|
||||
* @param {number} lat1 Latitude 1.
|
||||
* @param {number} lat2 Latitude 2.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {Array.<number>} Flat coordinates.
|
||||
*/
|
||||
ol.geom.flat.geodesic.meridian =
|
||||
function(lon, lat1, lat2, projection, squaredTolerance) {
|
||||
var epsg4326Projection = ol.proj.get('EPSG:4326');
|
||||
return ol.geom.flat.geodesic.line_(
|
||||
/**
|
||||
* @param {number} frac Fraction.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
function(frac) {
|
||||
return [lon, lat1 + ((lat2 - lat1) * frac)];
|
||||
},
|
||||
ol.proj.getTransform(epsg4326Projection, projection), squaredTolerance);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a parallel (line at constant latitude).
|
||||
* @param {number} lat Latitude.
|
||||
* @param {number} lon1 Longitude 1.
|
||||
* @param {number} lon2 Longitude 2.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {Array.<number>} Flat coordinates.
|
||||
*/
|
||||
ol.geom.flat.geodesic.parallel =
|
||||
function(lat, lon1, lon2, projection, squaredTolerance) {
|
||||
var epsg4326Projection = ol.proj.get('EPSG:4326');
|
||||
return ol.geom.flat.geodesic.line_(
|
||||
/**
|
||||
* @param {number} frac Fraction.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
function(frac) {
|
||||
return [lon1 + ((lon2 - lon1) * frac), lat];
|
||||
},
|
||||
ol.proj.getTransform(epsg4326Projection, projection), squaredTolerance);
|
||||
};
|
||||
@@ -65,7 +65,7 @@ ol.geom.Point.prototype.closestPointXY =
|
||||
* @api
|
||||
*/
|
||||
ol.geom.Point.prototype.getCoordinates = function() {
|
||||
return this.flatCoordinates.slice();
|
||||
return goog.isNull(this.flatCoordinates) ? [] : this.flatCoordinates.slice();
|
||||
};
|
||||
|
||||
|
||||
|
||||
427
src/ol/graticule.js
Normal file
427
src/ol/graticule.js
Normal file
@@ -0,0 +1,427 @@
|
||||
goog.provide('ol.Graticule');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.flat.geodesic');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.style.Stroke');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {olx.GraticuleOptions=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
ol.Graticule = function(opt_options) {
|
||||
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @type {ol.Map}
|
||||
* @private
|
||||
*/
|
||||
this.map_ = null;
|
||||
|
||||
/**
|
||||
* @type {ol.proj.Projection}
|
||||
* @private
|
||||
*/
|
||||
this.projection_ = null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxLat_ = Infinity;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxLon_ = Infinity;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minLat_ = -Infinity;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minLon_ = -Infinity;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.targetSize_ = goog.isDef(options.targetSize) ?
|
||||
options.targetSize : 100;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxLines_ = goog.isDef(options.maxLines) ? options.maxLines : 100;
|
||||
goog.asserts.assert(this.maxLines_ > 0);
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LineString>}
|
||||
* @private
|
||||
*/
|
||||
this.meridians_ = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LineString>}
|
||||
* @private
|
||||
*/
|
||||
this.parallels_ = [];
|
||||
|
||||
/**
|
||||
* TODO can be configurable
|
||||
* @type {ol.style.Stroke}
|
||||
* @private
|
||||
*/
|
||||
this.strokeStyle_ = new ol.style.Stroke({
|
||||
color: 'rgba(0,0,0,0.2)'
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {ol.TransformFunction|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.fromLonLatTransform_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {ol.TransformFunction|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.toLonLatTransform_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {ol.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.projectionCenterLonLat_ = null;
|
||||
|
||||
this.setMap(goog.isDef(options.map) ? options.map : null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TODO can be configurable
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.intervals_ = [90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05,
|
||||
0.01, 0.005, 0.002, 0.001];
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} lon Longitude.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} index Index.
|
||||
* @return {number} Index.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.addMeridian_ =
|
||||
function(lon, squaredTolerance, extent, index) {
|
||||
var lineString = this.getMeridian_(lon, squaredTolerance, index);
|
||||
if (ol.extent.intersects(lineString.getExtent(), extent)) {
|
||||
this.meridians_[index++] = lineString;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} lat Latitude.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} index Index.
|
||||
* @return {number} Index.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.addParallel_ =
|
||||
function(lat, squaredTolerance, extent, index) {
|
||||
var lineString = this.getParallel_(lat, squaredTolerance, index);
|
||||
if (ol.extent.intersects(lineString.getExtent(), extent)) {
|
||||
this.parallels_[index++] = lineString;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Coordinate} center Center.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.createGraticule_ =
|
||||
function(extent, center, resolution, squaredTolerance) {
|
||||
|
||||
var interval = this.getInterval_(resolution);
|
||||
if (interval == -1) {
|
||||
this.meridians_.length = this.parallels_.length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
var centerLonLat = this.toLonLatTransform_(center);
|
||||
var centerLon = centerLonLat[0];
|
||||
var centerLat = centerLonLat[1];
|
||||
var maxLines = this.maxLines_;
|
||||
var cnt, idx, lat, lon;
|
||||
|
||||
// Create meridians
|
||||
|
||||
centerLon = Math.floor(centerLon / interval) * interval;
|
||||
lon = goog.math.clamp(centerLon, this.minLon_, this.maxLon_);
|
||||
|
||||
idx = this.addMeridian_(lon, squaredTolerance, extent, 0);
|
||||
|
||||
cnt = 0;
|
||||
while (lon != this.minLon_ && cnt++ < maxLines) {
|
||||
lon = Math.max(lon - interval, this.minLon_);
|
||||
idx = this.addMeridian_(lon, squaredTolerance, extent, idx);
|
||||
}
|
||||
|
||||
lon = goog.math.clamp(centerLon, this.minLon_, this.maxLon_);
|
||||
|
||||
cnt = 0;
|
||||
while (lon != this.maxLon_ && cnt++ < maxLines) {
|
||||
lon = Math.min(lon + interval, this.maxLon_);
|
||||
idx = this.addMeridian_(lon, squaredTolerance, extent, idx);
|
||||
}
|
||||
|
||||
this.meridians_.length = idx;
|
||||
|
||||
// Create parallels
|
||||
|
||||
centerLat = Math.floor(centerLat / interval) * interval;
|
||||
lat = goog.math.clamp(centerLat, this.minLat_, this.maxLat_);
|
||||
|
||||
idx = this.addParallel_(lat, squaredTolerance, extent, 0);
|
||||
|
||||
cnt = 0;
|
||||
while (lat != this.minLat_ && cnt++ < maxLines) {
|
||||
lat = Math.max(lat - interval, this.minLat_);
|
||||
idx = this.addParallel_(lat, squaredTolerance, extent, idx);
|
||||
}
|
||||
|
||||
lat = goog.math.clamp(centerLat, this.minLat_, this.maxLat_);
|
||||
|
||||
cnt = 0;
|
||||
while (lat != this.maxLat_ && cnt++ < maxLines) {
|
||||
lat = Math.min(lat + interval, this.maxLat_);
|
||||
idx = this.addParallel_(lat, squaredTolerance, extent, idx);
|
||||
}
|
||||
|
||||
this.parallels_.length = idx;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {number} The interval in degrees.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.getInterval_ = function(resolution) {
|
||||
var centerLon = this.projectionCenterLonLat_[0];
|
||||
var centerLat = this.projectionCenterLonLat_[1];
|
||||
var interval = -1;
|
||||
var i, ii, delta, dist;
|
||||
var target = Math.pow(this.targetSize_ * resolution, 2);
|
||||
/** @type {Array.<number>} **/
|
||||
var p1 = [];
|
||||
/** @type {Array.<number>} **/
|
||||
var p2 = [];
|
||||
for (i = 0, ii = ol.Graticule.intervals_.length; i < ii; ++i) {
|
||||
delta = ol.Graticule.intervals_[i] / 2;
|
||||
p1[0] = centerLon - delta;
|
||||
p1[1] = centerLat - delta;
|
||||
p2[0] = centerLon + delta;
|
||||
p2[1] = centerLat + delta;
|
||||
this.fromLonLatTransform_(p1, p1);
|
||||
this.fromLonLatTransform_(p2, p2);
|
||||
dist = Math.pow(p2[0] - p1[0], 2) + Math.pow(p2[1] - p1[1], 2);
|
||||
if (dist <= target) {
|
||||
break;
|
||||
}
|
||||
interval = ol.Graticule.intervals_[i];
|
||||
}
|
||||
return interval;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Map} The map.
|
||||
* @api
|
||||
*/
|
||||
ol.Graticule.prototype.getMap = function() {
|
||||
return this.map_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} lon Longitude.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {ol.geom.LineString} The meridian line string.
|
||||
* @param {number} index Index.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.getMeridian_ = function(lon, squaredTolerance, index) {
|
||||
goog.asserts.assert(lon >= this.minLon_);
|
||||
goog.asserts.assert(lon <= this.maxLon_);
|
||||
var flatCoordinates = ol.geom.flat.geodesic.meridian(lon,
|
||||
this.minLat_, this.maxLat_, this.projection_, squaredTolerance);
|
||||
goog.asserts.assert(flatCoordinates.length > 0);
|
||||
var lineString = goog.isDef(this.meridians_[index]) ?
|
||||
this.meridians_[index] : new ol.geom.LineString(null);
|
||||
lineString.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
|
||||
return lineString;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.geom.LineString>} The meridians.
|
||||
* @api
|
||||
*/
|
||||
ol.Graticule.prototype.getMeridians = function() {
|
||||
return this.meridians_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} lat Latitude.
|
||||
* @param {number} squaredTolerance Squared tolerance.
|
||||
* @return {ol.geom.LineString} The parallel line string.
|
||||
* @param {number} index Index.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.getParallel_ = function(lat, squaredTolerance, index) {
|
||||
goog.asserts.assert(lat >= this.minLat_);
|
||||
goog.asserts.assert(lat <= this.maxLat_);
|
||||
var flatCoordinates = ol.geom.flat.geodesic.parallel(lat,
|
||||
this.minLon_, this.maxLon_, this.projection_, squaredTolerance);
|
||||
goog.asserts.assert(flatCoordinates.length > 0);
|
||||
var lineString = goog.isDef(this.parallels_[index]) ?
|
||||
this.parallels_[index] : new ol.geom.LineString(null);
|
||||
lineString.setFlatCoordinates(ol.geom.GeometryLayout.XY, flatCoordinates);
|
||||
return lineString;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.geom.LineString>} The parallels.
|
||||
* @api
|
||||
*/
|
||||
ol.Graticule.prototype.getParallels = function() {
|
||||
return this.parallels_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.render.Event} e Event.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.handlePostCompose_ = function(e) {
|
||||
var vectorContext = e.vectorContext;
|
||||
var frameState = e.frameState;
|
||||
var extent = frameState.extent;
|
||||
var viewState = frameState.viewState;
|
||||
var center = viewState.center;
|
||||
var projection = viewState.projection;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var squaredTolerance =
|
||||
resolution * resolution / (4 * pixelRatio * pixelRatio);
|
||||
|
||||
var updateProjectionInfo = goog.isNull(this.projection_) ||
|
||||
!ol.proj.equivalent(this.projection_, projection);
|
||||
|
||||
if (updateProjectionInfo) {
|
||||
this.updateProjectionInfo_(projection);
|
||||
}
|
||||
|
||||
this.createGraticule_(extent, center, resolution, squaredTolerance);
|
||||
|
||||
// Draw the lines
|
||||
vectorContext.setFillStrokeStyle(null, this.strokeStyle_);
|
||||
var i, l, line;
|
||||
for (i = 0, l = this.meridians_.length; i < l; ++i) {
|
||||
line = this.meridians_[i];
|
||||
vectorContext.drawLineStringGeometry(line, null);
|
||||
}
|
||||
for (i = 0, l = this.parallels_.length; i < l; ++i) {
|
||||
line = this.parallels_[i];
|
||||
vectorContext.drawLineStringGeometry(line, null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.updateProjectionInfo_ = function(projection) {
|
||||
goog.asserts.assert(!goog.isNull(projection));
|
||||
|
||||
var extent = projection.getExtent();
|
||||
var worldExtent = projection.getWorldExtent();
|
||||
var maxLat = worldExtent[3];
|
||||
var maxLon = worldExtent[2];
|
||||
var minLat = worldExtent[1];
|
||||
var minLon = worldExtent[0];
|
||||
|
||||
goog.asserts.assert(!goog.isNull(extent));
|
||||
goog.asserts.assert(goog.isDef(maxLat));
|
||||
goog.asserts.assert(goog.isDef(maxLon));
|
||||
goog.asserts.assert(goog.isDef(minLat));
|
||||
goog.asserts.assert(goog.isDef(minLon));
|
||||
|
||||
this.maxLat_ = maxLat;
|
||||
this.maxLon_ = maxLon;
|
||||
this.minLat_ = minLat;
|
||||
this.minLon_ = minLon;
|
||||
|
||||
var epsg4326Projection = ol.proj.get('EPSG:4326');
|
||||
|
||||
this.fromLonLatTransform_ = ol.proj.getTransform(
|
||||
epsg4326Projection, projection);
|
||||
|
||||
this.toLonLatTransform_ = ol.proj.getTransform(
|
||||
projection, epsg4326Projection);
|
||||
|
||||
this.projectionCenterLonLat_ = this.toLonLatTransform_(
|
||||
ol.extent.getCenter(extent));
|
||||
|
||||
this.projection_ = projection;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map Map.
|
||||
* @api
|
||||
*/
|
||||
ol.Graticule.prototype.setMap = function(map) {
|
||||
if (!goog.isNull(this.map_)) {
|
||||
this.map_.un(ol.render.EventType.POSTCOMPOSE,
|
||||
this.handlePostCompose_, this);
|
||||
this.map_.render();
|
||||
}
|
||||
if (!goog.isNull(map)) {
|
||||
map.on(ol.render.EventType.POSTCOMPOSE,
|
||||
this.handlePostCompose_, this);
|
||||
map.render();
|
||||
}
|
||||
this.map_ = map;
|
||||
};
|
||||
@@ -152,8 +152,7 @@ ol.interaction.DragBox.prototype.onBoxEnd = goog.nullFunction;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragBox.prototype.handlePointerUp =
|
||||
function(mapBrowserEvent) {
|
||||
ol.interaction.DragBox.prototype.handlePointerUp = function(mapBrowserEvent) {
|
||||
if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
|
||||
return true;
|
||||
}
|
||||
@@ -176,8 +175,7 @@ ol.interaction.DragBox.prototype.handlePointerUp =
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragBox.prototype.handlePointerDown =
|
||||
function(mapBrowserEvent) {
|
||||
ol.interaction.DragBox.prototype.handlePointerDown = function(mapBrowserEvent) {
|
||||
if (!ol.events.condition.mouseOnly(mapBrowserEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,10 +67,10 @@ ol.interaction.DragPan.prototype.handlePointerDrag = function(mapBrowserEvent) {
|
||||
goog.asserts.assert(this.targetPointers.length >= 1);
|
||||
var centroid =
|
||||
ol.interaction.Pointer.centroid(this.targetPointers);
|
||||
if (this.kinetic_) {
|
||||
this.kinetic_.update(centroid[0], centroid[1]);
|
||||
}
|
||||
if (!goog.isNull(this.lastCentroid)) {
|
||||
if (this.kinetic_) {
|
||||
this.kinetic_.update(centroid[0], centroid[1]);
|
||||
}
|
||||
var deltaX = this.lastCentroid[0] - centroid[0];
|
||||
var deltaY = centroid[1] - this.lastCentroid[1];
|
||||
var map = mapBrowserEvent.map;
|
||||
@@ -91,8 +91,7 @@ ol.interaction.DragPan.prototype.handlePointerDrag = function(mapBrowserEvent) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragPan.prototype.handlePointerUp =
|
||||
function(mapBrowserEvent) {
|
||||
ol.interaction.DragPan.prototype.handlePointerUp = function(mapBrowserEvent) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var view = map.getView();
|
||||
if (this.targetPointers.length === 0) {
|
||||
@@ -124,8 +123,7 @@ ol.interaction.DragPan.prototype.handlePointerUp =
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragPan.prototype.handlePointerDown =
|
||||
function(mapBrowserEvent) {
|
||||
ol.interaction.DragPan.prototype.handlePointerDown = function(mapBrowserEvent) {
|
||||
if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var view = map.getView();
|
||||
|
||||
@@ -205,7 +205,7 @@ goog.inherits(ol.interaction.Draw, ol.interaction.Pointer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.feature.StyleFunction} Styles.
|
||||
* @return {ol.style.StyleFunction} Styles.
|
||||
*/
|
||||
ol.interaction.Draw.getDefaultStyleFunction = function() {
|
||||
var styles = ol.feature.createDefaultEditingStyles();
|
||||
|
||||
@@ -74,8 +74,7 @@ ol.interaction.Interaction.prototype.setMap = function(map) {
|
||||
* @param {ol.Coordinate} delta Delta.
|
||||
* @param {number=} opt_duration Duration.
|
||||
*/
|
||||
ol.interaction.Interaction.pan = function(
|
||||
map, view, delta, opt_duration) {
|
||||
ol.interaction.Interaction.pan = function(map, view, delta, opt_duration) {
|
||||
var currentCenter = view.getCenter();
|
||||
if (goog.isDef(currentCenter)) {
|
||||
if (goog.isDef(opt_duration) && opt_duration > 0) {
|
||||
|
||||
@@ -14,7 +14,6 @@ goog.require('ol.interaction.PinchZoom');
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Set of interactions included in maps by default. Specific interactions can be
|
||||
* excluded by setting the appropriate option to false in the constructor
|
||||
* options, but the order of the interactions is fixed. If you want to specify
|
||||
|
||||
@@ -769,7 +769,7 @@ ol.interaction.Modify.prototype.updateSegmentIndices_ = function(
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.feature.StyleFunction} Styles.
|
||||
* @return {ol.style.StyleFunction} Styles.
|
||||
*/
|
||||
ol.interaction.Modify.getDefaultStyleFunction = function() {
|
||||
var style = ol.feature.createDefaultEditingStyles();
|
||||
|
||||
@@ -204,7 +204,7 @@ ol.interaction.Select.prototype.setMap = function(map) {
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.feature.StyleFunction} Styles.
|
||||
* @return {ol.style.StyleFunction} Styles.
|
||||
*/
|
||||
ol.interaction.Select.getDefaultStyleFunction = function() {
|
||||
var styles = ol.feature.createDefaultEditingStyles();
|
||||
|
||||
@@ -81,25 +81,30 @@ ol.Kinetic.prototype.update = function(x, y) {
|
||||
* @return {boolean} Whether we should do kinetic animation.
|
||||
*/
|
||||
ol.Kinetic.prototype.end = function() {
|
||||
if (this.points_.length < 6) {
|
||||
// at least 2 points are required (i.e. there must be at least 6 elements
|
||||
// in the array)
|
||||
return false;
|
||||
}
|
||||
var delay = goog.now() - this.delay_;
|
||||
var lastIndex = this.points_.length - 3;
|
||||
if (this.points_[lastIndex + 2] < delay) {
|
||||
// the user stopped panning before releasing the map
|
||||
// the last tracked point is too old, which means that the user stopped
|
||||
// panning before releasing the map
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the first point which still falls into the delay time
|
||||
var firstIndex = lastIndex - 3;
|
||||
while (firstIndex >= 0 && this.points_[firstIndex + 2] > delay) {
|
||||
while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
|
||||
firstIndex -= 3;
|
||||
}
|
||||
if (firstIndex >= 0) {
|
||||
var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
|
||||
var dx = this.points_[lastIndex] - this.points_[firstIndex];
|
||||
var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
|
||||
this.angle_ = Math.atan2(dy, dx);
|
||||
this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
|
||||
return this.initialVelocity_ > this.minVelocity_;
|
||||
}
|
||||
return false;
|
||||
var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
|
||||
var dx = this.points_[lastIndex] - this.points_[firstIndex];
|
||||
var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
|
||||
this.angle_ = Math.atan2(dy, dx);
|
||||
this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
|
||||
return this.initialVelocity_ > this.minVelocity_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -157,6 +157,8 @@ ol.layer.Heatmap.createCircle_ = function(radius, blur, shadow) {
|
||||
|
||||
/**
|
||||
* @return {Array.<string>} Colors.
|
||||
* @api
|
||||
* @observable
|
||||
*/
|
||||
ol.layer.Heatmap.prototype.getGradient = function() {
|
||||
return /** @type {Array.<string>} */ (
|
||||
@@ -201,6 +203,8 @@ ol.layer.Heatmap.prototype.handleRender_ = function(event) {
|
||||
|
||||
/**
|
||||
* @param {Array.<string>} colors Gradient.
|
||||
* @api
|
||||
* @observable
|
||||
*/
|
||||
ol.layer.Heatmap.prototype.setGradient = function(colors) {
|
||||
this.set(ol.layer.HeatmapLayerProperty.GRADIENT, colors);
|
||||
|
||||
@@ -19,6 +19,7 @@ ol.layer.LayerProperty = {
|
||||
OPACITY: 'opacity',
|
||||
SATURATION: 'saturation',
|
||||
VISIBLE: 'visible',
|
||||
EXTENT: 'extent',
|
||||
MAX_RESOLUTION: 'maxResolution',
|
||||
MIN_RESOLUTION: 'minResolution'
|
||||
};
|
||||
@@ -33,6 +34,7 @@ ol.layer.LayerProperty = {
|
||||
* saturation: number,
|
||||
* sourceState: ol.source.State,
|
||||
* visible: boolean,
|
||||
* extent: (ol.Extent|undefined),
|
||||
* maxResolution: number,
|
||||
* minResolution: number}}
|
||||
*/
|
||||
@@ -141,6 +143,7 @@ ol.layer.Base.prototype.getLayerState = function() {
|
||||
var saturation = this.getSaturation();
|
||||
var sourceState = this.getSourceState();
|
||||
var visible = this.getVisible();
|
||||
var extent = this.getExtent();
|
||||
var maxResolution = this.getMaxResolution();
|
||||
var minResolution = this.getMinResolution();
|
||||
return {
|
||||
@@ -152,6 +155,7 @@ ol.layer.Base.prototype.getLayerState = function() {
|
||||
saturation: goog.isDef(saturation) ? Math.max(saturation, 0) : 1,
|
||||
sourceState: sourceState,
|
||||
visible: goog.isDef(visible) ? !!visible : true,
|
||||
extent: extent,
|
||||
maxResolution: goog.isDef(maxResolution) ? maxResolution : Infinity,
|
||||
minResolution: goog.isDef(minResolution) ? Math.max(minResolution, 0) : 0
|
||||
};
|
||||
@@ -174,6 +178,21 @@ ol.layer.Base.prototype.getLayersArray = goog.abstractMethod;
|
||||
ol.layer.Base.prototype.getLayerStatesArray = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent|undefined} The layer extent.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
ol.layer.Base.prototype.getExtent = function() {
|
||||
return /** @type {ol.Extent|undefined} */ (
|
||||
this.get(ol.layer.LayerProperty.EXTENT));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Base.prototype,
|
||||
'getExtent',
|
||||
ol.layer.Base.prototype.getExtent);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} The maximum resolution of the layer.
|
||||
* @observable
|
||||
@@ -320,6 +339,22 @@ goog.exportProperty(
|
||||
ol.layer.Base.prototype.setHue);
|
||||
|
||||
|
||||
/**
|
||||
* Set the extent at which the layer is visible. If `undefined`, the layer
|
||||
* will be visible at all extents.
|
||||
* @param {ol.Extent|undefined} extent The extent of the layer.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
ol.layer.Base.prototype.setExtent = function(extent) {
|
||||
this.set(ol.layer.LayerProperty.EXTENT, extent);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Base.prototype,
|
||||
'setExtent',
|
||||
ol.layer.Base.prototype.setExtent);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} maxResolution The maximum resolution of the layer.
|
||||
* @observable
|
||||
|
||||
@@ -11,6 +11,7 @@ goog.require('ol.CollectionEvent');
|
||||
goog.require('ol.CollectionEventType');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.ObjectEventType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Base');
|
||||
goog.require('ol.source.State');
|
||||
|
||||
@@ -30,8 +31,7 @@ ol.layer.GroupProperty = {
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.layer.Base}
|
||||
* @fires change Triggered when the state of the source of any of the layers of
|
||||
* this group changes
|
||||
* @fires change Triggered when the group/Collection changes.
|
||||
* @param {olx.layer.GroupOptions=} opt_options Layer options.
|
||||
* @api
|
||||
*/
|
||||
@@ -212,6 +212,10 @@ ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) {
|
||||
layerState.maxResolution, ownLayerState.maxResolution);
|
||||
layerState.minResolution = Math.max(
|
||||
layerState.minResolution, ownLayerState.minResolution);
|
||||
if (goog.isDef(ownLayerState.extent) && goog.isDef(layerState.extent)) {
|
||||
layerState.extent = ol.extent.getIntersection(
|
||||
layerState.extent, ownLayerState.extent);
|
||||
}
|
||||
}
|
||||
|
||||
return states;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
goog.provide('ol.layer.Vector');
|
||||
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.feature');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
/**
|
||||
@@ -39,21 +39,20 @@ ol.layer.Vector = function(opt_options) {
|
||||
|
||||
/**
|
||||
* User provided style.
|
||||
* @type {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction}
|
||||
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
|
||||
* @private
|
||||
*/
|
||||
this.style_ = null;
|
||||
|
||||
/**
|
||||
* Style function for use within the library.
|
||||
* @type {ol.feature.StyleFunction|undefined}
|
||||
* @type {ol.style.StyleFunction|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.styleFunction_ = undefined;
|
||||
|
||||
if (goog.isDef(options.style)) {
|
||||
this.setStyle(options.style);
|
||||
}
|
||||
this.setStyle(goog.isDefAndNotNull(options.style) ?
|
||||
options.style : ol.style.defaultStyleFunction);
|
||||
|
||||
};
|
||||
goog.inherits(ol.layer.Vector, ol.layer.Layer);
|
||||
@@ -72,7 +71,7 @@ ol.layer.Vector.prototype.getRenderOrder = function() {
|
||||
/**
|
||||
* Get the style for features. This returns whatever was passed to the `style`
|
||||
* option at construction or to the `setStyle` method.
|
||||
* @return {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction}
|
||||
* @return {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
|
||||
* Layer style.
|
||||
* @api
|
||||
*/
|
||||
@@ -83,7 +82,7 @@ ol.layer.Vector.prototype.getStyle = function() {
|
||||
|
||||
/**
|
||||
* Get the style function.
|
||||
* @return {ol.feature.StyleFunction|undefined} Layer style function.
|
||||
* @return {ol.style.StyleFunction|undefined} Layer style function.
|
||||
* @api
|
||||
*/
|
||||
ol.layer.Vector.prototype.getStyleFunction = function() {
|
||||
@@ -104,12 +103,12 @@ ol.layer.Vector.prototype.setRenderOrder = function(renderOrder) {
|
||||
* Set the style for features. This can be a single style object, an array
|
||||
* of styles, or a function that takes a feature and resolution and returns
|
||||
* an array of styles.
|
||||
* @param {ol.style.Style|Array.<ol.style.Style>|ol.feature.StyleFunction} style
|
||||
* @param {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction} style
|
||||
* Layer style.
|
||||
* @api
|
||||
*/
|
||||
ol.layer.Vector.prototype.setStyle = function(style) {
|
||||
this.style_ = style;
|
||||
this.styleFunction_ = ol.feature.createStyleFunction(style);
|
||||
this.styleFunction_ = ol.style.createStyleFunction(style);
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
@@ -139,6 +139,15 @@ ol.MapProperty = {
|
||||
* The above snippet creates a map with a MapQuest OSM layer on a 2D view and
|
||||
* renders it to a DOM element with the id `map`.
|
||||
*
|
||||
* The constructor places a viewport container (with CSS class name
|
||||
* `ol-viewport`) in the target element (see `getViewport()`), and then two
|
||||
* further elements within the viewport: one with CSS class name
|
||||
* `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
|
||||
* CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
|
||||
* option of {@link ol.Overlay} for the difference). The map itself is placed in
|
||||
* a further element within the viewport, either DOM or Canvas, depending on the
|
||||
* renderer.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
* @param {olx.MapOptions} options Map options.
|
||||
@@ -163,9 +172,9 @@ ol.Map = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
* @type {Object}
|
||||
*/
|
||||
this.ol3Logo_ = optionsInternal.ol3Logo;
|
||||
this.logos_ = optionsInternal.logos;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -680,8 +689,7 @@ ol.Map.prototype.getInteractions = function() {
|
||||
* @api stable
|
||||
*/
|
||||
ol.Map.prototype.getLayerGroup = function() {
|
||||
return /** @type {ol.layer.Group} */ (
|
||||
this.get(ol.MapProperty.LAYERGROUP));
|
||||
return /** @type {ol.layer.Group} */ (this.get(ol.MapProperty.LAYERGROUP));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
@@ -1094,8 +1102,8 @@ ol.Map.prototype.render = function() {
|
||||
/**
|
||||
* Remove the given control from the map.
|
||||
* @param {ol.control.Control} control Control.
|
||||
* @return {ol.control.Control|undefined} The removed control of undefined
|
||||
* if the control was not found.
|
||||
* @return {ol.control.Control|undefined} The removed control (or undefined
|
||||
* if the control was not found).
|
||||
* @api stable
|
||||
*/
|
||||
ol.Map.prototype.removeControl = function(control) {
|
||||
@@ -1129,8 +1137,8 @@ ol.Map.prototype.removeInteraction = function(interaction) {
|
||||
/**
|
||||
* Removes the given layer from the map.
|
||||
* @param {ol.layer.Base} layer Layer.
|
||||
* @return {ol.layer.Base|undefined} The removed layer or undefined if the
|
||||
* layer was not found.
|
||||
* @return {ol.layer.Base|undefined} The removed layer (or undefined if the
|
||||
* layer was not found).
|
||||
* @api stable
|
||||
*/
|
||||
ol.Map.prototype.removeLayer = function(layer) {
|
||||
@@ -1143,8 +1151,8 @@ ol.Map.prototype.removeLayer = function(layer) {
|
||||
/**
|
||||
* Remove the given overlay from the map.
|
||||
* @param {ol.Overlay} overlay Overlay.
|
||||
* @return {ol.Overlay|undefined} The removed overlay of undefined
|
||||
* if the overlay was not found.
|
||||
* @return {ol.Overlay|undefined} The removed overlay (or undefined
|
||||
* if the overlay was not found).
|
||||
* @api stable
|
||||
*/
|
||||
ol.Map.prototype.removeOverlay = function(overlay) {
|
||||
@@ -1201,7 +1209,7 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
index: this.frameIndex_++,
|
||||
layerStates: layerStates,
|
||||
layerStatesArray: layerStatesArray,
|
||||
logos: {},
|
||||
logos: this.logos_,
|
||||
pixelRatio: this.pixelRatio_,
|
||||
pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_,
|
||||
postRenderFunctions: [],
|
||||
@@ -1214,9 +1222,6 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
viewHints: viewHints,
|
||||
wantedTiles: {}
|
||||
});
|
||||
if (this.ol3Logo_) {
|
||||
frameState.logos[ol.OL3_LOGO_URL] = ol.OL3_URL;
|
||||
}
|
||||
}
|
||||
|
||||
var preRenderFunctions = this.preRenderFunctions_;
|
||||
@@ -1348,8 +1353,7 @@ ol.Map.prototype.updateSize = function() {
|
||||
/**
|
||||
* @type {Element}
|
||||
*/
|
||||
var targetElement = goog.isDef(target) ?
|
||||
goog.dom.getElement(target) : null;
|
||||
var targetElement = goog.isDef(target) ? goog.dom.getElement(target) : null;
|
||||
|
||||
if (goog.isNull(targetElement)) {
|
||||
this.setSize(undefined);
|
||||
@@ -1375,7 +1379,7 @@ ol.Map.prototype.unskipFeature = function(feature) {
|
||||
* deviceOptions: olx.DeviceOptions,
|
||||
* interactions: ol.Collection,
|
||||
* keyboardEventTarget: (Element|Document),
|
||||
* ol3Logo: boolean,
|
||||
* logos: Object,
|
||||
* overlays: ol.Collection,
|
||||
* rendererConstructor:
|
||||
* function(new: ol.renderer.Map, Element, ol.Map),
|
||||
@@ -1407,7 +1411,20 @@ ol.Map.createOptionsInternal = function(options) {
|
||||
*/
|
||||
var values = {};
|
||||
|
||||
var ol3Logo = goog.isDef(options.ol3Logo) ? options.ol3Logo : true;
|
||||
var logos = {};
|
||||
if (!goog.isDef(options.logo) ||
|
||||
(goog.isBoolean(options.logo) && options.logo)) {
|
||||
logos[ol.OL3_LOGO_URL] = ol.OL3_URL;
|
||||
} else {
|
||||
var logo = options.logo;
|
||||
if (goog.isString(logo)) {
|
||||
logos[logo] = '';
|
||||
} else if (goog.isObject(logo)) {
|
||||
goog.asserts.assertString(logo.href);
|
||||
goog.asserts.assertString(logo.src);
|
||||
logos[logo.src] = logo.href;
|
||||
}
|
||||
}
|
||||
|
||||
var layerGroup = (options.layers instanceof ol.layer.Group) ?
|
||||
options.layers : new ol.layer.Group({layers: options.layers});
|
||||
@@ -1505,7 +1522,7 @@ ol.Map.createOptionsInternal = function(options) {
|
||||
deviceOptions: deviceOptions,
|
||||
interactions: interactions,
|
||||
keyboardEventTarget: keyboardEventTarget,
|
||||
ol3Logo: ol3Logo,
|
||||
logos: logos,
|
||||
overlays: overlays,
|
||||
rendererConstructor: rendererConstructor,
|
||||
values: values
|
||||
|
||||
@@ -45,18 +45,18 @@ ol.MapBrowserEvent = function(type, map, browserEvent, opt_frameState) {
|
||||
*/
|
||||
this.originalEvent = browserEvent.getBrowserEvent();
|
||||
|
||||
/**
|
||||
* @type {ol.Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = map.getEventCoordinate(this.originalEvent);
|
||||
|
||||
/**
|
||||
* @type {ol.Pixel}
|
||||
* @api
|
||||
*/
|
||||
this.pixel = map.getEventPixel(this.originalEvent);
|
||||
|
||||
/**
|
||||
* @type {ol.Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = map.getCoordinateFromPixel(this.pixel);
|
||||
|
||||
};
|
||||
goog.inherits(ol.MapBrowserEvent, ol.MapEvent);
|
||||
|
||||
|
||||
@@ -119,19 +119,47 @@ ol.ObjectAccessor.prototype.transform = function(from, to) {
|
||||
* @classdesc
|
||||
* Abstract base class; normally only used for creating subclasses and not
|
||||
* instantiated in apps.
|
||||
* All non-trivial classes inherit from this.
|
||||
* Most non-trivial classes inherit from this.
|
||||
*
|
||||
* It provides standardised get/set methods, and implements a form of
|
||||
* Key Value Observing. Setting a value triggers a change event, and 2 objects
|
||||
* can be bound together such that a change in one will automatically be
|
||||
* reflected in the other.
|
||||
* This extends {@link ol.Observable} with observable properties, where each
|
||||
* property is observable as well as the object as a whole.
|
||||
*
|
||||
* See {@link ol.dom.Input} for specific case of binding an object with an
|
||||
* HTML element.
|
||||
* Classes that inherit from this have pre-defined properties, to which you can
|
||||
* add your own. The pre-defined properties are listed in this documentation as
|
||||
* 'Observable Properties', and have their own accessors; for example,
|
||||
* {@link ol.Map} has a `target` property, accessed with `getTarget()` and
|
||||
* changed with `setTarget()`. Not all properties are however settable. There
|
||||
* are also general-purpose accessors `get()` and `set()`. For example,
|
||||
* `get('target')` is equivalent to `getTarget()`.
|
||||
*
|
||||
* The `set` accessors trigger a change event, and you can monitor this by
|
||||
* registering a listener. For example, {@link ol.View} has a `center`
|
||||
* property, so `view.on('change:center', function(evt) {...});` would call the
|
||||
* function whenever the value of the center property changes. Within the
|
||||
* function, `evt.target` would be the view, so `evt.target.getCenter()` would
|
||||
* return the new center.
|
||||
*
|
||||
* You can add your own observable properties with `set('myProp', 'new value')`,
|
||||
* and retrieve that with `get('myProp')`. A change listener can then be
|
||||
* registered with `on('change:myProp', ...)`. And a change can be triggered
|
||||
* with `dispatchEvent('change:myProp')`. You can get a list of all properties
|
||||
* with `getProperties()`.
|
||||
*
|
||||
* Note that the observable properties are separate from standard JS properties.
|
||||
* You can, for example, give your map object a title with
|
||||
* `map.title='New title'` and with `map.set('title', 'Another title')`. The
|
||||
* first will be a `hasOwnProperty`; the second will appear in
|
||||
* `getProperties()`. Only the second is observable.
|
||||
*
|
||||
* The observable properties also implement a form of Key Value Observing.
|
||||
* Two objects can be bound together such that a change in one will
|
||||
* automatically be reflected in the other. See `bindTo` method for more
|
||||
* details, and see {@link ol.dom.Input} for the specific case of binding an
|
||||
* object with an HTML element.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Observable}
|
||||
* @param {Object.<string, *>=} opt_values Values.
|
||||
* @param {Object.<string, *>=} opt_values An object with key-value pairs.
|
||||
* @fires ol.ObjectEvent
|
||||
* @api
|
||||
*/
|
||||
|
||||
30
src/ol/ol.js
30
src/ol/ol.js
@@ -208,14 +208,34 @@ ol.ZOOMSLIDER_ANIMATION_DURATION = 200;
|
||||
|
||||
|
||||
/**
|
||||
* ol.inherits is an alias to the goog.inherits function. It is exported
|
||||
* for use in non-compiled application code.
|
||||
* Inherit the prototype methods from one constructor into another.
|
||||
*
|
||||
* FIXME: We use a new line to fake the linter. Without the new line the
|
||||
* linter complains with:
|
||||
* Usage:
|
||||
*
|
||||
* "Missing newline between constructor and goog.inherits"
|
||||
* function ParentClass(a, b) { }
|
||||
* ParentClass.prototype.foo = function(a) { }
|
||||
*
|
||||
* function ChildClass(a, b, c) {
|
||||
* goog.base(this, a, b);
|
||||
* }
|
||||
* ol.inherits(ChildClass, ParentClass);
|
||||
*
|
||||
* var child = new ChildClass('a', 'b', 'see');
|
||||
* child.foo(); // This works.
|
||||
*
|
||||
* In addition, a superclass' implementation of a method can be invoked as
|
||||
* follows:
|
||||
*
|
||||
* ChildClass.prototype.foo = function(a) {
|
||||
* ChildClass.superClass_.foo.call(this, a);
|
||||
* // Other code here.
|
||||
* };
|
||||
*
|
||||
* @param {Function} childCtor Child constructor.
|
||||
* @param {Function} parentCtor Parent constructor.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
ol.inherits =
|
||||
goog.inherits;
|
||||
// note that the newline above is necessary to satisfy the linter
|
||||
|
||||
@@ -257,19 +257,6 @@ ol.pointer.PointerEvent.prototype.getPressure_ = function(eventDict, buttons) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Warning is suppressed because Closure thinks the MouseEvent
|
||||
* constructor takes no arguments.
|
||||
* @param {string} inType The type of the event to create.
|
||||
* @param {Object} inDict An dictionary of initial event properties.
|
||||
* @return {MouseEvent}
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
ol.pointer.PointerEvent.createMouseEvent = function(inType, inDict) {
|
||||
return new MouseEvent(inType, inDict);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Is the `buttons` property supported?
|
||||
* @type {boolean}
|
||||
@@ -282,7 +269,7 @@ ol.pointer.PointerEvent.HAS_BUTTONS = false;
|
||||
*/
|
||||
(function() {
|
||||
try {
|
||||
var ev = ol.pointer.PointerEvent.createMouseEvent('click', {buttons: 1});
|
||||
var ev = new MouseEvent('click', {buttons: 1});
|
||||
ol.pointer.PointerEvent.HAS_BUTTONS = ev.buttons === 1;
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
@@ -1,471 +0,0 @@
|
||||
goog.provide('ol.proj.CH');
|
||||
goog.provide('ol.proj.EPSG2056');
|
||||
goog.provide('ol.proj.EPSG21781');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.ellipsoid.BESSEL1841');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.proj.EPSG4326');
|
||||
goog.require('ol.proj.Projection');
|
||||
goog.require('ol.proj.Units');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal base class for Swiss grid projections.
|
||||
* @constructor
|
||||
* @extends {ol.proj.Projection}
|
||||
* @param {{code: string, extent: ol.Extent}} options Options.
|
||||
* @api
|
||||
*/
|
||||
ol.proj.CH = function(options) {
|
||||
goog.base(this, {
|
||||
code: options.code,
|
||||
extent: options.extent,
|
||||
global: false,
|
||||
units: ol.proj.Units.METERS
|
||||
});
|
||||
};
|
||||
goog.inherits(ol.proj.CH, ol.proj.Projection);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.PHI0 = goog.math.toRadians((3600 * 46 + 60 * 57 + 8.66) / 3600);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.LAMBDA0 = goog.math.toRadians((3600 * 7 + 60 * 26 + 22.5) / 3600);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Ellipsoid}
|
||||
*/
|
||||
ol.proj.CH.ELLIPSOID = ol.ellipsoid.BESSEL1841;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.COS_PHI0 = Math.cos(ol.proj.CH.PHI0);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.SIN_PHI0 = Math.sin(ol.proj.CH.PHI0);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.R = ol.proj.CH.ELLIPSOID.a * Math.sqrt(1 -
|
||||
ol.proj.CH.ELLIPSOID.eSquared) / (1 - ol.proj.CH.ELLIPSOID.eSquared *
|
||||
ol.proj.CH.SIN_PHI0 * ol.proj.CH.SIN_PHI0);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.ALPHA = Math.sqrt(1 +
|
||||
ol.proj.CH.ELLIPSOID.eSquared * Math.pow(ol.proj.CH.COS_PHI0, 4) /
|
||||
(1 - ol.proj.CH.ELLIPSOID.eSquared));
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.SIN_B0 = ol.proj.CH.SIN_PHI0 / ol.proj.CH.ALPHA;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.B0 = Math.asin(ol.proj.CH.SIN_B0);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.COS_B0 = Math.cos(ol.proj.CH.B0);
|
||||
// FIXME should we use Math.sqrt(1 - ol.proj.CH.SIN_B0 * ol.proj.CH.SIN_B0) ?
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.CH.K = Math.log(Math.tan(Math.PI / 4 + ol.proj.CH.B0 / 2)) -
|
||||
ol.proj.CH.ALPHA * Math.log(Math.tan(Math.PI / 4 + ol.proj.CH.PHI0 / 2)) +
|
||||
ol.proj.CH.ALPHA * ol.proj.CH.ELLIPSOID.e * Math.log(
|
||||
(1 + ol.proj.CH.ELLIPSOID.e * ol.proj.CH.SIN_PHI0) /
|
||||
(1 - ol.proj.CH.ELLIPSOID.e * ol.proj.CH.SIN_PHI0)) / 2;
|
||||
|
||||
|
||||
/**
|
||||
* Add EPSG:2056 and EPSG:21781 projections, and transformations between them.
|
||||
*/
|
||||
ol.proj.CH.add = function() {
|
||||
ol.proj.EPSG2056.add();
|
||||
ol.proj.EPSG21781.add();
|
||||
var epsg2056 = ol.proj.get('EPSG:2056');
|
||||
var epsg21781 = ol.proj.get('EPSG:21781');
|
||||
ol.proj.addTransform(epsg2056, epsg21781,
|
||||
goog.partial(ol.proj.CH.translate_, -2000000, -1000000));
|
||||
ol.proj.addTransform(epsg21781, epsg2056,
|
||||
goog.partial(ol.proj.CH.translate_, 2000000, 1000000));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:4326 to EPSG:2056/EPSG:21781.
|
||||
*
|
||||
* This uses an approximation that is accurate to about 1m.
|
||||
*
|
||||
* @see http://www.swisstopo.admin.ch/internet/swisstopo/en/home/products/software/products/skripts.html
|
||||
*
|
||||
* @param {number} offsetY Y offset.
|
||||
* @param {number} offsetX X offset.
|
||||
* @param {Array.<number>} input Input array of coordinate values.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
* @param {number=} opt_dimension Dimension (default is `2`).
|
||||
* @private
|
||||
* @return {Array.<number>} Output array of coordinate values.
|
||||
*/
|
||||
ol.proj.CH.fromEPSG4326Approximate_ =
|
||||
function(offsetY, offsetX, input, opt_output, opt_dimension) {
|
||||
var n = input.length;
|
||||
var dimension = goog.isDef(opt_dimension) ? opt_dimension : 2;
|
||||
var output;
|
||||
if (goog.isDef(opt_output)) {
|
||||
output = opt_output;
|
||||
} else {
|
||||
if (dimension > 2) {
|
||||
output = input.slice();
|
||||
} else {
|
||||
output = new Array(n);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(dimension >= 2);
|
||||
goog.asserts.assert(output.length % dimension === 0);
|
||||
var auxLat, auxLon, i;
|
||||
for (i = 0; i < n; i += dimension) {
|
||||
auxLat = 36 * input[i + 1] / 100 - 16.902866;
|
||||
auxLon = 36 * input[i] / 100 - 2.67825;
|
||||
output[i] = offsetY + 72.37 +
|
||||
211455.93 * auxLon -
|
||||
10938.51 * auxLon * auxLat -
|
||||
0.36 * auxLon * auxLat * auxLat -
|
||||
44.54 * auxLon * auxLon * auxLon;
|
||||
output[i + 1] = offsetX + 147.07 +
|
||||
308807.95 * auxLat +
|
||||
3745.25 * auxLon * auxLon +
|
||||
76.63 * auxLat * auxLat -
|
||||
194.56 * auxLon * auxLon * auxLat +
|
||||
119.79 * auxLat * auxLat * auxLat;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:4326 to EPSG:2056/EPSG:21781.
|
||||
*
|
||||
* @see http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/projections.html
|
||||
*
|
||||
* @param {number} offsetY Y offset.
|
||||
* @param {number} offsetX X offset.
|
||||
* @param {Array.<number>} input Input array of coordinate values.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
* @param {number=} opt_dimension Dimension (default is `2`).
|
||||
* @private
|
||||
* @return {Array.<number>} Output array of coordinate values.
|
||||
*/
|
||||
ol.proj.CH.fromEPSG4326Rigorous_ =
|
||||
function(offsetY, offsetX, input, opt_output, opt_dimension) {
|
||||
var n = input.length;
|
||||
var dimension = goog.isDef(opt_dimension) ? opt_dimension : 2;
|
||||
var output;
|
||||
if (goog.isDef(opt_output)) {
|
||||
output = opt_output;
|
||||
} else {
|
||||
if (dimension > 2) {
|
||||
output = input.slice();
|
||||
} else {
|
||||
output = new Array(n);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(dimension >= 2);
|
||||
goog.asserts.assert(output.length % dimension === 0);
|
||||
var b, bBar, eSinPhi, i, l, lambda, lBar, phi, s;
|
||||
for (i = 0; i < n; i += dimension) {
|
||||
lambda = goog.math.toRadians(input[i]);
|
||||
phi = goog.math.toRadians(input[i + 1]);
|
||||
eSinPhi = ol.proj.CH.ELLIPSOID.e * Math.sin(phi);
|
||||
s = ol.proj.CH.ALPHA * Math.log(Math.tan(Math.PI / 4 + phi / 2)) -
|
||||
ol.proj.CH.ALPHA * ol.proj.CH.ELLIPSOID.e * Math.log(
|
||||
(1 + eSinPhi) / (1 - eSinPhi)) / 2 + ol.proj.CH.K;
|
||||
b = 2 * (Math.atan(Math.exp(s)) - Math.PI / 4);
|
||||
l = ol.proj.CH.ALPHA * (lambda - ol.proj.CH.LAMBDA0);
|
||||
lBar = Math.atan2(Math.sin(l),
|
||||
ol.proj.CH.SIN_B0 * Math.tan(b) + ol.proj.CH.COS_B0 * Math.cos(l));
|
||||
bBar = Math.asin(ol.proj.CH.COS_B0 * Math.sin(b) -
|
||||
ol.proj.CH.SIN_B0 * Math.cos(b) * Math.cos(l));
|
||||
output[i] = offsetY + ol.proj.CH.R * lBar;
|
||||
output[i + 1] = offsetX + ol.proj.CH.R *
|
||||
Math.log((1 + Math.sin(bBar)) / (1 - Math.sin(bBar))) / 2;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:2056/EPSG:21781 to EPSG:4326.
|
||||
*
|
||||
* This uses an approximation that is accurate to about 1m.
|
||||
*
|
||||
* @see http://www.swisstopo.admin.ch/internet/swisstopo/en/home/products/software/products/skripts.html
|
||||
*
|
||||
* @param {number} offsetY Y offset.
|
||||
* @param {number} offsetX X offset.
|
||||
* @param {Array.<number>} input Input array of coordinate values.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
* @param {number=} opt_dimension Dimension (default is `2`).
|
||||
* @private
|
||||
* @return {Array.<number>} Output array of coordinate values.
|
||||
*/
|
||||
ol.proj.CH.toEPSG4326Approximate_ =
|
||||
function(offsetY, offsetX, input, opt_output, opt_dimension) {
|
||||
var n = input.length;
|
||||
var dimension = goog.isDef(opt_dimension) ? opt_dimension : 2;
|
||||
var output;
|
||||
if (goog.isDef(opt_output)) {
|
||||
output = opt_output;
|
||||
} else {
|
||||
if (dimension > 2) {
|
||||
output = input.slice();
|
||||
} else {
|
||||
output = new Array(n);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(dimension >= 2);
|
||||
goog.asserts.assert(output.length % dimension === 0);
|
||||
var auxX, auxY, i;
|
||||
for (i = 0; i < n; i += dimension) {
|
||||
auxY = (input[i] - offsetY) / 1000000;
|
||||
auxX = (input[i + 1] - offsetX) / 1000000;
|
||||
output[i] = 100 * (2.6779094 +
|
||||
4.728982 * auxY +
|
||||
0.791484 * auxY * auxX +
|
||||
0.1306 * auxY * auxX * auxX -
|
||||
0.0436 * auxY * auxY * auxY) / 36;
|
||||
output[i + 1] = 100 * (16.9023892 +
|
||||
3.238272 * auxX -
|
||||
0.270978 * auxY * auxY -
|
||||
0.002528 * auxX * auxX -
|
||||
0.0447 * auxY * auxY * auxX -
|
||||
0.014 * auxX * auxX * auxX) / 36;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transformation from EPSG:2056/EPSG:21781 to EPSG:4326.
|
||||
*
|
||||
* @see http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/projections.html
|
||||
*
|
||||
* @param {number} offsetY Y offset.
|
||||
* @param {number} offsetX X offset.
|
||||
* @param {Array.<number>} input Input array of coordinate values.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
* @param {number=} opt_dimension Dimension (default is `2`).
|
||||
* @private
|
||||
* @return {Array.<number>} Output array of coordinate values.
|
||||
*/
|
||||
ol.proj.CH.toEPSG4326Rigorous_ =
|
||||
function(offsetY, offsetX, input, opt_output, opt_dimension) {
|
||||
var n = input.length;
|
||||
var dimension = goog.isDef(opt_dimension) ? opt_dimension : 2;
|
||||
var output;
|
||||
if (goog.isDef(opt_output)) {
|
||||
output = opt_output;
|
||||
} else {
|
||||
if (dimension > 2) {
|
||||
output = input.slice();
|
||||
} else {
|
||||
output = new Array(n);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(dimension >= 2);
|
||||
goog.asserts.assert(output.length % dimension === 0);
|
||||
var b, bBar, eSinPhi, i, iterations, l, lambda, lastPhi, lBar, phi, s, x, y;
|
||||
for (i = 0; i < n; i += dimension) {
|
||||
y = input[i] - offsetY;
|
||||
x = input[i + 1] - offsetX;
|
||||
lBar = y / ol.proj.CH.R;
|
||||
bBar = 2 * (Math.atan(Math.exp(x / ol.proj.CH.R)) - Math.PI / 4);
|
||||
b = Math.asin(ol.proj.CH.COS_B0 * Math.sin(bBar) +
|
||||
ol.proj.CH.SIN_B0 * Math.cos(bBar) * Math.cos(lBar));
|
||||
l = Math.atan2(Math.sin(lBar), ol.proj.CH.COS_B0 * Math.cos(lBar) -
|
||||
ol.proj.CH.SIN_B0 * Math.tan(bBar));
|
||||
lambda = ol.proj.CH.LAMBDA0 + l / ol.proj.CH.ALPHA;
|
||||
lastPhi = phi = b;
|
||||
// Empirically, about 18 iterations are required for 1e-7 radian accuracy
|
||||
for (iterations = 20; iterations > 0; --iterations) {
|
||||
s = (Math.log(Math.tan(Math.PI / 4 + b / 2)) -
|
||||
ol.proj.CH.K) / ol.proj.CH.ALPHA +
|
||||
ol.proj.CH.ELLIPSOID.e * Math.log(Math.tan(Math.PI / 4 +
|
||||
Math.asin(ol.proj.CH.ELLIPSOID.e * Math.sin(phi)) / 2));
|
||||
phi = 2 * Math.atan(Math.exp(s)) - Math.PI / 2;
|
||||
if (Math.abs(phi - lastPhi) < 1e-7) {
|
||||
break;
|
||||
}
|
||||
lastPhi = phi;
|
||||
}
|
||||
goog.asserts.assert(iterations !== 0);
|
||||
output[i] = goog.math.toDegrees(lambda);
|
||||
output[i + 1] = goog.math.toDegrees(phi);
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transformation between EPSG:2056 and EPSG:21781.
|
||||
*
|
||||
* Currently a simple offset is used. This is accurate to within 3m.
|
||||
*
|
||||
* @param {number} offsetY Y offset.
|
||||
* @param {number} offsetX X offset.
|
||||
* @param {Array.<number>} input Input array of coordinate values.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
* @param {number=} opt_dimension Dimension (default is `2`).
|
||||
* @private
|
||||
* @return {Array.<number>} Output array of coordinate values.
|
||||
*/
|
||||
ol.proj.CH.translate_ =
|
||||
function(offsetY, offsetX, input, opt_output, opt_dimension) {
|
||||
var n = input.length;
|
||||
var dimension = goog.isDef(opt_dimension) ? opt_dimension : 2;
|
||||
var output;
|
||||
if (goog.isDef(opt_output)) {
|
||||
output = opt_output;
|
||||
} else {
|
||||
if (dimension > 2) {
|
||||
output = input.slice();
|
||||
} else {
|
||||
output = new Array(n);
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(dimension >= 2);
|
||||
goog.asserts.assert(output.length % dimension === 0);
|
||||
var i;
|
||||
for (i = 0; i < n; i += dimension) {
|
||||
output[i] = input[i] + offsetY;
|
||||
output[i + 1] = input[i + 1] + offsetX;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.proj.CH.prototype.getPointResolution = function(resolution, point) {
|
||||
return resolution;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The EPSG:2056 projection, also known as LV95 (CH1903+).
|
||||
* @constructor
|
||||
* @extends {ol.proj.CH}
|
||||
* @api
|
||||
*/
|
||||
ol.proj.EPSG2056 = function() {
|
||||
goog.base(this, {
|
||||
code: 'EPSG:2056',
|
||||
extent: ol.proj.EPSG2056.EXTENT
|
||||
});
|
||||
};
|
||||
goog.inherits(ol.proj.EPSG2056, ol.proj.CH);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
ol.proj.EPSG2056.EXTENT =
|
||||
[2485869.5728, 1076443.1884, 2837076.5648, 1299941.7864];
|
||||
|
||||
|
||||
/**
|
||||
* Add the EPSG:2056 projection and transformations to and from EPSG:4326.
|
||||
*/
|
||||
ol.proj.EPSG2056.add = function() {
|
||||
ol.proj.addEquivalentProjections(ol.proj.EPSG4326.PROJECTIONS);
|
||||
var epsg2056 = new ol.proj.EPSG2056();
|
||||
ol.proj.addProjection(epsg2056);
|
||||
ol.proj.addEquivalentTransforms(
|
||||
ol.proj.EPSG4326.PROJECTIONS,
|
||||
[epsg2056],
|
||||
goog.partial(ol.proj.CH.fromEPSG4326Rigorous_, 2600000, 1200000),
|
||||
goog.partial(ol.proj.CH.toEPSG4326Rigorous_, 2600000, 1200000));
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The EPSG:21781 projection, also known as LV03 (CH1903).
|
||||
* @constructor
|
||||
* @extends {ol.proj.CH}
|
||||
* @api
|
||||
*/
|
||||
ol.proj.EPSG21781 = function() {
|
||||
goog.base(this, {
|
||||
code: 'EPSG:21781',
|
||||
extent: ol.proj.EPSG21781.EXTENT
|
||||
});
|
||||
};
|
||||
goog.inherits(ol.proj.EPSG21781, ol.proj.CH);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
ol.proj.EPSG21781.EXTENT = [
|
||||
485869.5728, 76443.1884,
|
||||
837076.5648, 299941.7864
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Add the EPSG:21781 projection and transformations to and from EPSG:4326.
|
||||
*/
|
||||
ol.proj.EPSG21781.add = function() {
|
||||
ol.proj.addEquivalentProjections(ol.proj.EPSG4326.PROJECTIONS);
|
||||
var epsg21781 = new ol.proj.EPSG21781();
|
||||
ol.proj.addProjection(epsg21781);
|
||||
ol.proj.addEquivalentTransforms(
|
||||
ol.proj.EPSG4326.PROJECTIONS,
|
||||
[epsg21781],
|
||||
goog.partial(ol.proj.CH.fromEPSG4326Rigorous_, 600000, 200000),
|
||||
goog.partial(ol.proj.CH.toEPSG4326Rigorous_, 600000, 200000));
|
||||
};
|
||||
@@ -16,17 +16,26 @@ goog.require('ol.proj.Units');
|
||||
* @constructor
|
||||
* @extends {ol.proj.Projection}
|
||||
* @param {string} code Code.
|
||||
* @api
|
||||
* @private
|
||||
*/
|
||||
ol.proj.EPSG3857 = function(code) {
|
||||
ol.proj.EPSG3857_ = function(code) {
|
||||
goog.base(this, {
|
||||
code: code,
|
||||
units: ol.proj.Units.METERS,
|
||||
extent: ol.proj.EPSG3857.EXTENT,
|
||||
global: true
|
||||
global: true,
|
||||
worldExtent: ol.proj.EPSG3857.WORLD_EXTENT
|
||||
});
|
||||
};
|
||||
goog.inherits(ol.proj.EPSG3857, ol.proj.Projection);
|
||||
goog.inherits(ol.proj.EPSG3857_, ol.proj.Projection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.proj.EPSG3857_.prototype.getPointResolution = function(resolution, point) {
|
||||
return resolution / ol.math.cosh(point[1] / ol.proj.EPSG3857.RADIUS);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@@ -53,6 +62,13 @@ ol.proj.EPSG3857.EXTENT = [
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
ol.proj.EPSG3857.WORLD_EXTENT = [-180, -85, 180, 85];
|
||||
|
||||
|
||||
/**
|
||||
* Lists several projection codes with the same meaning as EPSG:3857.
|
||||
*
|
||||
@@ -77,7 +93,7 @@ ol.proj.EPSG3857.CODES = [
|
||||
ol.proj.EPSG3857.PROJECTIONS = goog.array.map(
|
||||
ol.proj.EPSG3857.CODES,
|
||||
function(code) {
|
||||
return new ol.proj.EPSG3857(code);
|
||||
return new ol.proj.EPSG3857_(code);
|
||||
});
|
||||
|
||||
|
||||
@@ -139,11 +155,3 @@ ol.proj.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) {
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.proj.EPSG3857.prototype.getPointResolution = function(resolution, point) {
|
||||
return resolution / ol.math.cosh(point[1] / ol.proj.EPSG3857.RADIUS);
|
||||
};
|
||||
|
||||
@@ -18,18 +18,27 @@ goog.require('ol.proj.Units');
|
||||
* @extends {ol.proj.Projection}
|
||||
* @param {string} code Code.
|
||||
* @param {string=} opt_axisOrientation Axis orientation.
|
||||
* @api
|
||||
* @private
|
||||
*/
|
||||
ol.proj.EPSG4326 = function(code, opt_axisOrientation) {
|
||||
ol.proj.EPSG4326_ = function(code, opt_axisOrientation) {
|
||||
goog.base(this, {
|
||||
code: code,
|
||||
units: ol.proj.Units.DEGREES,
|
||||
extent: ol.proj.EPSG4326.EXTENT,
|
||||
axisOrientation: opt_axisOrientation,
|
||||
global: true
|
||||
global: true,
|
||||
worldExtent: ol.proj.EPSG4326.EXTENT
|
||||
});
|
||||
};
|
||||
goog.inherits(ol.proj.EPSG4326, ol.proj.Projection);
|
||||
goog.inherits(ol.proj.EPSG4326_, ol.proj.Projection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.proj.EPSG4326_.prototype.getPointResolution = function(resolution, point) {
|
||||
return resolution;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@@ -48,19 +57,11 @@ ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90];
|
||||
* @type {Array.<ol.proj.Projection>}
|
||||
*/
|
||||
ol.proj.EPSG4326.PROJECTIONS = [
|
||||
new ol.proj.EPSG4326('CRS:84'),
|
||||
new ol.proj.EPSG4326('EPSG:4326', 'neu'),
|
||||
new ol.proj.EPSG4326('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),
|
||||
new ol.proj.EPSG4326('urn:ogc:def:crs:OGC:1.3:CRS84'),
|
||||
new ol.proj.EPSG4326('urn:ogc:def:crs:OGC:2:84'),
|
||||
new ol.proj.EPSG4326('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
|
||||
new ol.proj.EPSG4326('urn:x-ogc:def:crs:EPSG:4326', 'neu')
|
||||
new ol.proj.EPSG4326_('CRS:84'),
|
||||
new ol.proj.EPSG4326_('EPSG:4326', 'neu'),
|
||||
new ol.proj.EPSG4326_('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),
|
||||
new ol.proj.EPSG4326_('urn:ogc:def:crs:OGC:1.3:CRS84'),
|
||||
new ol.proj.EPSG4326_('urn:ogc:def:crs:OGC:2:84'),
|
||||
new ol.proj.EPSG4326_('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
|
||||
new ol.proj.EPSG4326_('urn:x-ogc:def:crs:EPSG:4326', 'neu')
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.proj.EPSG4326.prototype.getPointResolution = function(resolution, point) {
|
||||
return resolution;
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@ ol.proj.Units = {
|
||||
* @type {Object.<ol.proj.Units, number>}
|
||||
* @api
|
||||
*/
|
||||
ol.proj.METERS_PER_UNIT = {};
|
||||
ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] =
|
||||
2 * Math.PI * ol.sphere.NORMAL.radius / 360;
|
||||
ol.proj.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048;
|
||||
@@ -51,16 +52,14 @@ ol.proj.METERS_PER_UNIT[ol.proj.Units.METERS] = 1;
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Class for coordinate transforms between coordinate systems. By default,
|
||||
* OpenLayers ships with the ability to transform coordinates between
|
||||
* geographic (EPSG:4326) and web or spherical mercator (EPSG:3857)
|
||||
* coordinate reference systems. Any transform functions can be added with
|
||||
* {@link ol.proj.addCoordinateTransforms}.
|
||||
* Projection definition class. One of these is created for each projection
|
||||
* supported in the application and stored in the {@link ol.proj} namespace.
|
||||
* You can use these in applications, but this is not required, as API params
|
||||
* and options use {@link ol.proj.ProjectionLike} which means the simple string
|
||||
* code will suffice.
|
||||
*
|
||||
* Additional transforms may be added by using the {@link http://proj4js.org/}
|
||||
* library. If the proj4js library is loaded, transforms will work between any
|
||||
* coordinate reference systems with proj4js definitions. These definitions can
|
||||
* be obtained from {@link http://epsg.io/}.
|
||||
* You can use {@link ol.proj.get} to retrieve the object for a particular
|
||||
* projection.
|
||||
*
|
||||
* @constructor
|
||||
* @param {olx.ProjectionOptions} options Projection options.
|
||||
@@ -87,6 +86,13 @@ ol.proj.Projection = function(options) {
|
||||
*/
|
||||
this.extent_ = goog.isDef(options.extent) ? options.extent : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.worldExtent_ = goog.isDef(options.worldExtent) ?
|
||||
options.worldExtent : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
@@ -149,6 +155,16 @@ ol.proj.Projection.prototype.getMetersPerUnit = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the world extent for this projection.
|
||||
* @return {ol.Extent} Extent.
|
||||
* @api
|
||||
*/
|
||||
ol.proj.Projection.prototype.getWorldExtent = function() {
|
||||
return this.worldExtent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the axis orientation of this projection.
|
||||
* Example values are:
|
||||
@@ -199,6 +215,17 @@ ol.proj.Projection.prototype.setExtent = function(extent) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the world extent for this projection.
|
||||
* @param {ol.Extent} worldExtent World extent
|
||||
* [minlon, minlat, maxlon, maxlat].
|
||||
* @api
|
||||
*/
|
||||
ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) {
|
||||
this.worldExtent_ = worldExtent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the resolution of the point in degrees. For projections with degrees as
|
||||
* the unit this will simply return the provided resolution. For other
|
||||
@@ -368,6 +395,9 @@ ol.proj.addTransform = function(source, destination, transformFn) {
|
||||
/**
|
||||
* Registers coordinate transform functions to convert coordinates between the
|
||||
* source projection and the destination projection.
|
||||
* The forward and inverse functions convert coordinate pairs; this function
|
||||
* converts these into the functions used internally which also handle
|
||||
* extents and coordinate arrays.
|
||||
*
|
||||
* @param {ol.proj.ProjectionLike} source Source projection.
|
||||
* @param {ol.proj.ProjectionLike} destination Destination projection.
|
||||
|
||||
@@ -14,5 +14,41 @@
|
||||
* for example by Bing Maps or OpenStreetMap), together with the relevant
|
||||
* transform functions.
|
||||
*
|
||||
* Additional transforms may be added by using the {@link http://proj4js.org/}
|
||||
* library (version 2.2 or later). You can use the full build supplied by
|
||||
* Proj4js, or create a custom build to support those projections you need; see
|
||||
* the Proj4js website for how to do this. You also need the Proj4js definitions
|
||||
* for the required projections. These definitions can be obtained from
|
||||
* {@link http://epsg.io/}, and are a JS function, so can be loaded in a script
|
||||
* tag (as in the examples) or pasted into your application.
|
||||
* The first time there is a request for a projection, either with a
|
||||
* {@link ol.proj.projectionLike} or directly with {@link ol.proj.get}, the
|
||||
* code will check if the Proj4js library and the necessary definition are
|
||||
* loaded; if so, it will register the appropriate {@link ol.proj.Projection}
|
||||
* object and add transform functions between the new projection and all the
|
||||
* existing ones. See examples/wms-image-custom-proj for an example of this.
|
||||
* Because the check for presence of the Proj4js library and the definition only
|
||||
* takes place on the first request for them, this means they can be loaded
|
||||
* dynamically as needed; for example, with user-supplied data where you don't
|
||||
* know in advance what projections are needed, you can initially load minimal
|
||||
* support and then load whichever are requested.
|
||||
*
|
||||
* Note that Proj4js does not support projection extents. If you want to add
|
||||
* one for creating default tile grids, you can add it after the Projection
|
||||
* object has been created with `setExtent`, for example,
|
||||
* `ol.proj.get('EPSG:1234').setExtent(extent)`.
|
||||
*
|
||||
* In addition to Proj4js support, any transform functions can be added with
|
||||
* {@link ol.proj.addCoordinateTransforms}. To use this, you must first create
|
||||
* a {@link ol.proj.Projection} object for the new projection and add it with
|
||||
* {@link ol.proj.addProjection}. You can then add the forward and inverse
|
||||
* functions with {@link ol.proj.addCoordinateTransforms}. See
|
||||
* examples/wms-custom-proj for an example of this.
|
||||
*
|
||||
* Note that if no transforms are needed and you only need to define the
|
||||
* projection, just add a {@link ol.proj.Projection} with
|
||||
* {@link ol.proj.addProjection}. See examples/wms-no-proj for an example of
|
||||
* this.
|
||||
*
|
||||
* @namespace ol.proj
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@ goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.ImageBase');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
@@ -102,9 +103,16 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame =
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING]) {
|
||||
var renderedExtent = frameState.extent;
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
renderedExtent = ol.extent.getIntersection(
|
||||
renderedExtent, layerState.extent);
|
||||
}
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
|
||||
!ol.extent.isEmpty(renderedExtent)) {
|
||||
image = imageSource.getImage(
|
||||
frameState.extent, viewResolution, pixelRatio, viewState.projection);
|
||||
renderedExtent, viewResolution, pixelRatio, viewState.projection);
|
||||
if (!goog.isNull(image)) {
|
||||
var imageState = image.getState();
|
||||
if (imageState == ol.ImageState.IDLE) {
|
||||
|
||||
@@ -193,6 +193,11 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
} else {
|
||||
extent = frameState.extent;
|
||||
}
|
||||
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
extent = ol.extent.getIntersection(extent, layerState.extent);
|
||||
}
|
||||
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
extent, tileResolution);
|
||||
|
||||
@@ -233,6 +238,11 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
if (z != this.renderedCanvasZ_ ||
|
||||
!this.renderedCanvasTileRange_.containsTileRange(tileRange)) {
|
||||
this.renderedCanvasTileRange_ = null;
|
||||
// Due to limited layer extent, we may be rendering tiles on a small
|
||||
// portion of the canvas.
|
||||
if (z < this.renderedCanvasZ_) {
|
||||
this.context_.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ goog.require('goog.events');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.feature');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.render.canvas.ReplayGroup');
|
||||
@@ -155,7 +154,7 @@ ol.renderer.canvas.VectorLayer.prototype.handleImageChange_ =
|
||||
ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var vectorLayer = this.getLayer();
|
||||
var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
|
||||
goog.asserts.assertInstanceof(vectorLayer, ol.layer.Vector);
|
||||
var vectorSource = vectorLayer.getSource();
|
||||
goog.asserts.assertInstanceof(vectorSource, ol.source.Vector);
|
||||
@@ -202,10 +201,6 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
||||
|
||||
this.dirty_ = false;
|
||||
|
||||
var styleFunction = vectorLayer.getStyleFunction();
|
||||
if (!goog.isDef(styleFunction)) {
|
||||
styleFunction = ol.feature.defaultStyleFunction;
|
||||
}
|
||||
var replayGroup =
|
||||
new ol.render.canvas.ReplayGroup(
|
||||
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||
@@ -217,10 +212,17 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
||||
* @this {ol.renderer.canvas.VectorLayer}
|
||||
*/
|
||||
function(feature) {
|
||||
goog.asserts.assert(goog.isDef(styleFunction));
|
||||
var dirty = this.renderFeature(
|
||||
feature, resolution, pixelRatio, styleFunction, replayGroup);
|
||||
this.dirty_ = this.dirty_ || dirty;
|
||||
var styles;
|
||||
if (goog.isDef(feature.getStyleFunction())) {
|
||||
styles = feature.getStyleFunction().call(feature, resolution);
|
||||
} else if (goog.isDef(vectorLayer.getStyleFunction())) {
|
||||
styles = vectorLayer.getStyleFunction()(feature, resolution);
|
||||
}
|
||||
if (goog.isDefAndNotNull(styles)) {
|
||||
var dirty = this.renderFeature(
|
||||
feature, resolution, pixelRatio, styles, replayGroup);
|
||||
this.dirty_ = this.dirty_ || dirty;
|
||||
}
|
||||
};
|
||||
if (!goog.isNull(vectorLayerRenderOrder)) {
|
||||
/** @type {Array.<ol.Feature>} */
|
||||
@@ -252,13 +254,12 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.feature.StyleFunction} styleFunction Style function.
|
||||
* @param {Array.<ol.style.Style>} styles Array of styles
|
||||
* @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
|
||||
* @return {boolean} `true` if an image is loading.
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.renderFeature =
|
||||
function(feature, resolution, pixelRatio, styleFunction, replayGroup) {
|
||||
var styles = styleFunction(feature, resolution);
|
||||
function(feature, resolution, pixelRatio, styles, replayGroup) {
|
||||
if (!goog.isDefAndNotNull(styles)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ goog.require('ol.ImageBase');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
goog.require('ol.source.Image');
|
||||
@@ -89,8 +90,15 @@ ol.renderer.dom.ImageLayer.prototype.prepareFrame =
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING]) {
|
||||
var image_ = imageSource.getImage(frameState.extent, viewResolution,
|
||||
var renderedExtent = frameState.extent;
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
renderedExtent = ol.extent.getIntersection(
|
||||
renderedExtent, layerState.extent);
|
||||
}
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
|
||||
!ol.extent.isEmpty(renderedExtent)) {
|
||||
var image_ = imageSource.getImage(renderedExtent, viewResolution,
|
||||
frameState.pixelRatio, viewState.projection);
|
||||
if (!goog.isNull(image_)) {
|
||||
var imageState = image_.getState();
|
||||
|
||||
@@ -109,6 +109,11 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
} else {
|
||||
extent = frameState.extent;
|
||||
}
|
||||
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
extent = ol.extent.getIntersection(extent, layerState.extent);
|
||||
}
|
||||
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
extent, tileResolution);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.renderer.Layer');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.TileState');
|
||||
@@ -160,7 +161,13 @@ ol.renderer.Layer.prototype.updateAttributions =
|
||||
ol.renderer.Layer.prototype.updateLogos = function(frameState, source) {
|
||||
var logo = source.getLogo();
|
||||
if (goog.isDef(logo)) {
|
||||
frameState.logos[logo] = '';
|
||||
if (goog.isString(logo)) {
|
||||
frameState.logos[logo] = '';
|
||||
} else if (goog.isObject(logo)) {
|
||||
goog.asserts.assertString(logo.href);
|
||||
goog.asserts.assertString(logo.src);
|
||||
frameState.logos[logo.src] = logo.href;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ goog.require('ol.Extent');
|
||||
goog.require('ol.ImageBase');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.renderer.webgl.Layer');
|
||||
goog.require('ol.source.Image');
|
||||
@@ -119,8 +120,14 @@ ol.renderer.webgl.ImageLayer.prototype.prepareFrame =
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING]) {
|
||||
var image_ = imageSource.getImage(frameState.extent, viewResolution,
|
||||
var renderedExtent = frameState.extent;
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
renderedExtent = ol.extent.getIntersection(
|
||||
renderedExtent, layerState.extent);
|
||||
}
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
|
||||
!ol.extent.isEmpty(renderedExtent)) {
|
||||
var image_ = imageSource.getImage(renderedExtent, viewResolution,
|
||||
frameState.pixelRatio, viewState.projection);
|
||||
if (!goog.isNull(image_)) {
|
||||
var imageState = image_.getState();
|
||||
|
||||
@@ -207,11 +207,18 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
var allTilesLoaded = true;
|
||||
var tmpExtent = ol.extent.createEmpty();
|
||||
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
|
||||
var childTileRange, fullyLoaded, tile, tileState, x, y;
|
||||
var childTileRange, fullyLoaded, tile, tileState, x, y, tileExtent;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
if (goog.isDef(layerState.extent)) {
|
||||
// ignore tiles outside layer extent
|
||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||
if (!ol.extent.intersects(tileExtent, layerState.extent)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.LOADED) {
|
||||
if (mapRenderer.isTileTextureLoaded(tile)) {
|
||||
@@ -243,7 +250,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number);
|
||||
goog.array.sort(zs);
|
||||
var u_tileOffset = goog.vec.Vec4.createFloat32();
|
||||
var i, ii, sx, sy, tileExtent, tileKey, tilesToDraw, tx, ty;
|
||||
var i, ii, sx, sy, tileKey, tilesToDraw, tx, ty;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
tilesToDraw = tilesToDrawByZ[zs[i]];
|
||||
for (tileKey in tilesToDraw) {
|
||||
|
||||
@@ -74,6 +74,13 @@ ol.DebugTile_.prototype.getImage = function(opt_context) {
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A pseudo tile source, which does not fetch tiles from a server, but renders
|
||||
* a grid outline for the tile grid/projection along with the coordinates for
|
||||
* each tile. See examples/canvas-tiles for an example.
|
||||
*
|
||||
* Uses Canvas context2d, so requires Canvas support.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.source.Tile}
|
||||
* @param {olx.source.TileDebugOptions} options Debug tile options.
|
||||
@@ -82,7 +89,6 @@ ol.DebugTile_.prototype.getImage = function(opt_context) {
|
||||
ol.source.TileDebug = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
extent: options.extent,
|
||||
opaque: false,
|
||||
projection: options.projection,
|
||||
tileGrid: options.tileGrid
|
||||
|
||||
@@ -33,7 +33,6 @@ ol.source.FormatVector = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: options.projection
|
||||
});
|
||||
|
||||
@@ -20,7 +20,6 @@ ol.source.ImageCanvas = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions,
|
||||
|
||||
@@ -11,7 +11,7 @@ goog.require('ol.source.Source');
|
||||
/**
|
||||
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
|
||||
* extent: (null|ol.Extent|undefined),
|
||||
* logo: (string|undefined),
|
||||
* logo: (string|olx.LogoOptions|undefined),
|
||||
* projection: ol.proj.ProjectionLike,
|
||||
* resolutions: (Array.<number>|undefined),
|
||||
* state: (ol.source.State|string|undefined)}}
|
||||
|
||||
@@ -31,7 +31,6 @@ ol.source.ImageStatic = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: attributions,
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: projection,
|
||||
resolutions: [imageResolution]
|
||||
|
||||
@@ -6,11 +6,11 @@ goog.require('goog.events.EventType');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.feature');
|
||||
goog.require('ol.render.canvas.ReplayGroup');
|
||||
goog.require('ol.renderer.vector');
|
||||
goog.require('ol.source.ImageCanvas');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.vec.Mat4');
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ ol.source.ImageVector = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!ol.feature.StyleFunction}
|
||||
* @type {!ol.style.StyleFunction}
|
||||
*/
|
||||
this.styleFunction_ = goog.isDef(options.style) ?
|
||||
ol.feature.createStyleFunction(options.style) :
|
||||
ol.feature.defaultStyleFunction;
|
||||
this.styleFunction_ = goog.isDefAndNotNull(options.style) ?
|
||||
ol.style.createStyleFunction(options.style) :
|
||||
ol.style.defaultStyleFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -75,7 +75,6 @@ ol.source.ImageVector = function(options) {
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
canvasFunction: goog.bind(this.canvasFunctionInternal_, this),
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: options.projection,
|
||||
ratio: options.ratio,
|
||||
|
||||
@@ -31,7 +31,6 @@ ol.source.ImageWMS = function(opt_options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
logo: options.logo,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions
|
||||
|
||||
@@ -22,7 +22,6 @@ ol.source.KML = function(opt_options) {
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
doc: options.doc,
|
||||
extent: options.extent,
|
||||
format: new ol.format.KML({
|
||||
defaultStyle: options.defaultStyle
|
||||
}),
|
||||
|
||||
@@ -21,7 +21,6 @@ goog.require('ol.source.Image');
|
||||
ol.source.MapGuide = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
extent: options.extent,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions
|
||||
});
|
||||
@@ -55,6 +54,12 @@ ol.source.MapGuide = function(options) {
|
||||
*/
|
||||
this.imageUrlFunction_ = imageUrlFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
this.params_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -87,10 +92,27 @@ ol.source.MapGuide = function(options) {
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedRevision_ = 0;
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.MapGuide, ol.source.Image);
|
||||
|
||||
|
||||
/**
|
||||
* Get the user-provided params, i.e. those passed to the constructor through
|
||||
* the "params" option, and possibly updated using the updateParams method.
|
||||
* @return {Object} Params.
|
||||
* @api
|
||||
*/
|
||||
ol.source.MapGuide.prototype.getParams = function() {
|
||||
return this.params_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -101,6 +123,7 @@ ol.source.MapGuide.prototype.getImage =
|
||||
|
||||
var image = this.image_;
|
||||
if (!goog.isNull(image) &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
ol.extent.containsExtent(image.getExtent(), extent)) {
|
||||
@@ -123,6 +146,7 @@ ol.source.MapGuide.prototype.getImage =
|
||||
image = null;
|
||||
}
|
||||
this.image_ = image;
|
||||
this.renderedRevision_ = this.getRevision();
|
||||
|
||||
return image;
|
||||
};
|
||||
@@ -149,6 +173,17 @@ ol.source.MapGuide.getScale = function(extent, size, metersPerUnit, dpi) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the user-provided params.
|
||||
* @param {Object} params Params.
|
||||
* @api
|
||||
*/
|
||||
ol.source.MapGuide.prototype.updateParams = function(params) {
|
||||
goog.object.extend(this.params_, params);
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} baseUrl The mapagent url.
|
||||
* @param {Object.<string, string|number>} params Request parameters.
|
||||
|
||||
@@ -22,7 +22,6 @@ ol.source.OSMXML = function(opt_options) {
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
doc: options.doc,
|
||||
extent: options.extent,
|
||||
format: new ol.format.OSMXML(),
|
||||
logo: options.logo,
|
||||
node: options.node,
|
||||
|
||||
@@ -23,7 +23,6 @@ ol.source.ServerVector = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
format: options.format,
|
||||
logo: options.logo,
|
||||
projection: options.projection
|
||||
|
||||
@@ -22,8 +22,7 @@ ol.source.State = {
|
||||
|
||||
/**
|
||||
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
|
||||
* extent: (ol.Extent|undefined),
|
||||
* logo: (string|undefined),
|
||||
* logo: (string|olx.LogoOptions|undefined),
|
||||
* projection: ol.proj.ProjectionLike,
|
||||
* state: (ol.source.State|string|undefined)}}
|
||||
*/
|
||||
@@ -52,14 +51,6 @@ ol.source.Source = function(options) {
|
||||
*/
|
||||
this.projection_ = ol.proj.get(options.projection);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.extent_ = goog.isDef(options.extent) ?
|
||||
options.extent : goog.isDef(options.projection) ?
|
||||
this.projection_.getExtent() : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.Attribution>}
|
||||
@@ -69,7 +60,7 @@ ol.source.Source = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
* @type {string|olx.LogoOptions|undefined}
|
||||
*/
|
||||
this.logo_ = options.logo;
|
||||
|
||||
@@ -107,15 +98,7 @@ ol.source.Source.prototype.getAttributions = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent} Extent.
|
||||
*/
|
||||
ol.source.Source.prototype.getExtent = function() {
|
||||
return this.extent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string|undefined} Logo.
|
||||
* @return {string|olx.LogoOptions|undefined} Logo.
|
||||
*/
|
||||
ol.source.Source.prototype.getLogo = function() {
|
||||
return this.logo_;
|
||||
@@ -154,15 +137,7 @@ ol.source.Source.prototype.setAttributions = function(attributions) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
*/
|
||||
ol.source.Source.prototype.setExtent = function(extent) {
|
||||
this.extent_ = extent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|undefined} logo Logo.
|
||||
* @param {string|olx.LogoOptions|undefined} logo Logo.
|
||||
*/
|
||||
ol.source.Source.prototype.setLogo = function(logo) {
|
||||
this.logo_ = logo;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user