├── Gruntfile.js
├── examples
├── images
│ ├── gizah.jpg
│ ├── icon.png
│ ├── eiffel.jpg
│ ├── marker.png
│ ├── map-marker.png
│ ├── notredame.jpg
│ └── versailles.jpg
├── json
│ ├── LIS.geo.json
│ ├── README
│ ├── paths.json
│ ├── PRT.geo.json
│ ├── ESP.geo.json
│ ├── FRA.geo.json
│ ├── JPN.geo.json
│ ├── ITA.geo.json
│ └── features.json
├── 026-center-no-javascript-example.html
├── 010-simple-example.html
├── 056-layers-no-javascript-example.html
├── 066-markers-with-layers-no-javascript-example.html
├── 060-marker-example.html
├── 110-path-example.html
├── 020-center-example.html
├── 022-center-autodiscover-example.html
├── 053-layers-image-wms-example.html
├── 023-center-constrain-zoom-example.html
├── 052-heatmap-example.html
├── 062-markers-label-example.html
├── 044-layers-mapquest-maps-example.html
├── 070-view-rotation-example.html
├── 047-layers-topojson-example.html
├── 111-layer-tile-vector-example.html
├── 085-events-kml-example.html
├── 048-layers-static-image-example.html
├── 049-layers-stamen-example.html
├── 050-layer-geojson-change-style-example.html
├── 041-layers-zoom-tiles-changer-example.html
├── 102-controls-measure-example.html
├── 024-center-bounds-example.html
├── 101-controls-fullscreen-example.html
├── 030-custom-parameters-example.html
├── 021-center-url-hash-example.html
├── 046-layers-geojson-center-example.html
├── 112-layers-esri-basemaps-example.html
├── 043-layers-bing-maps-example.html
├── 105-controls-overviewmap-example.html
├── 084-events-add-markers-on-click-example.html
├── 061-markers-add-remove-example.html
├── 051-layer-geojson-change-style-with-function-example.html
├── 057-layers-wmts-example.html
├── 067-marker-custom-icon-example.html
├── 083-events-static-image-layer-example.html
├── 042-layers-opacity-example.html
├── 055-layers-geojon-dynamic-load-example.html
├── 065-markers-static-image-layer-example.html
├── 100-controls-example.html
├── 025-center-projections-example.html
├── 120-custom-layer-and-projection-example.html
├── 113-layers-image-wms-with-attribution-example.html
├── 104-controls-options-example.html
├── 103-controls-custom-example.html
├── 058-layers-geojson-style-function.html
├── 081-events-vector-example.html
├── 054-add-remove-multiple-layers-example.html
├── 080-events-propagation-example.html
├── 063-markers-properties-example.html
├── 064-markers-render-html-inside-labels-example.html
├── 045-layers-geojson-example.html
├── 059-layer-clustering.html
├── 040-layers-change-tiles-example.html
├── 086-events-multi-layer-vector-example.html
└── 090-multiple-maps-example.html
├── grunt
├── changelog.js
├── pkg.js
├── jscs.js
├── coveralls.js
├── open.js
├── bower.js
├── ngAnnotate.js
├── uglify.js
├── bump.js
├── watch.js
├── shell.js
├── protractor.js
├── connect.js
├── aliases.yaml
├── karma.js
├── jshint.js
└── concat.js
├── .npmignore
├── .gitignore
├── CHANGELOG.md
├── .jscsrc
├── .editorconfig
├── .travis.yml
├── test
├── e2e
│ ├── 010-simple-example.js
│ └── 020-center-example.js
├── unit
│ ├── markerSpec.js
│ ├── viewSpec.js
│ ├── controlsSpec.js
│ ├── helperSpec.js
│ ├── openlayersSpec.js
│ └── centerSpec.js
└── protractor.conf.js
├── css
├── openlayers.css
└── markers.css
├── bower.json
├── LICENSE
├── src
├── header-MIT-license.txt
├── directives
│ ├── view.js
│ ├── path.js
│ ├── control.js
│ └── openlayers.js
└── services
│ └── olData.js
├── doc
├── 03-defaults-attribute.md
├── 04-layers-attribute.md
├── 02-center-attribute.md
└── 01-openlayers-directive.md
└── package.json
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | require('load-grunt-config')(grunt);
3 | };
4 |
--------------------------------------------------------------------------------
/examples/images/gizah.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/gizah.jpg
--------------------------------------------------------------------------------
/examples/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/icon.png
--------------------------------------------------------------------------------
/grunt/changelog.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/examples/images/eiffel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/eiffel.jpg
--------------------------------------------------------------------------------
/examples/images/marker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/marker.png
--------------------------------------------------------------------------------
/examples/images/map-marker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/map-marker.png
--------------------------------------------------------------------------------
/examples/images/notredame.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/notredame.jpg
--------------------------------------------------------------------------------
/examples/images/versailles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tombatossals/angular-openlayers-directive/HEAD/examples/images/versailles.jpg
--------------------------------------------------------------------------------
/grunt/pkg.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return grunt.file.readJSON('package.json');
5 | };
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | doc/
3 | grunt/
4 | examples/
5 | test/
6 | *.md
7 | Gruntfile.js
8 | .travis.yml
9 | package.json
10 | bower.json
11 | node_modules
12 | bower_components
--------------------------------------------------------------------------------
/examples/json/LIS.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"PRT","properties":{"name":"Lisbon"},"geometry":{"type":"Point","coordinates":[-9.394, 38.7139]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/examples/json/README:
--------------------------------------------------------------------------------
1 | countries.geo.json: https://raw.github.com/johan/world.geo.json/master/countries.geo.json
2 | all.json: https://raw.github.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/all/all.json
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib
2 | temp
3 | node_modules/
4 | bower_components/
5 | dist/
6 | libpeerconnection.log
7 | *.swp
8 | .*.swp
9 | *.iml
10 | .idea
11 | .project
12 | selenium
13 | coverage
14 | *.log
15 | .vscode
16 |
--------------------------------------------------------------------------------
/grunt/jscs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | jscs: {
6 | src: [ "src/**/*.js", "test/**/*.js" ]
7 | }
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/grunt/coveralls.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | // Options
5 | return {
6 | options: {
7 | debug: true,
8 | coverage_dir: 'coverage'
9 | }
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/grunt/open.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | devserver: {
6 | path: 'http://localhost:8888'
7 | },
8 | coverage: {
9 | path: 'http://localhost:5555'
10 | }
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/grunt/bower.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | install: {
6 | // options: {
7 | // targetDir: './bower_components',
8 | // cleanup: true
9 | // }
10 | }
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/grunt/ngAnnotate.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function ngAnnotate(grunt, options) {
4 | return {
5 | options: {},
6 | dist: {
7 | files: {
8 | 'dist/angular-openlayers-directive.js': [ 'dist/angular-openlayers-directive.pre.js' ]
9 | }
10 | }
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | angular-openlayers-directive changelog
2 | ---
3 |
4 | Hi, we've fully automated our release. Even the changelog which you can find under the [release](https://github.com/tombatossals/angular-openlayers-directive/releases) tab of our GitHub repo.
5 |
6 | You can automate your library as well. It's easy: [Release your libs like a pro](http://juristr.com/blog/2015/10/release-like-a-pro/)
7 |
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "preset": "google",
3 | "fileExtensions": [ ".js", "jscs" ],
4 |
5 | "requireParenthesesAroundIIFE": true,
6 | "maximumLineLength": 120,
7 | "validateIndentation": 4,
8 |
9 | "disallowKeywords": ["with"],
10 | "disallowSpacesInsideObjectBrackets": null,
11 | "disallowImplicitTypeConversion": ["string"],
12 |
13 | "safeContextKeyword": "_this"
14 | }
15 |
--------------------------------------------------------------------------------
/grunt/uglify.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
7 | },
8 | dist: {
9 | files: {
10 | 'dist/<%= pkg.name %>.min.no-header.js': ['dist/angular-openlayers-directive.js']
11 | }
12 | }
13 | };
14 | };
15 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 4
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | cache:
4 | directories:
5 | - node_modules
6 | branches:
7 | only:
8 | - master
9 | notifications:
10 | email: false
11 | node_js:
12 | - '6.1'
13 | before_install:
14 | - npm i -g npm@^2.0.0
15 | - npm install -g grunt-cli
16 | - npm install -g bower
17 | - bower install
18 | - npm install
19 | before_script:
20 | - npm prune
21 | after_success:
22 | - npm run semantic-release
23 |
--------------------------------------------------------------------------------
/test/e2e/010-simple-example.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | describe('Loading 010-simple-example.html', function() {
3 |
4 | beforeEach(function() {
5 | browser.get('/examples/010-simple-example.html');
6 | }, 30000);
7 |
8 | it('should load the Openlayers map inside the directive tag', function() {
9 | element(by.className('angular-openlayers-map')).getText().then(function(text) {
10 | expect(text).toBe('+\n−');
11 | });
12 | });
13 |
14 | });
15 |
--------------------------------------------------------------------------------
/test/e2e/020-center-example.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | describe('Loading 020-center-example.html', function() {
3 |
4 | beforeEach(function() {
5 | browser.get('/examples/020-center-example.html');
6 | }, 30000);
7 |
8 | it('should update the zoom value in the input if clicked the zoom control', function() {
9 | element(by.className('ol-zoom-in')).click();
10 | // Wait for zoom animation
11 | browser.sleep(300);
12 | expect(element(by.model('london.zoom')).getAttribute('value')).toBe('5');
13 | });
14 |
15 | });
16 |
--------------------------------------------------------------------------------
/css/openlayers.css:
--------------------------------------------------------------------------------
1 | .angular-openlayers-map:-moz-full-screen {
2 | height: 100%;
3 | }
4 | .angular-openlayers-map:-webkit-full-screen {
5 | height: 100%;
6 | }
7 | .angular-openlayers-map:full-screen {
8 | height: 100%;
9 | }
10 |
11 | .angular-openlayers-map:not(-moz-full-screen) {
12 | height: 400px;
13 | }
14 |
15 | .angular-openlayers-map:not(-webkit-full-screen) {
16 | height: 400px;
17 | }
18 |
19 | .angular-openlayers-map:not(full-screen) {
20 | height: 400px;
21 | }
22 | .ol-full-screen {
23 | position: absolute;
24 | top: 50%;
25 | }
26 |
--------------------------------------------------------------------------------
/grunt/bump.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | files: ['package.json'],
7 | updateConfigs: [],
8 | commit: true,
9 | commitMessage: 'Release v%VERSION%',
10 | commitFiles: ['package.json'],
11 | createTag: true,
12 | tagName: 'v%VERSION%',
13 | tagMessage: 'Version %VERSION%',
14 | push: true,
15 | pushTo: 'origin',
16 | gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d'
17 | }
18 | };
19 | };
20 |
--------------------------------------------------------------------------------
/grunt/watch.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options : {
6 | livereload: 7777
7 | },
8 | source: {
9 | files: ['src/**/*.js', 'test/unit/**.js', 'test/e2e/**.js', 'css/*.css'],
10 | tasks: [
11 | 'jshint',
12 | 'jscs',
13 | 'concat:dist',
14 | 'concat:css',
15 | 'ngAnnotate',
16 | 'uglify',
17 | 'test-unit',
18 | 'concat:license'
19 | ]
20 | }
21 | };
22 | };
23 |
--------------------------------------------------------------------------------
/grunt/shell.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | stdout: true
7 | },
8 | selenium: {
9 | command: 'node node_modules/protractor/bin/webdriver-manager start',
10 | options: {
11 | stdout: false,
12 | async: true
13 | }
14 | },
15 | protractor_update: {
16 | command: 'node node_modules/protractor/bin/webdriver-manager update'
17 | },
18 | npm_install: {
19 | command: 'npm install'
20 | }
21 | };
22 | };
23 |
--------------------------------------------------------------------------------
/examples/json/paths.json:
--------------------------------------------------------------------------------
1 | {
2 | "p1": {
3 | "color": "red",
4 | "weight": 8,
5 | "latlngs": [
6 | { "lat": 51.50, "lng": -0.082 },
7 | { "lat": 48.83, "lng": 2.37 },
8 | { "lat": 41.91, "lng": 12.48 }
9 | ],
10 | "message": "
Route from London to Rome Distance: 1862km
"
11 | },
12 | "p2": {
13 | "color": "green",
14 | "weight": 8,
15 | "latlngs": [
16 | { "lat": 48.2083537, "lng": 16.3725042 },
17 | { "lat": 48.8534, "lng": 2.3485 }
18 | ],
19 | "label": { "message": "Route from Vienna to Paris Distance: 1211km
"}
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/grunt/protractor.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | keepAlive: false,
7 | configFile: 'test/protractor.conf.js',
8 | args: {
9 | specs: [ 'test/e2e/*.js' ],
10 | }
11 | },
12 | run: {},
13 | saucelabs: {
14 | options: {
15 | args: {
16 | baseUrl: "http://tombatossals.github.io/angular-openlayers-directive/examples/",
17 | sauceUser: process.env.SAUCE_USERNAME,
18 | sauceKey: process.env.SAUCE_ACCESS_KEY
19 | }
20 | }
21 | }
22 | };
23 | };
24 |
--------------------------------------------------------------------------------
/examples/026-center-no-javascript-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 | Centering map with no javascript example
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/unit/markerSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | describe('Directive: openlayers marker', function() {
7 | var $compile = null;
8 | var scope;
9 |
10 | beforeEach(module('openlayers-directive'));
11 | beforeEach(inject(function(_$compile_, $rootScope) {
12 | $compile = _$compile_;
13 |
14 | scope = $rootScope.$new();
15 | }));
16 |
17 | it('should not error on $scope.$destroy', function() {
18 | var element = angular.element(' ');
19 | element = $compile(element)(scope);
20 | scope.$digest();
21 | expect(function() { scope.$destroy(); }).not.toThrow();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/grunt/connect.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | base: ''
7 | },
8 | webserver: {
9 | options: {
10 | port: 8888,
11 | keepalive: true
12 | }
13 | },
14 | devserver: {
15 | options: {
16 | port: 8888
17 | }
18 | },
19 | testserver: {
20 | options: {
21 | port: 9999
22 | }
23 | },
24 | coverage: {
25 | options: {
26 | base: 'coverage/',
27 | directory: 'coverage/',
28 | port: 5555,
29 | keepalive: true
30 | }
31 | }
32 | };
33 | };
34 |
--------------------------------------------------------------------------------
/examples/010-simple-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 | Simple example
16 | Showing a simple map on your DOM requires almost no code. Look at the source code of this page.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/json/PRT.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"PRT","properties":{"name":"Portugal"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.671946,42.134689],[-8.263857,42.280469],[-8.013175,41.790886],[-7.422513,41.792075],[-7.251309,41.918346],[-6.668606,41.883387],[-6.389088,41.381815],[-6.851127,41.111083],[-6.86402,40.330872],[-7.026413,40.184524],[-7.066592,39.711892],[-7.498632,39.629571],[-7.098037,39.030073],[-7.374092,38.373059],[-7.029281,38.075764],[-7.166508,37.803894],[-7.537105,37.428904],[-7.453726,37.097788],[-7.855613,36.838269],[-8.382816,36.97888],[-8.898857,36.868809],[-8.746101,37.651346],[-8.839998,38.266243],[-9.287464,38.358486],[-9.526571,38.737429],[-9.446989,39.392066],[-9.048305,39.755093],[-8.977353,40.159306],[-8.768684,40.760639],[-8.790853,41.184334],[-8.990789,41.543459],[-9.034818,41.880571]]]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/css/markers.css:
--------------------------------------------------------------------------------
1 | .popup-label {
2 | background-color: #fff;
3 | border: 2px #444 solid;
4 | border-radius: 7px;
5 | -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
6 | -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
7 | box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
8 | color: #111;
9 | font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
10 | font-weight: bold;
11 | padding: 3px 6px;
12 | position: absolute;
13 | white-space: nowrap;
14 | top: -35px;
15 | left: 20px;
16 | display: none;
17 | }
18 |
19 | .popup-label img {
20 | vertical-align: middle;
21 | }
22 |
23 | .popup-label.marker:before {
24 | border-top: 6px solid transparent;
25 | border-bottom: 6px solid transparent;
26 | content: "";
27 | border-right: 6px solid black;
28 | border-right-color: inherit;
29 | position: absolute;
30 | left: -8px;
31 | top: 5px;
32 | }
33 |
--------------------------------------------------------------------------------
/examples/056-layers-no-javascript-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 | Adding a layer with no javascript example
18 |
19 |
20 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-openlayers-directive",
3 | "description": "AngularJS directive to embed an interact with maps managed by OpenLayers library",
4 | "keywords": [
5 | "angularjs",
6 | "javascript",
7 | "directive",
8 | "openlayers"
9 | ],
10 | "main": [
11 | "dist/angular-openlayers-directive.min.js"
12 | ],
13 | "dependencies": {
14 | "angular": "1.4.9",
15 | "angular-sanitize": "1.4.9",
16 | "openlayers": "https://github.com/openlayers/ol3/releases/download/v4.3.4/v4.3.4-dist.zip"
17 | },
18 | "devDependencies": {
19 | "jquery": "*",
20 | "angular-route": "1.4.9",
21 | "angular-mocks": "1.4.9",
22 | "js-polyfills": "^0.1.20"
23 | },
24 | "ignore": [
25 | "**/.*",
26 | "src",
27 | "doc",
28 | "grunt",
29 | "examples",
30 | "test",
31 | "*.md",
32 | "Gruntfile.js",
33 | "package.json",
34 | "bower.json",
35 | "node_modules",
36 | "bower_components"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/grunt/aliases.yaml:
--------------------------------------------------------------------------------
1 | test:
2 | - 'jshint'
3 | - 'test-unit'
4 | - 'test-e2e'
5 |
6 | test-unit:
7 | - 'karma:unit'
8 |
9 | test-e2e:
10 | - 'shell:protractor_update'
11 | - 'connect:testserver'
12 | - 'protractor:run'
13 |
14 | test-e2e-firefox:
15 | - 'shell:protractor_update'
16 | - 'connect:testserver'
17 | - 'protractor:firefox'
18 |
19 | test-coverage:
20 | - 'karma:unit_coverage'
21 |
22 | coverage:
23 | - 'karma:unit_coverage'
24 | - 'open:coverage'
25 | - 'connect:coverage'
26 |
27 | install:
28 | - 'shell:npm_install'
29 | - 'bower:install'
30 | - 'shell:protractor_update'
31 |
32 | default:
33 | - 'build'
34 |
35 | dev:
36 | - 'connect:devserver'
37 | - 'open:devserver'
38 | - 'watch:source'
39 |
40 | serve:
41 | - 'connect:webserver'
42 |
43 | build:
44 | - 'jshint'
45 | - 'jscs'
46 | - 'concat:dist'
47 | - 'concat:css'
48 | - 'ngAnnotate'
49 | - 'uglify'
50 | - 'test-unit'
51 | - 'concat:license'
52 |
53 | travis:
54 | - 'bower:install'
55 | - 'test-unit'
56 |
--------------------------------------------------------------------------------
/examples/066-markers-with-layers-no-javascript-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Adding a layer with markers with no javascript example
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2012-2013 https://github.com/tombatossals/angular-openlayers-directive
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/examples/json/ESP.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"ESP","properties":{"name":"Spain"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.984433,42.592775],[-9.392884,43.026625],[-7.97819,43.748338],[-6.754492,43.567909],[-5.411886,43.57424],[-4.347843,43.403449],[-3.517532,43.455901],[-1.901351,43.422802],[-1.502771,43.034014],[0.338047,42.579546],[0.701591,42.795734],[1.826793,42.343385],[2.985999,42.473015],[3.039484,41.89212],[2.091842,41.226089],[0.810525,41.014732],[0.721331,40.678318],[0.106692,40.123934],[-0.278711,39.309978],[0.111291,38.738514],[-0.467124,38.292366],[-0.683389,37.642354],[-1.438382,37.443064],[-2.146453,36.674144],[-3.415781,36.6589],[-4.368901,36.677839],[-4.995219,36.324708],[-5.37716,35.94685],[-5.866432,36.029817],[-6.236694,36.367677],[-6.520191,36.942913],[-7.453726,37.097788],[-7.537105,37.428904],[-7.166508,37.803894],[-7.029281,38.075764],[-7.374092,38.373059],[-7.098037,39.030073],[-7.498632,39.629571],[-7.066592,39.711892],[-7.026413,40.184524],[-6.86402,40.330872],[-6.851127,41.111083],[-6.389088,41.381815],[-6.668606,41.883387],[-7.251309,41.918346],[-7.422513,41.792075],[-8.013175,41.790886],[-8.263857,42.280469],[-8.671946,42.134689],[-9.034818,41.880571]]]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/examples/060-marker-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
23 |
24 |
25 |
26 |
27 | Adding a marker to the map
28 | You can add a marker to the map easily with the ol-marker sub-directive.
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/json/FRA.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"FRA","properties":{"name":"France"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.560016,42.152492],[9.229752,41.380007],[8.775723,41.583612],[8.544213,42.256517],[8.746009,42.628122],[9.390001,43.009985],[9.560016,42.152492]]],[[[3.588184,50.378992],[4.286023,49.907497],[4.799222,49.985373],[5.674052,49.529484],[5.897759,49.442667],[6.18632,49.463803],[6.65823,49.201958],[8.099279,49.017784],[7.593676,48.333019],[7.466759,47.620582],[7.192202,47.449766],[6.736571,47.541801],[6.768714,47.287708],[6.037389,46.725779],[6.022609,46.27299],[6.5001,46.429673],[6.843593,45.991147],[6.802355,45.70858],[7.096652,45.333099],[6.749955,45.028518],[7.007562,44.254767],[7.549596,44.127901],[7.435185,43.693845],[6.529245,43.128892],[4.556963,43.399651],[3.100411,43.075201],[2.985999,42.473015],[1.826793,42.343385],[0.701591,42.795734],[0.338047,42.579546],[-1.502771,43.034014],[-1.901351,43.422802],[-1.384225,44.02261],[-1.193798,46.014918],[-2.225724,47.064363],[-2.963276,47.570327],[-4.491555,47.954954],[-4.59235,48.68416],[-3.295814,48.901692],[-1.616511,48.644421],[-1.933494,49.776342],[-0.989469,49.347376],[1.338761,50.127173],[1.639001,50.946606],[2.513573,51.148506],[2.658422,50.796848],[3.123252,50.780363],[3.588184,50.378992]]]]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/examples/110-path-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Adding a path to the map
22 | You can add a path to the map easily with the ol-path sub-directive.
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/020-center-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 |
23 |
24 | Center map example
25 |
30 | Center object
31 | {{ london | json }}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/examples/022-center-autodiscover-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 |
23 |
24 | Center autodiscover example
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/examples/053-layers-image-wms-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | WMS Image Layer
35 | This map uses a WMS image layer from a geoserver.
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/header-MIT-license.txt:
--------------------------------------------------------------------------------
1 | /**!
2 | * The MIT License
3 | *
4 | * Copyright (c) 2013 the angular-openlayers-directive Team, http://tombatossals.github.io/angular-openlayers-directive
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | *
24 | * angular-google-maps
25 | * https://github.com/tombatossals/angular-openlayers-directive
26 | *
27 | * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors
28 | */
29 |
--------------------------------------------------------------------------------
/grunt/karma.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | module.exports = function (grunt, options) {
5 | return {
6 | unit: {
7 | frameworks: ['jasmine'],
8 | browsers: ['PhantomJS'],
9 | singleRun: true,
10 | options: {
11 | files: [
12 | 'bower_components/openlayers/ol-debug.js',
13 | 'bower_components/js-polyfills/polyfill.js',
14 | 'bower_components/angular/angular.js',
15 | 'bower_components/angular-sanitize/angular-sanitize.js',
16 | 'bower_components/angular-mocks/angular-mocks.js',
17 | 'dist/angular-openlayers-directive.js',
18 | 'test/unit/*.js'
19 | ]
20 | }
21 | },
22 | dev: {
23 | frameworks: ['jasmine'],
24 | browsers: ['Chrome', 'IE'],
25 | singleRun: false,
26 | autoWatch: true,
27 | options: {
28 | files: [
29 | 'bower_components/openlayers/ol-debug.js',
30 | 'bower_components/js-polyfills/polyfill.js',
31 | 'bower_components/angular/angular.js',
32 | 'bower_components/angular-sanitize/angular-sanitize.js',
33 | 'bower_components/angular-mocks/angular-mocks.js',
34 | 'dist/angular-openlayers-directive.js',
35 | 'test/unit/*.js'
36 | ]
37 | }
38 | }
39 | };
40 | };
41 |
--------------------------------------------------------------------------------
/examples/023-center-constrain-zoom-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
27 |
28 |
29 |
30 | Constrain zoom map example
31 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/doc/03-defaults-attribute.md:
--------------------------------------------------------------------------------
1 | 'Defaults' Attribute Documentation
2 | ==================================
3 |
4 | This sub-directive needs the **openlayers** main directive, so it is normaly used as an attribute of the *openlayers* tag, like this:
5 |
6 | ```
7 |
8 | ```
9 |
10 | It will define the default parameters from which we want to initialize our map. It's not used as a bi-directional attribute, so it will only apply the initial map parameters and nothing more. Let's see its possibilities.
11 |
12 | We can define some custom parameters that apply to the Leaflet map creation. This is the list:
13 |
14 |
15 | Let's see an example of how to use this. First of all, in our controller, we will create a new object *defaults* inside the *$scope* where we will set the parameters that we want to change.
16 |
17 | ```
18 | angular.extend($scope, {
19 | defaults: {
20 | layer: {
21 | url: "http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"
22 | },
23 | interactions: {
24 | mouseWheelZoom: false
25 | },
26 | controls: {
27 | zoom: {
28 | position: 'topright'
29 | }
30 | }
31 | }
32 | });
33 | ```
34 |
35 | And after that, in our HTML code we will define our openlayers directive like this:
36 | ```
37 |
38 | ```
39 |
40 | And that's all. A full example of using this attribute can be found [here](http://tombatossals.github.io/angular-openlayers-directive/examples/030-custom-parameters-example.html).
41 |
--------------------------------------------------------------------------------
/examples/json/JPN.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"JPN","properties":{"name":"Japan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[134.638428,34.149234],[134.766379,33.806335],[134.203416,33.201178],[133.79295,33.521985],[133.280268,33.28957],[133.014858,32.704567],[132.363115,32.989382],[132.371176,33.463642],[132.924373,34.060299],[133.492968,33.944621],[133.904106,34.364931],[134.638428,34.149234]]],[[[140.976388,37.142074],[140.59977,36.343983],[140.774074,35.842877],[140.253279,35.138114],[138.975528,34.6676],[137.217599,34.606286],[135.792983,33.464805],[135.120983,33.849071],[135.079435,34.596545],[133.340316,34.375938],[132.156771,33.904933],[130.986145,33.885761],[132.000036,33.149992],[131.33279,31.450355],[130.686318,31.029579],[130.20242,31.418238],[130.447676,32.319475],[129.814692,32.61031],[129.408463,33.296056],[130.353935,33.604151],[130.878451,34.232743],[131.884229,34.749714],[132.617673,35.433393],[134.608301,35.731618],[135.677538,35.527134],[136.723831,37.304984],[137.390612,36.827391],[138.857602,37.827485],[139.426405,38.215962],[140.05479,39.438807],[139.883379,40.563312],[140.305783,41.195005],[141.368973,41.37856],[141.914263,39.991616],[141.884601,39.180865],[140.959489,38.174001],[140.976388,37.142074]]],[[[143.910162,44.1741],[144.613427,43.960883],[145.320825,44.384733],[145.543137,43.262088],[144.059662,42.988358],[143.18385,41.995215],[141.611491,42.678791],[141.067286,41.584594],[139.955106,41.569556],[139.817544,42.563759],[140.312087,43.333273],[141.380549,43.388825],[141.671952,44.772125],[141.967645,45.551483],[143.14287,44.510358],[143.910162,44.1741]]]]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/examples/052-heatmap-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
31 |
32 |
33 |
34 |
35 |
36 | Layers GeoJSON example
37 | You can load GeoJSON as new layers easily, look at the source of the layers attribute:
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/examples/062-markers-label-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
24 |
25 |
26 |
27 |
28 |
29 | Markers label example
30 | You can show a label on the marker adding a simple property to it, and it will be shown when you mouseover the marker. The style of the markers is the same used in Leaflet label , and you can personalize it with CSS.
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/doc/04-layers-attribute.md:
--------------------------------------------------------------------------------
1 | 'layers' Attribute Documentation
2 | ===================================
3 |
4 | This sub-directive needs the **openlayers** main directive, so it is normaly used as an attribute of the *openlayers* tag, like this:
5 |
6 | ```
7 |
8 | ```
9 |
10 | It will map an object _layers_ of our controller scope with the corresponding object on our leaflet directive isolated scope. It's not a bidirectional relationship, only the changes made to our _tiles_ object on the controller scope will affect the map, but no viceversa.
11 |
12 | This object defines the layers that integrate the map, so it's basically composed of three attributes: **type**, **url** and **attribution**. Let's see them in an example definition:
13 | ```
14 | $scope.layers = {
15 | main: {
16 | type: "tile",
17 | source: {
18 | type: "OSM",
19 | url: "http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",
20 | attribution: '© OpenStreetMap contributors'
21 | }
22 | }
23 | }
24 | ```
25 |
26 | And that's all, we can see how the map is affected when we change the _layers_ scope object values, like these examples:
27 |
28 | * [layers-change-tiles-example.html](http://tombatossals.github.io/angular-openlayers-directive/examples/040-layers-change-tiles-example.html).
29 | * [layers-zoom-tiles-changer-example.html](http://tombatossals.github.io/angular-openlayers-directive/examples/041-layers-zoom-tiles-changer-example.html).
30 | * [layers-opacity-example.html](http://tombatossals.github.io/angular-openlayers-directive/examples/042-layers-opacity-example.html).
31 |
--------------------------------------------------------------------------------
/examples/044-layers-mapquest-maps-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | MapQuest Layer
34 | This map uses a MapQuest source.
35 |
36 |
41 |
42 | Current TileLayer Url:
43 |
{{ layers | json }}
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/070-view-rotation-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
33 |
34 |
35 |
36 | View rotation example
37 | You can interact with the view rotation of your map.
38 |
39 | Degrees: {{ degrees }}
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/unit/viewSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | describe('Directive: openlayers', function() {
7 | var $compile = null;
8 | var $rootScope = null;
9 | var $timeout;
10 | var olData = null;
11 | var olMapDefaults = null;
12 | var scope;
13 |
14 | beforeEach(module('openlayers-directive'));
15 | beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _olData_, _olMapDefaults_) {
16 | $compile = _$compile_;
17 | $rootScope = _$rootScope_;
18 | $timeout = _$timeout_;
19 | olData = _olData_;
20 | olMapDefaults = _olMapDefaults_;
21 |
22 | scope = $rootScope.$new();
23 | }));
24 |
25 | afterEach(inject(function($rootScope) {
26 | $rootScope.$apply();
27 | }));
28 |
29 | it('should have loaded openlayers library inside the directive', function() {
30 | var element = angular.element(' ');
31 | element = $compile(element)(scope);
32 | var map;
33 | olData.getMap().then(function(olMap) {
34 | map = olMap;
35 | });
36 | scope.$digest();
37 | expect(map).toBeDefined();
38 | });
39 |
40 | it('should set default center if no center is provided', function() {
41 | var element = angular.element(' ');
42 | element = $compile(element)(scope);
43 | var map;
44 | olData.getMap().then(function(olMap) {
45 | map = olMap;
46 | });
47 | $rootScope.$digest();
48 | expect(map.getView().getZoom()).toEqual(1);
49 | expect(map.getView().getCenter()[0]).toBeCloseTo(0);
50 | expect(map.getView().getCenter()[1]).toBeCloseTo(0);
51 | });
52 |
53 | });
54 |
--------------------------------------------------------------------------------
/examples/047-layers-topojson-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
37 |
38 |
39 |
40 |
41 |
42 | Layers TopoJSON example
43 | You can load TopoJSON as new layers easily, look at the source of the layers attribute:
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/examples/111-layer-tile-vector-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
37 |
38 |
39 |
40 |
41 |
42 | Layers TileVector events example
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/grunt/jshint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt, options) {
4 | return {
5 | options: {
6 | node: true,
7 | browser: true,
8 | esnext: true,
9 | bitwise: true,
10 | curly: true,
11 | eqeqeq: true,
12 | immed: true,
13 | indent: 4,
14 | latedef: true,
15 | newcap: true,
16 | noarg: true,
17 | regexp: true,
18 | undef: true,
19 | unused: true,
20 | trailing: true,
21 | smarttabs: true,
22 | globals: {
23 | angular: false,
24 | ol: false,
25 | lvector: false,
26 | cartodb: false,
27 | // Jasmine
28 | jasmine : false,
29 | isCommonJS : false,
30 | exports : false,
31 | spyOn : false,
32 | it : false,
33 | xit : false,
34 | expect : false,
35 | runs : false,
36 | waits : false,
37 | waitsFor : false,
38 | beforeEach : false,
39 | afterEach : false,
40 | describe : false,
41 | xdescribe : false,
42 |
43 | // Protractor
44 | protractor: false,
45 | browser: false,
46 | by: false,
47 | element: false
48 | }
49 | },
50 | source: {
51 | src: ['src/directives/*.js', 'src/services/*.js']
52 | },
53 | tests: {
54 | src: ['test/unit/*.js', 'test/e2e/*.js'],
55 | },
56 | grunt: {
57 | src: ['Gruntfile.js']
58 | }
59 | };
60 | };
61 |
--------------------------------------------------------------------------------
/examples/085-events-kml-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/examples/048-layers-static-image-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
34 |
35 |
36 |
37 |
38 |
39 | Static Image Layer example
40 | You can load an static image (no tiles) easily, look at the source of the layer object:
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/examples/049-layers-stamen-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Using Stamen Maps Layer
34 | This map uses a Stamen layer. Click on the buttons to see the three types of layers:
35 |
36 |
41 |
42 | Current TileLayer Url:
43 |
{{ stamen | json }}
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/050-layer-geojson-change-style-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
37 |
38 |
39 |
40 |
41 |
42 | Layers GeoJSON change style
43 | Stroke color:
44 |
Stroke width:
45 |
Fill color:
46 |
47 |
48 |
--------------------------------------------------------------------------------
/examples/041-layers-zoom-tiles-changer-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
32 |
33 |
34 |
35 |
36 |
37 | Tiles zoom changer example
38 | This is a map with dynamic tile change depending on zoom level
39 | Current TileLayer Url:
{{ OSMLayer.source.url | json }}
40 | Current Zoom Level: {{ london.zoom }}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/102-controls-measure-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
38 |
39 |
40 |
41 |
42 |
43 | Fullscreen control example
44 | Example of the fullscreen control:
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/examples/json/ITA.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[
2 | {"type":"Feature","id":"ITA","properties":{"name":"Italy"},"geometry":{"type":"MultiPolygon","coordinates":[[[[15.520376,38.231155],[15.160243,37.444046],[15.309898,37.134219],[15.099988,36.619987],[14.335229,36.996631],[13.826733,37.104531],[12.431004,37.61295],[12.570944,38.126381],[13.741156,38.034966],[14.761249,38.143874],[15.520376,38.231155]]],[[[9.210012,41.209991],[9.809975,40.500009],[9.669519,39.177376],[9.214818,39.240473],[8.806936,38.906618],[8.428302,39.171847],[8.388253,40.378311],[8.159998,40.950007],[8.709991,40.899984],[9.210012,41.209991]]],[[[12.376485,46.767559],[13.806475,46.509306],[13.69811,46.016778],[13.93763,45.591016],[13.141606,45.736692],[12.328581,45.381778],[12.383875,44.885374],[12.261453,44.600482],[12.589237,44.091366],[13.526906,43.587727],[14.029821,42.761008],[15.14257,41.95514],[15.926191,41.961315],[16.169897,41.740295],[15.889346,41.541082],[16.785002,41.179606],[17.519169,40.877143],[18.376687,40.355625],[18.480247,40.168866],[18.293385,39.810774],[17.73838,40.277671],[16.869596,40.442235],[16.448743,39.795401],[17.17149,39.4247],[17.052841,38.902871],[16.635088,38.843572],[16.100961,37.985899],[15.684087,37.908849],[15.687963,38.214593],[15.891981,38.750942],[16.109332,38.964547],[15.718814,39.544072],[15.413613,40.048357],[14.998496,40.172949],[14.703268,40.60455],[14.060672,40.786348],[13.627985,41.188287],[12.888082,41.25309],[12.106683,41.704535],[11.191906,42.355425],[10.511948,42.931463],[10.200029,43.920007],[9.702488,44.036279],[8.888946,44.366336],[8.428561,44.231228],[7.850767,43.767148],[7.435185,43.693845],[7.549596,44.127901],[7.007562,44.254767],[6.749955,45.028518],[7.096652,45.333099],[6.802355,45.70858],[6.843593,45.991147],[7.273851,45.776948],[7.755992,45.82449],[8.31663,46.163642],[8.489952,46.005151],[8.966306,46.036932],[9.182882,46.440215],[9.922837,46.314899],[10.363378,46.483571],[10.442701,46.893546],[11.048556,46.751359],[11.164828,46.941579],[12.153088,47.115393],[12.376485,46.767559]]]]}}
3 | ]}
4 |
--------------------------------------------------------------------------------
/examples/024-center-bounds-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
30 |
31 |
32 |
33 | Map bounds example
34 | We can define a bounds property inside our center object and it will be filled with the maximum extent of the map.
35 | Center
36 | Latitude :
37 | Longitude :
38 | Zoom :
39 | Center object
40 |
41 | {{ cairo | json }}
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/examples/101-controls-fullscreen-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
38 |
39 |
40 |
41 |
42 |
43 | Fullscreen control example
44 | Example of the fullscreen control. Controls object:
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/examples/030-custom-parameters-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
41 |
42 |
43 |
44 | Custom parameters example
45 | These are the custom properties applied in this map:
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/directives/view.js:
--------------------------------------------------------------------------------
1 | angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) {
2 | return {
3 | restrict: 'A',
4 | scope: false,
5 | replace: false,
6 | require: 'openlayers',
7 | link: function(scope, element, attrs, controller) {
8 | var olScope = controller.getOpenlayersScope();
9 | var isNumber = olHelpers.isNumber;
10 | var safeApply = olHelpers.safeApply;
11 | var createView = olHelpers.createView;
12 |
13 | olScope.getMap().then(function(map) {
14 | var defaults = olMapDefaults.getDefaults(olScope);
15 | var view = olScope.view;
16 |
17 | if (!view.projection) {
18 | view.projection = defaults.view.projection;
19 | }
20 |
21 | if (!view.maxZoom) {
22 | view.maxZoom = defaults.view.maxZoom;
23 | }
24 |
25 | if (!view.minZoom) {
26 | view.minZoom = defaults.view.minZoom;
27 | }
28 |
29 | if (!view.rotation) {
30 | view.rotation = defaults.view.rotation;
31 | }
32 |
33 | var mapView = createView(view);
34 | map.setView(mapView);
35 |
36 | olScope.$watchCollection('view', function(view) {
37 | if (isNumber(view.rotation)) {
38 | mapView.setRotation(view.rotation);
39 | }
40 | });
41 |
42 | var rotationEventKey = mapView.on('change:rotation', function() {
43 | safeApply(olScope, function(scope) {
44 | scope.view.rotation = map.getView().getRotation();
45 | });
46 | });
47 |
48 | olScope.$on('$destroy', function() {
49 | ol.Observable.unByKey(rotationEventKey);
50 | });
51 |
52 | });
53 | }
54 | };
55 | });
56 |
--------------------------------------------------------------------------------
/examples/021-center-url-hash-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
26 |
27 |
28 |
29 | Center map with URL synchronization example
30 | This demo syncs the map center position with the URL, and viceversa, using the center-url-params property.
31 |
36 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/046-layers-geojson-center-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
41 |
42 |
43 |
44 |
45 |
46 | Layers center to GeoJSON example
47 | Click the button to center the map to the extent of the Japan GeoJSON Vector Layer.
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/examples/112-layers-esri-basemaps-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ESRI BaseMaps
34 | This map uses ESRI BaseMaps.
35 |
36 |
41 |
42 |
43 | Current TileLayer Url:
44 |
{{ esribasemaps.source.layer | json }}
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/043-layers-bing-maps-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Using a Bing Maps Layer
36 | This map uses a Bing source. You must request an API key to use these maps here .
37 |
38 |
43 |
44 | Current TileLayer Url:
45 |
{{ bing | json }}
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/examples/105-controls-overviewmap-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
40 |
41 |
42 |
43 |
44 |
45 | Overview control example
46 | Example of the overviewmap control. Controls object:
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/examples/084-events-add-markers-on-click-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/examples/061-markers-add-remove-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
50 |
51 |
52 |
53 |
54 |
55 | Markers simple example
56 |
57 | You can add/remove markers to the map easily. Look at the markers object:
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/grunt/concat.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var banner = '(function (root, factory) {\n' +
4 | ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' +
5 | ' // CommonJS\n' +
6 | ' var ol = require(\'openlayers\');\n' +
7 | ' exports.angularOpenlayersDirective = factory(ol);\n' +
8 | ' } else if (typeof define === \'function\' && define.amd) {\n' +
9 | ' // AMD.\n' +
10 | ' define([\'ol\'], function (ol) {\n' +
11 | ' return root.angularOpenlayersDirective = factory(ol);\n' +
12 | ' });\n' +
13 | ' } else {\n' +
14 | ' // Browser globals\n' +
15 | ' root.angularOpenlayersDirective = factory(root.ol);\n' +
16 | ' }\n' +
17 | '}(this, function (ol) {\n';
18 |
19 | module.exports = function (grunt, options) {
20 | return {
21 | dist: {
22 | options: {
23 | banner: banner,
24 | footer: '\n}));'
25 | },
26 | src: [
27 | 'src/directives/openlayers.js',
28 | 'src/directives/center.js',
29 | 'src/directives/layer.js',
30 | 'src/directives/events.js',
31 | 'src/directives/path.js',
32 | 'src/directives/view.js',
33 | 'src/directives/control.js',
34 | 'src/directives/marker.js',
35 | 'src/services/olData.js',
36 | 'src/services/olHelpers.js',
37 | 'src/services/olMapDefaults.js'
38 | ],
39 | dest: 'dist/angular-openlayers-directive.pre.js',
40 | },
41 | css: {
42 | src: [
43 | 'css/markers.css',
44 | 'css/openlayers.css'
45 | ],
46 | dest: 'dist/angular-openlayers-directive.css'
47 | },
48 | license: {
49 | src: [
50 | 'src/header-MIT-license.txt',
51 | 'dist/angular-openlayers-directive.min.no-header.js'
52 | ],
53 | dest: 'dist/angular-openlayers-directive.min.js',
54 | },
55 | };
56 | };
57 |
--------------------------------------------------------------------------------
/examples/051-layer-geojson-change-style-with-function-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
54 |
55 |
56 |
57 |
58 |
59 | Layers GeoJSON change style with a function
60 | Move the map to change the vector layer style.
61 | Change Style
62 |
63 |
64 |
--------------------------------------------------------------------------------
/examples/057-layers-wmts-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | WMTS Layer
51 | This map uses a WMTS layer from a geoserver.
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/examples/067-marker-custom-icon-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/examples/083-events-static-image-layer-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
49 |
50 |
51 |
52 |
53 |
54 | Mouse position
55 |
56 | Mouse click position
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/services/olData.js:
--------------------------------------------------------------------------------
1 | angular.module('openlayers-directive').service('olData', function($log, $q) {
2 |
3 | var maps = {};
4 |
5 | var setResolvedDefer = function(d, mapId) {
6 | var id = obtainEffectiveMapId(d, mapId);
7 | d[id].resolvedDefer = true;
8 | };
9 |
10 | var getUnresolvedDefer = function(d, mapId) {
11 | var id = obtainEffectiveMapId(d, mapId);
12 | var defer;
13 |
14 | if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) {
15 | defer = $q.defer();
16 | d[id] = {
17 | defer: defer,
18 | resolvedDefer: false
19 | };
20 | } else {
21 | defer = d[id].defer;
22 | }
23 | return defer;
24 | };
25 |
26 | var getDefer = function(d, mapId) {
27 | var id = obtainEffectiveMapId(d, mapId);
28 | var defer;
29 |
30 | if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) {
31 | defer = getUnresolvedDefer(d, mapId);
32 | } else {
33 | defer = d[id].defer;
34 | }
35 | return defer;
36 | };
37 |
38 | this.setMap = function(olMap, scopeId) {
39 | var defer = getUnresolvedDefer(maps, scopeId);
40 | defer.resolve(olMap);
41 | setResolvedDefer(maps, scopeId);
42 | };
43 |
44 | this.getMap = function(scopeId) {
45 | var defer = getDefer(maps, scopeId);
46 | return defer.promise;
47 | };
48 |
49 | function obtainEffectiveMapId(d, mapId) {
50 | var id;
51 | var i;
52 | if (!angular.isDefined(mapId)) {
53 | if (Object.keys(d).length === 1) {
54 | for (i in d) {
55 | if (d.hasOwnProperty(i)) {
56 | id = i;
57 | }
58 | }
59 | } else if (Object.keys(d).length === 0) {
60 | id = 'main';
61 | } else {
62 | $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' +
63 | 'you must provide the map ID to the olData.getXXX call');
64 | }
65 | } else {
66 | id = mapId;
67 | }
68 | return id;
69 | }
70 |
71 | this.resetMap = function(scopeId) {
72 | if (angular.isDefined(maps[scopeId])) {
73 | delete maps[scopeId];
74 | }
75 | };
76 |
77 | });
78 |
--------------------------------------------------------------------------------
/examples/042-layers-opacity-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
Layers opacity example
46 |
This is a map that can change the tiles of the main layer by demand
47 |
48 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/directives/path.js:
--------------------------------------------------------------------------------
1 | angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) {
2 |
3 | return {
4 | restrict: 'E',
5 | scope: {
6 | properties: '=olGeomProperties',
7 | style: '=olStyle'
8 | },
9 | require: '^openlayers',
10 | replace: true,
11 | template: '',
12 |
13 | link: function(scope, element, attrs, controller) {
14 | var isDefined = olHelpers.isDefined;
15 | var createFeature = olHelpers.createFeature;
16 | var createOverlay = olHelpers.createOverlay;
17 | var createVectorLayer = olHelpers.createVectorLayer;
18 | var insertLayer = olHelpers.insertLayer;
19 | var removeLayer = olHelpers.removeLayer;
20 | var olScope = controller.getOpenlayersScope();
21 |
22 | olScope.getMap().then(function(map) {
23 | var mapDefaults = olMapDefaults.getDefaults(olScope);
24 | var viewProjection = mapDefaults.view.projection;
25 |
26 | var layer = createVectorLayer();
27 | var layerCollection = map.getLayers();
28 |
29 | insertLayer(layerCollection, layerCollection.getLength(), layer);
30 |
31 | scope.$on('$destroy', function() {
32 | removeLayer(layerCollection, layer.index);
33 | });
34 |
35 | if (isDefined(attrs.coords)) {
36 | var proj = attrs.proj || 'EPSG:4326';
37 | var coords = JSON.parse(attrs.coords);
38 | var data = {
39 | type: 'Polygon',
40 | coords: coords,
41 | projection: proj,
42 | style: scope.style ? scope.style : mapDefaults.styles.path
43 | };
44 | var feature = createFeature(data, viewProjection);
45 | layer.getSource().addFeature(feature);
46 |
47 | if (attrs.message) {
48 | scope.message = attrs.message;
49 | var extent = feature.getGeometry().getExtent();
50 | var label = createOverlay(element, extent);
51 | map.addOverlay(label);
52 | }
53 | return;
54 | }
55 | });
56 | }
57 | };
58 | });
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-openlayers-directive",
3 | "author": "David Rubert ",
4 | "contributors": ["Juri Strumpflohner "],
5 | "description":
6 | "angular-openlayers-directive - An AngularJS directive to easily interact with Openlayers maps",
7 | "homepage": "http://tombatossals.github.io/angular-openlayers-directive/",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/tombatossals/angular-openlayers-directive"
11 | },
12 | "keywords": ["angularjs", "openlayers", "cli"],
13 | "license": "MIT",
14 | "dependencies": {
15 | "angular": "~1.4.8",
16 | "angular-sanitize": "~1.4.8",
17 | "openlayers": "4.3.4"
18 | },
19 | "devDependencies": {
20 | "grunt": "~0.4.5",
21 | "grunt-bower-task": "~0.4.0",
22 | "grunt-bump": "^0.3.0",
23 | "grunt-contrib-concat": "~0.5.0",
24 | "grunt-contrib-connect": "^0.11.2",
25 | "grunt-contrib-jshint": "^0.11.0",
26 | "grunt-contrib-uglify": "^0.9.1",
27 | "grunt-contrib-watch": "~0.6.1",
28 | "grunt-conventional-changelog": "^4.1.0",
29 | "grunt-jscs": "^2.1.0",
30 | "grunt-karma": "^0.12.0",
31 | "grunt-karma-coveralls": "~2.5.3",
32 | "grunt-ng-annotate": "^1.0.1",
33 | "grunt-open": "~0.2.3",
34 | "grunt-protractor-runner": "^2.0.0",
35 | "grunt-shell": "~1.1.1",
36 | "grunt-shell-spawn": "~0.3.0",
37 | "jasmine-core": "^2.2.0",
38 | "karma": "^0.13.9",
39 | "karma-chrome-launcher": "^0.2.0",
40 | "karma-coffee-preprocessor": "^0.3.0",
41 | "karma-coverage": "^0.5.0",
42 | "karma-firefox-launcher": "~0.1.4",
43 | "karma-html2js-preprocessor": "~0.1.0",
44 | "karma-jasmine": "~0.3.3",
45 | "karma-phantomjs-launcher": "^0.2.1",
46 | "karma-requirejs": "~0.2.2",
47 | "karma-script-launcher": "~0.1.0",
48 | "load-grunt-config": "^0.17.1",
49 | "matchdep": "~0.3.0",
50 | "phantomjs": "^2.1.0",
51 | "protractor": "~2.5.0",
52 | "publish-latest": "^1.1.2",
53 | "semantic-release": "^4.3.5"
54 | },
55 | "scripts": {
56 | "test": "grunt build && grunt karma:unit",
57 | "test.watch": "grunt build && grunt karma:dev",
58 | "build": "grunt build",
59 | "prepublish": "npm run build",
60 | "postpublish": "publish-latest",
61 | "semantic-release":
62 | "semantic-release pre && npm publish && semantic-release post"
63 | },
64 | "main": "dist/angular-openlayers-directive"
65 | }
66 |
--------------------------------------------------------------------------------
/examples/055-layers-geojon-dynamic-load-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
60 |
61 |
62 |
63 |
64 |
65 | Layers inline GeoJSON example
66 | Load France GeoJSON
67 | You can load inline GeoJSON as new layer easily, look at the source of the layers attribute:
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/directives/control.js:
--------------------------------------------------------------------------------
1 | angular.module('openlayers-directive')
2 | .directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) {
3 | return {
4 | restrict: 'E',
5 | scope: {
6 | properties: '=olControlProperties'
7 | },
8 | replace: false,
9 | require: '^openlayers',
10 | link: function(scope, element, attrs, controller) {
11 | var isDefined = olHelpers.isDefined;
12 | var olScope = controller.getOpenlayersScope();
13 | var olControl;
14 | var olControlOps;
15 | var getControlClasses = olHelpers.getControlClasses;
16 | var controlClasses = getControlClasses();
17 |
18 | olScope.getMap().then(function(map) {
19 |
20 | scope.$on('$destroy', function() {
21 | map.removeControl(olControl);
22 | });
23 |
24 | scope.$watch('properties', function(properties) {
25 | if (!isDefined(properties)) {
26 | return;
27 | }
28 |
29 | initCtrls(properties);
30 | });
31 |
32 | function initCtrls(properties) {
33 | if (properties && properties.control) {
34 | // the control instance is already defined,
35 | // so simply use it and go ahead
36 |
37 | // is there already a control, so destroy and recreate it?
38 | if (olControl) {
39 | map.removeControl(olControl);
40 | }
41 |
42 | olControl = properties.control;
43 | map.addControl(olControl);
44 | } else {
45 |
46 | // the name is the key to instantiate an ol3 control
47 | if (attrs.name) {
48 | if (isDefined(properties)) {
49 | olControlOps = properties;
50 | }
51 |
52 | // is there already a control, so destroy and recreate it?
53 | if (olControl) {
54 | map.removeControl(olControl);
55 | }
56 |
57 | olControl = new controlClasses[attrs.name](olControlOps);
58 | map.addControl(olControl);
59 | }
60 | }
61 | }
62 |
63 | initCtrls(scope.properties);
64 |
65 | });
66 |
67 | }
68 | };
69 | });
70 |
--------------------------------------------------------------------------------
/examples/065-markers-static-image-layer-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Static Image Layer example
61 | You can load an static image (no tiles) easily, look at the source of the layers attribute:
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/examples/100-controls-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
54 |
55 |
56 |
57 |
58 |
59 | Controls example
60 |
61 | Degrees: {{ degrees }}
62 | You can add/remove controls to the map via the controls attribute:
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/examples/025-center-projections-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
52 |
53 |
54 |
55 | Center map example
56 |
61 | Center object
62 | {{ center | json }}
63 | Sexagesimal system conversion: {{ sexagesimalCenter }}
64 | Center object transformed to view projection EPSG:3857
65 | {{ center | transform: 'EPSG:3857' | json }}
66 |
67 |
68 |
--------------------------------------------------------------------------------
/examples/120-custom-layer-and-projection-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
58 |
59 |
60 |
66 |
67 |
68 |
69 | Custom layer source with custom projection and extent
70 |
71 | An example that demonstrates how to adequately setup a custom layer source with a custom projection and extent
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/examples/113-layers-image-wms-with-attribution-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | WMS Image Layer with Attribution
60 |
61 | This map uses a WMS image layer from a geoserver with custom annotation defined in the layer object.
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/examples/104-controls-options-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
57 |
58 |
59 |
60 |
61 |
62 | Controls example
63 |
64 | Degrees: {{ degrees }}
65 | You can add/remove controls to the map via the controls attribute:
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/examples/103-controls-custom-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
18 |
69 |
70 |
71 |
72 |
73 |
74 | Example of a custom control
75 | Rotates the map 90 degrees when pressed:
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/examples/058-layers-geojson-style-function.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
62 |
63 |
64 |
65 |
66 |
67 | Layers GeoJSON features with different styles example
68 | You can define a function to set the style for features based on properties
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/examples/081-events-vector-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
68 |
69 |
70 |
71 |
72 |
73 | Layers GeoJSON events example
74 | Mouse over this country: {{ mouseMoveCountry }}
75 | Mouse clicked this country: {{ mouseClickCountry }}
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/examples/054-add-remove-multiple-layers-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
60 |
61 |
62 |
63 |
64 |
65 | Adding/removing layers example
66 |
67 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/test/unit/controlsSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | describe('Directive: openlayers controls', function() {
7 | var $compile = null;
8 | var $rootScope = null;
9 | var $timeout;
10 | var olData = null;
11 | var olMapDefaults = null;
12 | var scope;
13 |
14 | var containsInstance = function(controls, instance) {
15 | for (var i in controls.array_) {
16 | if (controls.array_[i] instanceof instance) {
17 | return true;
18 | }
19 | }
20 | return false;
21 | };
22 |
23 | beforeEach(module('openlayers-directive'));
24 | beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _olData_, _olMapDefaults_) {
25 | $compile = _$compile_;
26 | $rootScope = _$rootScope_;
27 | $timeout = _$timeout_;
28 | olData = _olData_;
29 | olMapDefaults = _olMapDefaults_;
30 |
31 | scope = $rootScope.$new();
32 | }));
33 |
34 | afterEach(inject(function($rootScope) {
35 | $rootScope.$apply();
36 | }));
37 |
38 | it('should show controls by name', function() {
39 | var element = angular.element('' +
40 | ' ' +
41 | ' ');
42 | element = $compile(element)(scope);
43 | var controls;
44 | olData.getMap().then(function(olMap) {
45 | controls = olMap.getControls();
46 | });
47 | scope.$digest();
48 |
49 | expect(containsInstance(controls, ol.control.FullScreen)).toBe(true);
50 | });
51 |
52 | it('should add controls by scope', function() {
53 | scope.fullscreen = {
54 | control: new ol.control.FullScreen()
55 | };
56 | var element = angular.element('' +
57 | ' ' +
58 | ' ');
59 | element = $compile(element)(scope);
60 | var controls;
61 | olData.getMap().then(function(olMap) {
62 | controls = olMap.getControls();
63 | });
64 | scope.$digest();
65 |
66 | expect(containsInstance(controls, ol.control.FullScreen)).toBe(true);
67 | });
68 |
69 | it('should remove controls from map', function() {
70 | scope.fullscreenControl = {
71 | control: new ol.control.FullScreen()
72 | };
73 | scope.showControl = true;
74 | var element = angular.element('' +
75 | ' ' +
76 | ' ');
77 | element = $compile(element)(scope);
78 | var controls;
79 | olData.getMap().then(function(olMap) {
80 | controls = olMap.getControls();
81 | });
82 | scope.$digest();
83 | expect(containsInstance(controls, ol.control.FullScreen)).toBe(true);
84 |
85 | scope.showControl = false;
86 | scope.$digest();
87 | expect(containsInstance(controls, ol.control.FullScreen)).toBe(false);
88 | });
89 |
90 | });
91 |
--------------------------------------------------------------------------------
/examples/json/features.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "geometry": {
7 | "type": "Point",
8 | "coordinates": [
9 | -80.87088507656375,
10 | 35.21515162500578
11 | ]
12 | },
13 | "properties": {
14 | "name": "ABBOTT NEIGHBORHOOD PARK",
15 | "address": "1300 SPRUCE ST",
16 | "radius": 5,
17 | "color": "black"
18 | }
19 | },
20 | {
21 | "type": "Feature",
22 | "geometry": {
23 | "type": "Point",
24 | "coordinates": [
25 | -80.83775386582222,
26 | 35.24980190252168
27 | ]
28 | },
29 | "properties": {
30 | "name": "DOUBLE OAKS CENTER",
31 | "address": "1326 WOODWARD AV",
32 | "radius": 6,
33 | "color": "red"
34 | }
35 | },
36 | {
37 | "type": "Feature",
38 | "geometry": {
39 | "type": "Point",
40 | "coordinates": [
41 | -80.83827000459532,
42 | 35.25674709224663
43 | ]
44 | },
45 | "properties": {
46 | "name": "DOUBLE OAKS NEIGHBORHOOD PARK",
47 | "address": "2605 DOUBLE OAKS RD",
48 | "radius": 7,
49 | "color": "yellow"
50 | }
51 | },
52 | {
53 | "type": "Feature",
54 | "geometry": {
55 | "type": "Point",
56 | "coordinates": [
57 | -80.83697759172735,
58 | 35.25751734669229
59 | ]
60 | },
61 | "properties": {
62 | "name": "DOUBLE OAKS POOL",
63 | "address": "1200 NEWLAND RD",
64 | "radius": 8,
65 | "color": "orange"
66 | }
67 | },
68 | {
69 | "type": "Feature",
70 | "geometry": {
71 | "type": "Point",
72 | "coordinates": [
73 | -80.81647652154736,
74 | 35.40148708491418
75 | ]
76 | },
77 | "properties": {
78 | "name": "DAVID B. WAYMER FLYING REGIONAL PARK",
79 | "address": "15401 HOLBROOKS RD",
80 | "radius": 9,
81 | "color": "green"
82 | }
83 | },
84 | {
85 | "type": "Feature",
86 | "geometry": {
87 | "type": "Point",
88 | "coordinates": [
89 | -80.83556459443902,
90 | 35.39917224760999
91 | ]
92 | },
93 | "properties": {
94 | "name": "DAVID B. WAYMER COMMUNITY PARK",
95 | "address": "302 HOLBROOKS RD",
96 | "radius": 10,
97 | "color": "blue"
98 | }
99 | }
100 | ]
101 | }
--------------------------------------------------------------------------------
/examples/080-events-propagation-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
60 |
61 |
62 |
63 | Events defaults example
64 | In this example we propagate two events in our map, the mouse position and the mouse click.
65 | Set desired projection:
66 |
67 |
68 |
69 | Mouse position
70 |
71 | Mouse click position
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/examples/063-markers-properties-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Markers label example
51 | You can interact with the marker properties to modify its behaviour.
52 | Santiago de Compostela
53 | Message:
54 | Label show
55 | Label show on marker mouse over
56 | Draggable
57 | Lat: , Lon:
58 |
59 | Finisterre
60 | Message:
61 | Label show
62 | Label show on marker mouse over
63 | Draggable
64 | Lat: , Lon:
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/examples/064-markers-render-html-inside-labels-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
21 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | Render HTML inside a marker label
79 | Mouse over the markers to show an image associated with each one.
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/examples/045-layers-geojson-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
90 |
91 |
92 |
93 |
94 |
95 | Layers GeoJSON example
96 | You can load GeoJSON as new layers easily, look at the source of the layers attribute:
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/examples/059-layer-clustering.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
91 |
92 |
93 |
94 |
95 |
96 | Layer clustering example
97 |
98 | You can activate clustering on a layer easily, look at the source of the layers :
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/examples/040-layers-change-tiles-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
Layers change tiles example
77 |
This is a map that can change the tiles of the main layer by demand
78 |
79 |
84 |
85 |
Current TileLayer Url:
86 |
{{ layers | json }}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/test/unit/helperSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | function replacer(k, v) {
7 | if (typeof v === 'function') {
8 | v = v.toString();
9 | } else if (window.File && v instanceof File) {
10 | v = '[File]';
11 | } else if (window.FileList && v instanceof FileList) {
12 | v = '[FileList]';
13 | }
14 | return v;
15 | }
16 |
17 | describe('Method: olHelpers.createStyle', function() {
18 | var _olHelpers;
19 |
20 | beforeEach(module('openlayers-directive'));
21 | beforeEach(inject(function(olHelpers) {
22 | _olHelpers = olHelpers;
23 | }));
24 |
25 | beforeEach(function() {
26 | jasmine.addMatchers({
27 | toBeJsonEqual: function() {
28 | return {
29 | compare: function(actual, expected) {
30 | var one = JSON.stringify(actual, replacer).replace(/(\\t|\\n)/g, '');
31 | var two = JSON.stringify(expected, replacer).replace(/(\\t|\\n)/g, '');
32 | return one === two;
33 | }
34 | };
35 | }
36 | });
37 | });
38 |
39 | it('makes marker icon style', function() {
40 | var style = {
41 | image: {
42 | icon: {
43 | anchor: [0.5, 1],
44 | anchorXUnits: 'fraction',
45 | anchorYUnits: 'fraction',
46 | opacity: 0.90,
47 | src: 'images/map-marker.png'
48 | }
49 | }
50 | };
51 | expect(_olHelpers.createStyle(style))
52 | .toEqual(new ol.style.Style({
53 | fill: null,
54 | stroke: null,
55 | image: new ol.style.Icon(style.image.icon)
56 | }));
57 | });
58 |
59 | it('makes drawing feature style', function() {
60 | var style = {
61 | fill: {
62 | color: 'rgba(0, 0, 255, 0.6)'
63 | },
64 | stroke: {
65 | color: 'white',
66 | width: 3
67 | }
68 | };
69 |
70 | expect(_olHelpers.createStyle(style))
71 | .toEqual(new ol.style.Style({
72 | fill: new ol.style.Fill({
73 | color: style.fill.color
74 | }),
75 | stroke: new ol.style.Stroke({
76 | color: style.stroke.color,
77 | width: style.stroke.width
78 | }),
79 | image: null
80 | }));
81 | });
82 |
83 | xit('makes circle feature style', function() {
84 | var style = {
85 | image: {
86 | circle: {
87 | radius: 8,
88 | fill: {
89 | color: 'rgba(0, 0, 255, 0.6)'
90 | },
91 | stroke: {
92 | color: 'white',
93 | width: 3
94 | }
95 | }
96 | }
97 | };
98 |
99 | expect(_olHelpers.createStyle(style))
100 | .toBeJsonEqual(new ol.style.Style({
101 | fill: null,
102 | stroke: null,
103 | image: new ol.style.Circle({
104 | radius: 8,
105 | fill: new ol.style.Fill({
106 | color: 'rgba(0, 0, 255, 0.6)'
107 | }),
108 | stroke: new ol.style.Stroke({
109 | color: 'white',
110 | width: 3
111 | })
112 | })
113 | }));
114 | });
115 |
116 | });
117 |
--------------------------------------------------------------------------------
/examples/086-events-multi-layer-vector-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
84 |
85 |
86 |
87 |
88 |
89 | Layers GeoJSON events example
90 | Mouse over this country: {{ mouseMoveCountry }}
91 | Mouse clicked this country: {{ mouseClickCountry }}
92 |
93 | Mouse over this feature: {{ mouseMoveFeature }}
94 | Mouse clicked this feature: {{ mouseClickFeature }}
95 |
96 |
97 |
--------------------------------------------------------------------------------
/doc/02-center-attribute.md:
--------------------------------------------------------------------------------
1 | 'ol-center' Attribute Documentation
2 | ===================================
3 |
4 | This is an attribute of the **openlayers** main directive, and we will use it like this:
5 |
6 | ```
7 |
8 | ```
9 |
10 | It will map an object *center* of our controller scope with the corresponding object on our directive isolated scope. It's a bidirectional relationship, so a change in this object on the controller scope will affect the map center position, or an interaction on the map which changes the map center will update our *center* values. Let's define the center model with an example:
11 |
12 | ```
13 | $scope.center = {
14 | lat: 51.505,
15 | lon: -0.09
16 | zoom: 4
17 | }
18 | ```
19 |
20 | It uses the projection EPSG:3857 by default, and we can see that a center is conformed by three required attributes: *lat*, *lon* and *zoom*. When we associate that object with our *openlayers-directive* the bi-directional relation will start.
21 |
22 | Let's see a complete example of how to use this. We must create a center object in our controller, pass its name to our directive *center* attribute, an that's all.
23 |
24 | ```
25 | angular.extend($scope, {
26 | center: {
27 | lat: 51.505,
28 | lon: -0.09
29 | zoom: 4
30 | }
31 | });
32 | ```
33 |
34 | And after that, in our HTML code we will define our openlayers directive like this:
35 |
36 | ```
37 |
38 | ```
39 |
40 | And that's all. A simple example of using this attribute can be found [here](http://tombatossals.github.io/angular-openlayers-directive/examples/020-center-example.html).
41 |
42 | Autodiscover
43 | ------------
44 |
45 | The *lat*, *long* and *zoom* properties are mandatory to make the center work, but we have an optional property which we can use to auto-discover the position of the user browsing our page using the [W3C Geolocation API](http://dev.w3.org/geo/api/spec-source.html) using the corresponding methods defined in the [Openlayers API](http://openlayers.org/en/v3.0.0/apidoc/ol.Geolocation.html).
46 |
47 | For example, we could show the user geographic position on start, or when he press a button. This property is defined like this:
48 |
49 | ```
50 | angular.extend($scope, {
51 | center: {
52 | lat: 0,
53 | lon: 0,
54 | zoom: 1,
55 | autodiscover: true
56 | }
57 | });
58 | ```
59 |
60 | Whenever we set the *autodiscover* attribute to our center object, the map will be positioned to the geographic location of the device (if the user allows it).
61 |
62 | We can see an example of how to use this [here](http://tombatossals.github.io/angular-openlayers-directive/examples/022-center-autodiscover-example.html).
63 |
64 | Center position coded on a hash URL param
65 | -----------------------------------------
66 |
67 | We can use a special feature of the center attribute which will allow us to synchronize the center position of the map with the URL of the browser, adding to it a special GET parameter where the center is coded. This way, we can persist the map position on the browser URL.
68 |
69 | ```
70 | center: {
71 | lat: 51.505,
72 | lon: -0.09
73 | zoom: 4,
74 | urlHash: true
75 | }
76 | ```
77 |
78 | Adding that attribute to our center object will synchronize the map center with a GET parameter on the URL of this form `?c=lat:lon:zoom`. Furthermore, whenever the map center is changed a new event `centerUrlHashChanged` will be emitted to the parent scope so you can update your `$location.search` with the new info (if you want).
79 |
80 | You can take a look of this feature on this [demo](http://tombatossals.github.io/angular-openlayers-directive/examples/021-url-hash-center-example.html).
81 |
82 | Bounds
83 | ------
84 |
85 | Maybe we are interested in knowing about the bounds of the map rendered on screen to the user.
86 |
87 | ```
88 | center {
89 | extent: [ 0, 0, 51.505, -0.09 ]
90 | }
91 | ```
92 |
--------------------------------------------------------------------------------
/doc/01-openlayers-directive.md:
--------------------------------------------------------------------------------
1 | Openlayers directive Documentation
2 | ==================================
3 |
4 | This directive acts as an intermediary between the AngularJS framework and the Openlayers (version 3) map management library. It's composed of a main directive **<openlayers>** and attributes (coded as sub-directives) of the main directive. For example, we could add to our HTML code:
5 |
6 | ```
7 |
8 | ```
9 |
10 | Here we have the main **openlayers** directive, with the attribute **center** and two more attributes **width** and **height**.
11 |
12 | Before detailing how to use the directive and its attributes, let's talk about initializing our web page to be able to work with the directive. We must load the required JS libraries and CSS in our HTML:
13 |
14 | ```
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ```
23 |
24 | After loading the required libraries, we only need to define our AngularJS application (depending on 'openlayers-directive') and an application controller to be able to load our map. Showing the map on screen will require that we set the width and height of our map, via CSS or as attributes of the *openlayers* tag. Let' see how to do it:
25 |
26 | - We can add *height* and *width* attributes to our *openlayers* directive inline. Example:
27 |
28 | ```
29 |
30 | ```
31 |
32 | - We can set the *width* and *height* of the common CSS class '*angular-openlayers-map*' applied to all maps. Beware this will be applied to all maps rendered on your application. Example:
33 |
34 | ```
35 |
41 | ```
42 |
43 | - We can set and *id* to our map, and set the CSS properties to this specifid id. Example:
44 |
45 | ```
46 |
52 | ...
53 |
54 | ```
55 |
56 | Great, let's see now the complete HTML and inline javascript code needed to load our first map:
57 |
58 | ```
59 |
60 |
61 |
62 |
63 |
64 |
65 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | ```
75 |
76 | You can see this example in action on the [simple-example demo file](http://tombatossals.github.io/angular-openlayers-directive/examples/01-simple-example.html).
77 |
78 | Take a look at the [AngularJS controller documentation](http://docs.angularjs.org/guide/controller) if you want to learn more about Angular controller definition, or to the [AngularJS ngApp](http://docs.angularjs.org/api/ng.directive:ngApp) to know how to bootstrap an Angular application.
79 |
80 | Attributes Documentation
81 | ========================
82 |
83 | We have much more possibilities than showing a simple map, but this will need that we take a closer look at the attributes, listed below:
84 |
85 | - [ol-defaults attribute](https://github.com/tombatossals/angular-openlayers-directive/blob/master/doc/03-defaults-attribute.md)
86 | - [ol-center attribute](https://github.com/tombatossals/angular-openlayers-directive/blob/master/doc/02-center-attribute.md)
87 | - [ol-layers attribute](https://github.com/tombatossals/angular-openlayers-directive/blob/master/doc/04-layers-attribute.md)
88 |
--------------------------------------------------------------------------------
/examples/090-multiple-maps-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
96 |
97 |
98 |
103 |
108 | Two maps sharing center example
109 | Drag the center in any of the maps
110 |
111 |
112 |
--------------------------------------------------------------------------------
/test/unit/openlayersSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | describe('Directive: openlayers', function() {
7 | var $compile = null;
8 | var $rootScope = null;
9 | var $timeout;
10 | var olData = null;
11 | var olHelpers;
12 | var olMapDefaults = null;
13 | var scope;
14 |
15 | beforeEach(module('openlayers-directive'));
16 | beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _olData_, _olHelpers_, _olMapDefaults_) {
17 | $compile = _$compile_;
18 | $rootScope = _$rootScope_;
19 | $timeout = _$timeout_;
20 | olData = _olData_;
21 | olHelpers = _olHelpers_;
22 | olMapDefaults = _olMapDefaults_;
23 |
24 | scope = $rootScope.$new();
25 | }));
26 |
27 | afterEach(inject(function($rootScope) {
28 | $rootScope.$apply();
29 | }));
30 |
31 | it('should have loaded openlayers library inside the directive', function() {
32 | var element = angular.element(' ');
33 | element = $compile(element)(scope);
34 | var map;
35 | olData.getMap().then(function(olMap) {
36 | map = olMap;
37 | });
38 | scope.$digest();
39 | expect(map).toBeDefined();
40 | });
41 |
42 | it('should set default center if not center is provided', function() {
43 | var element = angular.element(' ');
44 | element = $compile(element)(scope);
45 | var map;
46 | var defaults = olMapDefaults.getDefaults();
47 |
48 | olData.getMap().then(function(olMap) {
49 | map = olMap;
50 | });
51 |
52 | scope.$digest();
53 | expect(map.getView().getZoom()).toEqual(defaults.center.zoom);
54 | expect(map.getView().getCenter()[0]).toBeCloseTo(defaults.center.lon);
55 | expect(map.getView().getCenter()[1]).toBeCloseTo(defaults.center.lat);
56 | });
57 |
58 | it('should set default layer if not layers are provided', function() {
59 | var element = angular.element(' ');
60 | element = $compile(element)(scope);
61 | var map;
62 | olData.getMap().then(function(olMap) {
63 | map = olMap;
64 | });
65 | scope.$digest();
66 | var olLayers = map.getLayers();
67 | expect(olLayers.getLength()).toEqual(1);
68 | var layer = olLayers.item(0);
69 | expect(layer instanceof ol.layer.Tile).toBe(true);
70 | var olSource = layer.getSource();
71 | expect(olSource instanceof ol.source.OSM).toBe(true);
72 | });
73 |
74 | it('should set the default view if not specified', function() {
75 | var element = angular.element(' ');
76 | element = $compile(element)(scope);
77 | var map;
78 | var defaults = olMapDefaults.getDefaults();
79 |
80 | olData.getMap().then(function(olMap) {
81 | map = olMap;
82 | });
83 |
84 | scope.$digest();
85 | var view = map.getView();
86 | expect(view.getProjection().getCode()).toEqual(defaults.view.projection);
87 | expect(view.getRotation()).toEqual(defaults.view.rotation);
88 | });
89 |
90 | it('should set the default controls if not specified', function() {
91 | var element = angular.element(' ');
92 | element = $compile(element)(scope);
93 | var defaults = olMapDefaults.getDefaults();
94 | var controls;
95 |
96 | olData.getMap().then(function(olMap) {
97 | controls = olMap.getControls();
98 | });
99 |
100 | scope.$digest();
101 | var activeControls = Object.keys(defaults.controls).filter(function(c) {
102 | return defaults.controls[c] === true;
103 | });
104 | expect(controls.getLength()).toEqual(activeControls.length);
105 |
106 | var actualControls = Object.keys(olHelpers.detectControls(controls));
107 | actualControls.sort();
108 | activeControls.sort();
109 | expect(activeControls).toEqual(actualControls);
110 | });
111 | });
112 |
--------------------------------------------------------------------------------
/test/unit/centerSpec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*jshint -W117 */
3 | /*jshint globalstrict: true*/
4 | /* jasmine specs for directives go here */
5 |
6 | describe('Directive: openlayers center', function() {
7 | var $compile;
8 | var $rootScope;
9 | var $timeout;
10 | var $location;
11 | var olData;
12 | var olMapDefaults;
13 | var scope;
14 |
15 | beforeEach(module('openlayers-directive'));
16 | beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _olData_, _olMapDefaults_, _$location_) {
17 | $compile = _$compile_;
18 | $rootScope = _$rootScope_;
19 | $timeout = _$timeout_;
20 | $location = _$location_;
21 | olData = _olData_;
22 | olMapDefaults = _olMapDefaults_;
23 |
24 | scope = $rootScope.$new();
25 | }));
26 |
27 | afterEach(inject(function($rootScope) {
28 | $rootScope.$apply();
29 | }));
30 |
31 | it('should have default {[0, 0], 1} parameters on the map if not correctly defined', function() {
32 | scope.center = {};
33 | var element = angular.element(' ');
34 | element = $compile(element)(scope);
35 | scope.$digest();
36 |
37 | var map;
38 | olData.getMap().then(function(olMap) {
39 | map = olMap;
40 | });
41 |
42 | scope.$digest();
43 | var zoom = map.getView().getZoom();
44 | var center = map.getView().getCenter();
45 | expect(zoom).toEqual(1);
46 | expect(center[0]).toBeCloseTo(0);
47 | expect(center[1]).toBeCloseTo(0);
48 | });
49 |
50 | it('should update the map center if the initial center scope properties are set', function() {
51 | scope.center = {
52 | lat: 0.96658,
53 | lon: 2.02,
54 | zoom: 4
55 | };
56 |
57 | var element = angular.element(' ');
58 | element = $compile(element)(scope);
59 |
60 | var map;
61 | olData.getMap().then(function(olMap) {
62 | map = olMap;
63 | });
64 |
65 | scope.$digest();
66 | var defaults = olMapDefaults.getDefaults();
67 | var zoom = map.getView().getZoom();
68 | var mapCenter = map.getView().getCenter();
69 | mapCenter = ol.proj.transform([mapCenter[1], mapCenter[0]], defaults.view.projection, scope.center.projection);
70 | expect(zoom).toEqual(4);
71 | expect(mapCenter[0]).toBeCloseTo(0.96658);
72 | expect(mapCenter[1]).toBeCloseTo(2.02);
73 | });
74 |
75 | it('should update the map center if the scope center properties changes', function() {
76 | scope.center = {
77 | lat: 0.96658,
78 | lon: 2.02,
79 | zoom: 4
80 | };
81 |
82 | var element = angular.element(' ');
83 | element = $compile(element)(scope);
84 |
85 | var map;
86 | olData.getMap().then(function(olMap) {
87 | map = olMap;
88 | });
89 | scope.$digest();
90 |
91 | var defaults = olMapDefaults.getDefaults();
92 | var mapCenter = map.getView().getCenter();
93 | mapCenter = ol.proj.transform([mapCenter[1], mapCenter[0]], defaults.view.projection, scope.center.projection);
94 | expect(mapCenter[0]).toBeCloseTo(0.96658);
95 | expect(mapCenter[1]).toBeCloseTo(2.01958);
96 | expect(map.getView().getZoom()).toEqual(4);
97 |
98 | scope.center = {
99 | lat: 2.0304,
100 | lon: 4.04,
101 | zoom: 8
102 | };
103 |
104 | scope.$digest();
105 |
106 | mapCenter = map.getView().getCenter();
107 | mapCenter = ol.proj.transform([mapCenter[1], mapCenter[0]], defaults.view.projection, scope.center.projection);
108 | expect(mapCenter[0]).toBeCloseTo(2.0304);
109 | expect(mapCenter[1]).toBeCloseTo(4.0366);
110 | expect(map.getView().getZoom()).toEqual(8);
111 | });
112 |
113 | it('should constrain max/min zoom if specified', function() {
114 | scope.center = {
115 | lat: 0.96658,
116 | lon: 2.02,
117 | zoom: 8,
118 | centerUrlHash: true
119 | };
120 |
121 | scope.defaults = {
122 | view: {
123 | maxZoom: 6,
124 | minZoom: 3
125 | }
126 | };
127 |
128 | var element = angular.element(' ');
129 | element = $compile(element)(scope);
130 |
131 | var map;
132 | olData.getMap().then(function(olMap) {
133 | map = olMap;
134 | });
135 |
136 | scope.$digest();
137 | expect(map.getView().getZoom()).toEqual(6);
138 | });
139 | });
140 |
--------------------------------------------------------------------------------
/src/directives/openlayers.js:
--------------------------------------------------------------------------------
1 | angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', function($log, $q, $compile, olHelpers,
2 | olMapDefaults, olData) {
3 | return {
4 | restrict: 'EA',
5 | transclude: true,
6 | replace: true,
7 | scope: {
8 | center: '=olCenter',
9 | defaults: '=olDefaults',
10 | view: '=olView',
11 | events: '=olEvents'
12 | },
13 | template: '
',
14 | controller: function($scope) {
15 | var _map = $q.defer();
16 | $scope.getMap = function() {
17 | return _map.promise;
18 | };
19 |
20 | $scope.setMap = function(map) {
21 | _map.resolve(map);
22 | };
23 |
24 | this.getOpenlayersScope = function() {
25 | return $scope;
26 | };
27 | },
28 | link: function(scope, element, attrs) {
29 | var isDefined = olHelpers.isDefined;
30 | var createLayer = olHelpers.createLayer;
31 | var setMapEvents = olHelpers.setMapEvents;
32 | var setViewEvents = olHelpers.setViewEvents;
33 | var createView = olHelpers.createView;
34 | var defaults = olMapDefaults.setDefaults(scope);
35 |
36 | // Set width and height if they are defined
37 | if (isDefined(attrs.width)) {
38 | if (isNaN(attrs.width)) {
39 | element.css('width', attrs.width);
40 | } else {
41 | element.css('width', attrs.width + 'px');
42 | }
43 | }
44 |
45 | if (isDefined(attrs.height)) {
46 | if (isNaN(attrs.height)) {
47 | element.css('height', attrs.height);
48 | } else {
49 | element.css('height', attrs.height + 'px');
50 | }
51 | }
52 |
53 | if (isDefined(attrs.lat)) {
54 | defaults.center.lat = parseFloat(attrs.lat);
55 | }
56 |
57 | if (isDefined(attrs.lon)) {
58 | defaults.center.lon = parseFloat(attrs.lon);
59 | }
60 |
61 | if (isDefined(attrs.zoom)) {
62 | defaults.center.zoom = parseFloat(attrs.zoom);
63 | }
64 |
65 | var controls = ol.control.defaults(defaults.controls);
66 | var interactions = ol.interaction.defaults(defaults.interactions);
67 | var view = createView(defaults.view);
68 |
69 | // Create the Openlayers Map Object with the options
70 | var map = new ol.Map({
71 | target: element[0],
72 | controls: controls,
73 | interactions: interactions,
74 | renderer: defaults.renderer,
75 | view: view,
76 | loadTilesWhileAnimating: defaults.loadTilesWhileAnimating,
77 | loadTilesWhileInteracting: defaults.loadTilesWhileInteracting
78 | });
79 |
80 | scope.$on('$destroy', function() {
81 | olData.resetMap(attrs.id);
82 | map.setTarget(null);
83 | map = null;
84 | });
85 |
86 | // If no layer is defined, set the default tileLayer
87 | if (!attrs.customLayers) {
88 | var l = {
89 | type: 'Tile',
90 | source: {
91 | type: 'OSM'
92 | }
93 | };
94 | var layer = createLayer(l, view.getProjection(), 'default');
95 | map.addLayer(layer);
96 | map.set('default', true);
97 | }
98 |
99 | if (!isDefined(attrs.olCenter)) {
100 | var c = ol.proj.transform([defaults.center.lon,
101 | defaults.center.lat
102 | ],
103 | defaults.center.projection, view.getProjection()
104 | );
105 | view.setCenter(c);
106 | view.setZoom(defaults.center.zoom);
107 | }
108 |
109 | // Set the Default events for the map
110 | setMapEvents(defaults.events, map, scope);
111 |
112 | //Set the Default events for the map view
113 | setViewEvents(defaults.events, map, scope);
114 |
115 | // Resolve the map object to the promises
116 | scope.setMap(map);
117 | olData.setMap(map, attrs.id);
118 |
119 | }
120 | };
121 | });
122 |
--------------------------------------------------------------------------------
/test/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // A reference configuration file.
2 | exports.config = {
3 | // ----- How to setup Selenium -----
4 | //
5 | // There are three ways to specify how to use Selenium. Specify one of the
6 | // following:
7 | //
8 | // 1. seleniumServerJar - to start Selenium Standalone locally.
9 | // 2. seleniumAddress - to connect to a Selenium server which is already
10 | // running.
11 | // 3. sauceUser/sauceKey - to use remote Selenium servers via SauceLabs.
12 | //
13 | // If the chromeOnly option is specified, no Selenium server will be started,
14 | // and chromeDriver will be used directly (from the location specified in
15 | // chromeDriver)
16 |
17 | // The location of the selenium standalone server .jar file.
18 | seleniumServerJar: '../node_modules/protractor/selenium/selenium-server-standalone-2.47.1.jar',
19 | // The port to start the selenium server on, or null if the server should
20 | // find its own unused port.
21 | seleniumPort: null,
22 | // Chromedriver location is used to help the selenium standalone server
23 | // find chromedriver. This will be passed to the selenium jar as
24 | // the system property webdriver.chrome.driver. If null, selenium will
25 | // attempt to find chromedriver using PATH.
26 | chromeDriver: '../node_modules/protractor/selenium/chromedriver',
27 | // If true, only chromedriver will be started, not a standalone selenium.
28 | // Tests for browsers other than chrome will not run.
29 | chromeOnly: false,
30 | // Additional command line options to pass to selenium. For example,
31 | // if you need to change the browser timeout, use
32 | // seleniumArgs: ['-browserTimeout=60'],
33 | seleniumArgs: [],
34 |
35 | // If sauceUser and sauceKey are specified, seleniumServerJar will be ignored.
36 | // The tests will be run remotely using SauceLabs.
37 | sauceUser: null,
38 | sauceKey: null,
39 |
40 | // The address of a running selenium server. If specified, Protractor will
41 | // connect to an already running instance of selenium. This usually looks like
42 | // seleniumAddress: 'http://localhost:4444/wd/hub'
43 | //seleniumAddress: 'http://localhost:4444/wd/hub',
44 |
45 | // The timeout for each script run on the browser. This should be longer
46 | // than the maximum time your application needs to stabilize between tasks.
47 | allScriptsTimeout: 11000,
48 |
49 | // ----- What tests to run -----
50 | //
51 | // Spec patterns are relative to the location of this config.
52 | specs: [
53 | 'e2e/*.js',
54 | ],
55 |
56 | // ----- Capabilities to be passed to the webdriver instance ----
57 | //
58 | // For a full list of available capabilities, see
59 | // https://code.google.com/p/selenium/wiki/DesiredCapabilities
60 | // and
61 | // https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
62 | capabilities: {
63 | 'browserName': 'chrome'
64 | },
65 |
66 | // ----- More information for your tests ----
67 | //
68 | // A base URL for your application under test. Calls to protractor.get()
69 | // with relative paths will be prepended with this.
70 | baseUrl: 'http://localhost:9999/examples/',
71 |
72 | // Selector for the element housing the angular app - this defaults to
73 | // body, but is necessary if ng-app is on a descendant of
74 | rootElement: 'body',
75 |
76 | // A callback function called once protractor is ready and available, and
77 | // before the specs are executed
78 | // You can specify a file containing code to run by setting onPrepare to
79 | // the filename string.
80 | onPrepare: function() {
81 | // At this point, global 'protractor' object will be set up, and jasmine
82 | // will be available. For example, you can add a Jasmine reporter with:
83 | // jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter(
84 | // 'outputdir/', true, true));
85 | },
86 |
87 | // The params object will be passed directly to the protractor instance,
88 | // and can be accessed from your test. It is an arbitrary object and can
89 | // contain anything you my need in your test.
90 | // This can be changed via the command line as:
91 | // --params.login.user 'Joe'
92 | params: {
93 | login: {
94 | user: 'Jane',
95 | password: '1234'
96 | }
97 | },
98 |
99 | // ----- Options to be passed to minijasminenode -----
100 | //
101 | // See the full list at https://github.com/juliemr/minijasminenode
102 | jasmineNodeOpts: {
103 | // onComplete will be called just before the driver quits.
104 | onComplete: null,
105 | // If true, display spec names.
106 | isVerbose: true,
107 | // If true, print colors to the terminal.
108 | showColors: true,
109 | // If true, include stack traces in failures.
110 | includeStackTrace: true,
111 | // Default time to wait in ms before a test fails.
112 | defaultTimeoutInterval: 30000
113 | }
114 | };
115 |
--------------------------------------------------------------------------------