├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.js
├── circle.yml
├── cleanup.js
├── coverage
├── base.css
├── circle
│ ├── circle.ts.html
│ └── index.html
├── coverage.json
├── geojson
│ ├── geojson.ts.html
│ └── index.html
├── group
│ ├── group.ts.html
│ └── index.html
├── helpers
│ ├── coodinateHandler.ts.html
│ ├── geoJsonReader.ts.html
│ └── index.html
├── index.html
├── map
│ ├── index.html
│ └── map.ts.html
├── models
│ ├── index.html
│ └── path.ts.html
├── prettify.css
├── services
│ ├── globalId.service.ts.html
│ ├── group.service.ts.html
│ ├── helper.service.ts.html
│ ├── index.html
│ ├── map.service.ts.html
│ └── popup.service.ts.html
├── sort-arrow-sprite.png
└── test
│ ├── index.html
│ ├── main.test.ts.html
│ ├── mock.component.ts.html
│ └── tsloader.ts.html
├── karma.conf.js
├── ngx.leaflet.components.ts
├── package-lock.json
├── package.json
├── public_api.ts
├── rollup.config.esm.js
├── rollup.config.umd.js
├── src
├── circle
│ ├── circle.spec.ts
│ ├── circle.ts
│ └── index.ts
├── circlemarker
│ ├── circlemarker.ts
│ └── index.ts
├── geojson
│ ├── geojson.spec.ts
│ ├── geojson.ts
│ └── index.ts
├── group
│ ├── group.ts
│ └── index.ts
├── helpers
│ ├── coordinateHandler.ts
│ └── geoJsonReader.ts
├── imageoverlay
│ ├── image-overlay.ts
│ └── index.ts
├── index.ts
├── interfaces
│ └── path.ts
├── layer
│ ├── index.ts
│ └── layer.ts
├── map
│ ├── attribution
│ │ ├── attribution.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── map.spec.ts
│ ├── map.ts
│ ├── scale
│ │ ├── index.ts
│ │ └── scale.ts
│ ├── watermark
│ │ ├── index.ts
│ │ └── watermark.ts
│ └── zoom
│ │ ├── index.ts
│ │ └── zoom.ts
├── marker
│ ├── index.ts
│ └── marker.ts
├── models
│ ├── attributionModel.ts
│ ├── path.ts
│ ├── scaleModel.ts
│ └── zoomModel.ts
├── ngx.leaflet.components.ts
├── ngx.leaflet.module.ts
├── polygon
│ ├── index.ts
│ └── polygon.ts
├── polyline
│ ├── index.ts
│ └── polyline.ts
├── popup
│ ├── index.ts
│ └── popup.ts
├── services
│ ├── globalId.service.ts
│ ├── group.service.ts
│ ├── helper.service.ts
│ ├── map.service.ts
│ └── popup.service.ts
└── test
│ ├── main.test.ts
│ ├── mock.component.ts
│ ├── tsloader.js
│ └── tsloader.ts
├── tsconfig-build.json
├── tsconfig.json
├── tslint.json
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | typings/
3 | dist/
4 | test/mock/
5 | .vscode/
6 | documentation/
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Change Log
2 |
3 | ## 1.4.1
4 | * Angular updated to 5.0
5 | * Fixed empty popups on all elements
6 | * Changlelog was moved here
7 | * Changes on package.json to avoid certain webpack error
8 | * Change structure to be more compatible with a stricter tsconfig
9 | * Live website with some examples [here](https://elasticrash.github.io/Angular.io.MapViewer/app/)
10 |
11 | ## 1.4.0
12 | * Changes for depended type geojson
13 | * Css bug fixes
14 | * updates on tests
15 |
16 | ## 1.3.2
17 | * Angular updated to version 4.0.0
18 | * Project was renamed to ngx.leaflet.components (for obvious reasons) and previous one got deprecated
19 | * Coordinates now are automatically get re-projected, except for (wgs84 and 3857) so when using a custom crs, you need to pass, on the components, the coordinates associated with that particular crs. Automatic reprojection to wgs84 works on all components except ImageOverlay.
20 | * Bug Fixes
21 | * Components now accept x,y as inputs as well as lat lngs
22 |
23 | ## 1.3.1
24 | * Angular updated to 2.4.7
25 | * Circle Marker Element Added
26 | * Bug fixes
27 |
28 | ## 1.3.0
29 | * Polyline, Polygon, Circle and Marker now implement an ng-content pop up strategy
30 | * Increased Webpack compatibility (seems to work fine now)
31 | * Marker layer is no longer slow (it should work fine even with nearly 1000 markers)
32 | * Bug fixes
33 |
34 | ## 1.2.6
35 | * Bug fixes
36 | * Layers have attributions
37 | * Map has optional maxBounds
38 |
39 | ## 1.2.5
40 | * Scale, Zoom and Attribution are different components
41 | * Coverage reports for tests
42 | * Improved Webpack support
43 |
44 | ## 1.2.4
45 | * ImageOverlay support
46 | * GeoJson Layer support
47 | * CRS support for different coordinate systems (Proj4Leaflet is not working for leaflet 1.0.x though you need to write your own custom projection, I am working on an example)
48 | * Fixed a bug that didn't display a wms layer when set as basemap
49 | * Stopped using typings, switched to @types
50 | * Unit testing for more stable releases
51 | * Upgraded to typescript 2.14 and Angular 2.41
52 |
53 | ## 1.2.3
54 | * Fixed a bug that didn't allow the usage of polygons in a multiple map per page set up
55 |
56 | ## 1.2.2
57 | * Angular updated to 2.3.0
58 | * Bug fixes
59 | * Polygon element now supports holes
60 | * Polygon element can now be dynamically updated
61 |
62 | ## 1.2.1
63 | * Code was optimised, now everything is much faster
64 | * Layer Control can now be dynamically updated
65 | * polyline element now can be dynamically updated (able to create animated elements). Soon more elements will follow.
66 |
67 | ## 1.2.0
68 | * Added popup element
69 |
70 | ## 1.1.4
71 | * Choose whether a layer should be basemap or overlay on layerControl
72 | * Add names for the layers or groups on the layerControl
73 |
74 | ## 1.1.3
75 | * Custom marker icon
76 |
77 | ## 1.1.2
78 | * Multiple maps support
79 | * mouseover and onclick popup's for marker and all vector elements
80 |
81 | ## 1.1.1
82 | * css had top:64px now it has 0px so the map can take the whole available space
83 | * Added polygon element
84 | * Added polyline element
85 |
86 | ## 1.1.0
87 | * Error handling for circle-element
88 | * Error handling for marker-element
89 | * Added layer groups
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 stefanos kouroupis
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ngx.leaflet.component
2 |
3 | ## Native Angular Components designed to be used directly on the templates without much customization
4 |
5 | [website with examples](https://elasticrash.github.io/Angular.io.MapViewer/app/)
6 |
7 | Old Examples
8 | * [base example](https://elasticrash.github.io/Angular.io.MapViewer/example/)
9 | * [multi-map example ](https://elasticrash.github.io/Angular.io.MapViewer/example/#/mm-map)
10 | * [star map using L.CRS.Simple ](https://elasticrash.github.io/Angular.io.MapViewer/example/#/simple)
11 | * [custom CRS using leaflet ](https://elasticrash.github.io/Angular.io.MapViewer/example/#/prj)
12 | * [a genetic like algorithm trying to solve the Travelling salesman problem ](https://elasticrash.github.io/Angular.io.MapViewer/example/#/random)
13 |
14 | Examples sources can be found in the following github repository [here](https://github.com/elasticrash/Angular.io.MapViewer)
15 |
16 |
17 | Install
18 | ```terminal
19 | npm install ngx.leaflet.components
20 | npm install leaflet
21 | ```
22 |
23 | USE
24 |
25 | ```javascript
26 | import { ngxLeafletModule } from 'ngx.leaflet.components';
27 |
28 | @NgModule({
29 | imports: [ngxLeafletModule],
30 | })
31 | ```
32 |
33 | Leaflet stylesheets are not included automatically for the time, so you need to add it yourself
34 |
35 | for usage and basic examples check the wiki
36 |
37 | https://github.com/elasticrash/ngx.leaflet.component/wiki
38 |
39 |
40 | If anyone wants to help in any way feel free to do a fork and a pull request
41 |
42 | ## NOTE
43 |
44 | * angular 4/5 use for versions 1.4.2
45 | * angular 6 use versions 2.0.0+
46 |
47 | version 2.0.0 at the moment is not yet on npm due to not being tested properly but it can be easily be build by running
48 | * npm run build
49 |
--------------------------------------------------------------------------------
/build.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const shell = require('shelljs');
4 | const chalk = require('chalk');
5 |
6 | const PACKAGE = `src/ngx.leaflet.components`;
7 | const NPM_DIR = `dist`;
8 | const ESM2015_DIR = `${NPM_DIR}/esm2015`;
9 | const ESM5_DIR = `${NPM_DIR}/esm5`;
10 | const BUNDLES_DIR = `${NPM_DIR}/bundles`;
11 | const OUT_DIR_ESM5 = `${NPM_DIR}/package/esm5`;
12 |
13 | shell.echo(`Start building...`);
14 |
15 | shell.rm(`-Rf`, `${NPM_DIR}/*`);
16 | shell.mkdir(`-p`, `./${ESM2015_DIR}`);
17 | shell.mkdir(`-p`, `./${ESM5_DIR}`);
18 | shell.mkdir(`-p`, `./${BUNDLES_DIR}`);
19 |
20 | /* TSLint with Codelyzer */
21 | // https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts
22 | // https://github.com/mgechev/codelyzer
23 | shell.echo(`Start TSLint`);
24 | shell.exec(`tslint -c tslint.json -t stylish src/**/*.ts`);
25 | shell.echo(chalk.green(`TSLint completed`));
26 |
27 | /* AoT compilation */
28 | shell.echo(`Start AoT compilation`);
29 | if (shell.exec(`ngc -p tsconfig-build.json`).code !== 0) {
30 | shell.echo(chalk.red(`Error: AoT compilation failed`));
31 | shell.exit(1);
32 | }
33 | shell.echo(chalk.green(`AoT compilation completed`));
34 |
35 | /* BUNDLING PACKAGE */
36 | shell.echo(`Start bundling`);
37 | shell.echo(`Rollup package`);
38 | if (shell.exec(`rollup -c rollup.config.esm.js -i ${NPM_DIR}/${PACKAGE}.js -o ${ESM2015_DIR}/${PACKAGE}.js`).code !== 0) {
39 | shell.echo(chalk.red(`Error: Rollup package failed`));
40 | shell.exit(1);
41 | }
42 |
43 | shell.echo(`Produce ESM5 version`);
44 | shell.exec(`ngc -p tsconfig-build.json --target es5 -d false --outDir ${OUT_DIR_ESM5} --importHelpers true --sourceMap`);
45 | if (shell.exec(`rollup -c rollup.config.esm.js -i ${OUT_DIR_ESM5}/${PACKAGE}.js -o ${ESM5_DIR}/${PACKAGE}.js`).code !== 0) {
46 | shell.echo(chalk.red(`Error: ESM5 version failed`));
47 | shell.exit(1);
48 | }
49 |
50 | shell.echo(`Run Rollup conversion on package`);
51 | if (shell.exec(`rollup -c rollup.config.umd.js -i ${ESM5_DIR}/${PACKAGE}.js -o ${BUNDLES_DIR}/${PACKAGE}.umd.js`).code !== 0) {
52 | shell.echo(chalk.red(`Error: Rollup conversion failed`));
53 | shell.exit(1);
54 | }
55 |
56 | shell.echo(`Minifying`);
57 | shell.cd(`${BUNDLES_DIR}`);
58 | shell.exec(`uglifyjs ${PACKAGE}.umd.js -c --comments -o ${PACKAGE}.umd.min.js --source-map "filename='${PACKAGE}.umd.min.js.map', includeSources"`);
59 | shell.cd(`..`);
60 | shell.cd(`..`);
61 |
62 | shell.echo(chalk.green(`Bundling completed`));
63 |
64 | shell.rm(`-Rf`, `${NPM_DIR}/package`);
65 | shell.rm(`-Rf`, `${NPM_DIR}/node_modules`);
66 | shell.rm(`-Rf`, `${NPM_DIR}/*.js`);
67 | shell.rm(`-Rf`, `${NPM_DIR}/*.js.map`);
68 | shell.rm(`-Rf`, `${NPM_DIR}/src/**/*.js`);
69 | shell.rm(`-Rf`, `${NPM_DIR}/src/**/*.js.map`);
70 |
71 | shell.cp(`-Rf`, [`package.json`, `LICENSE`, `README.md`], `${NPM_DIR}`);
72 |
73 | shell.echo(chalk.green(`End building`));
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | node:
3 | version: 8.4.0
4 | npm:
5 | version: 5.2.0
--------------------------------------------------------------------------------
/cleanup.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | console.log(__dirname);
4 | var appPath = __dirname.split('node_modules')[0];
5 | rmDir(appPath +"//");
6 |
7 | function rmDir(dirPath) {
8 | var findWorkingDir = dirPath;
9 | console.log("findWorkingDir", findWorkingDir);
10 |
11 | if (findWorkingDir.indexOf('node_modules') === -1) {
12 | var files = fs.readdirSync(findWorkingDir);
13 |
14 | if (files.length > 0) {
15 | for (var i = 0; i < files.length; i++) {
16 |
17 | var filePath = findWorkingDir + files[i];
18 |
19 | if (filePath.indexOf('test') === -1 && filePath.indexOf('dist') === -1) {
20 | if (files[i].charAt(0) !== ".") {
21 | if (fs.statSync(filePath).isFile()) {
22 | if (files[i].indexOf('.js') !== -1) {
23 | if (files[i] !== "karma.conf.js" &&
24 | files[i] !== "webpack.config.js" &&
25 | files[i] !== "tsloader.js" &&
26 | files[i] !== "build.js" &&
27 | files[i] !== "cleanup.js" &&
28 | files[i] !== "rollup.config.esm.js" &&
29 | files[i] !== "rollup.config.umd.js" &&
30 | files[i].indexOf('.json') === -1 &&
31 | files[i].indexOf('.js.map') === -1) {
32 | fs.unlinkSync(filePath);
33 | //fs.rename(filePath, filePath.replace(appPath, appPath + "/test/mock/"));
34 | console.log("delete", files[i]);
35 | }
36 | }
37 | }
38 | else {
39 | rmDir(filePath + "/");
40 | }
41 | }
42 | }
43 | }
44 | }
45 | }
46 | }
47 |
48 | console.log('all js files are deleted');
--------------------------------------------------------------------------------
/coverage/base.css:
--------------------------------------------------------------------------------
1 | body, html {
2 | margin:0; padding: 0;
3 | height: 100%;
4 | }
5 | body {
6 | font-family: Helvetica Neue, Helvetica, Arial;
7 | font-size: 14px;
8 | color:#333;
9 | }
10 | .small { font-size: 12px; }
11 | *, *:after, *:before {
12 | -webkit-box-sizing:border-box;
13 | -moz-box-sizing:border-box;
14 | box-sizing:border-box;
15 | }
16 | h1 { font-size: 20px; margin: 0;}
17 | h2 { font-size: 14px; }
18 | pre {
19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
20 | margin: 0;
21 | padding: 0;
22 | -moz-tab-size: 2;
23 | -o-tab-size: 2;
24 | tab-size: 2;
25 | }
26 | a { color:#0074D9; text-decoration:none; }
27 | a:hover { text-decoration:underline; }
28 | .strong { font-weight: bold; }
29 | .space-top1 { padding: 10px 0 0 0; }
30 | .pad2y { padding: 20px 0; }
31 | .pad1y { padding: 10px 0; }
32 | .pad2x { padding: 0 20px; }
33 | .pad2 { padding: 20px; }
34 | .pad1 { padding: 10px; }
35 | .space-left2 { padding-left:55px; }
36 | .space-right2 { padding-right:20px; }
37 | .center { text-align:center; }
38 | .clearfix { display:block; }
39 | .clearfix:after {
40 | content:'';
41 | display:block;
42 | height:0;
43 | clear:both;
44 | visibility:hidden;
45 | }
46 | .fl { float: left; }
47 | @media only screen and (max-width:640px) {
48 | .col3 { width:100%; max-width:100%; }
49 | .hide-mobile { display:none!important; }
50 | }
51 |
52 | .quiet {
53 | color: #7f7f7f;
54 | color: rgba(0,0,0,0.5);
55 | }
56 | .quiet a { opacity: 0.7; }
57 |
58 | .fraction {
59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
60 | font-size: 10px;
61 | color: #555;
62 | background: #E8E8E8;
63 | padding: 4px 5px;
64 | border-radius: 3px;
65 | vertical-align: middle;
66 | }
67 |
68 | div.path a:link, div.path a:visited { color: #333; }
69 | table.coverage {
70 | border-collapse: collapse;
71 | margin: 10px 0 0 0;
72 | padding: 0;
73 | }
74 |
75 | table.coverage td {
76 | margin: 0;
77 | padding: 0;
78 | vertical-align: top;
79 | }
80 | table.coverage td.line-count {
81 | text-align: right;
82 | padding: 0 5px 0 20px;
83 | }
84 | table.coverage td.line-coverage {
85 | text-align: right;
86 | padding-right: 10px;
87 | min-width:20px;
88 | }
89 |
90 | table.coverage td span.cline-any {
91 | display: inline-block;
92 | padding: 0 5px;
93 | width: 100%;
94 | }
95 | .missing-if-branch {
96 | display: inline-block;
97 | margin-right: 5px;
98 | border-radius: 3px;
99 | position: relative;
100 | padding: 0 4px;
101 | background: #333;
102 | color: yellow;
103 | }
104 |
105 | .skip-if-branch {
106 | display: none;
107 | margin-right: 10px;
108 | position: relative;
109 | padding: 0 4px;
110 | background: #ccc;
111 | color: white;
112 | }
113 | .missing-if-branch .typ, .skip-if-branch .typ {
114 | color: inherit !important;
115 | }
116 | .coverage-summary {
117 | border-collapse: collapse;
118 | width: 100%;
119 | }
120 | .coverage-summary tr { border-bottom: 1px solid #bbb; }
121 | .keyline-all { border: 1px solid #ddd; }
122 | .coverage-summary td, .coverage-summary th { padding: 10px; }
123 | .coverage-summary tbody { border: 1px solid #bbb; }
124 | .coverage-summary td { border-right: 1px solid #bbb; }
125 | .coverage-summary td:last-child { border-right: none; }
126 | .coverage-summary th {
127 | text-align: left;
128 | font-weight: normal;
129 | white-space: nowrap;
130 | }
131 | .coverage-summary th.file { border-right: none !important; }
132 | .coverage-summary th.pct { }
133 | .coverage-summary th.pic,
134 | .coverage-summary th.abs,
135 | .coverage-summary td.pct,
136 | .coverage-summary td.abs { text-align: right; }
137 | .coverage-summary td.file { white-space: nowrap; }
138 | .coverage-summary td.pic { min-width: 120px !important; }
139 | .coverage-summary tfoot td { }
140 |
141 | .coverage-summary .sorter {
142 | height: 10px;
143 | width: 7px;
144 | display: inline-block;
145 | margin-left: 0.5em;
146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
147 | }
148 | .coverage-summary .sorted .sorter {
149 | background-position: 0 -20px;
150 | }
151 | .coverage-summary .sorted-desc .sorter {
152 | background-position: 0 -10px;
153 | }
154 | .status-line { height: 10px; }
155 | /* dark red */
156 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
157 | .low .chart { border:1px solid #C21F39 }
158 | /* medium red */
159 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
160 | /* light red */
161 | .low, .cline-no { background:#FCE1E5 }
162 | /* light green */
163 | .high, .cline-yes { background:rgb(230,245,208) }
164 | /* medium green */
165 | .cstat-yes { background:rgb(161,215,106) }
166 | /* dark green */
167 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) }
168 | .high .chart { border:1px solid rgb(77,146,33) }
169 | /* dark yellow (gold) */
170 | .medium .chart { border:1px solid #f9cd0b; }
171 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; }
172 | /* light yellow */
173 | .medium { background: #fff4c2; }
174 | /* light gray */
175 | span.cline-neutral { background: #eaeaea; }
176 |
177 | .cbranch-no { background: yellow !important; color: #111; }
178 |
179 | .cstat-skip { background: #ddd; color: #111; }
180 | .fstat-skip { background: #ddd; color: #111 !important; }
181 | .cbranch-skip { background: #ddd !important; color: #111; }
182 |
183 |
184 | .cover-fill, .cover-empty {
185 | display:inline-block;
186 | height: 12px;
187 | }
188 | .chart {
189 | line-height: 0;
190 | }
191 | .cover-empty {
192 | background: white;
193 | }
194 | .cover-full {
195 | border-right: none !important;
196 | }
197 | pre.prettyprint {
198 | border: none !important;
199 | padding: 0 !important;
200 | margin: 0 !important;
201 | }
202 | .com { color: #999 !important; }
203 | .ignore-none { color: #999; font-weight: normal; }
204 |
205 | .wrapper {
206 | min-height: 100%;
207 | height: auto !important;
208 | height: 100%;
209 | margin: 0 auto -48px;
210 | }
211 | .footer, .push {
212 | height: 48px;
213 | }
214 |
--------------------------------------------------------------------------------
/coverage/circle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for circle\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 65.22%
24 | Statements
25 | 30/46
26 |
27 |
28 | 14.29%
29 | Branches
30 | 2/14
31 |
32 |
33 | 50%
34 | Functions
35 | 2/4
36 |
37 |
38 | 62.79%
39 | Lines
40 | 27/43
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | circle.ts
63 |
64 | 65.22%
65 | 30/46
66 | 14.29%
67 | 2/14
68 | 50%
69 | 2/4
70 | 62.79%
71 | 27/43
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/coverage/geojson/geojson.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for geojson\geojson.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 92.11%
24 | Statements
25 | 35/38
26 |
27 |
28 | 60%
29 | Branches
30 | 6/10
31 |
32 |
33 | 100%
34 | Functions
35 | 4/4
36 |
37 |
38 | 91.43%
39 | Lines
40 | 32/35
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34
80 | 35
81 | 36
82 | 37
83 | 38
84 | 39
85 | 40
86 | 41
87 | 42
88 | 43
89 | 44
90 | 45
91 | 46
92 | 47
93 | 48
94 | 49
95 | 50
96 | 51
97 | 52
98 | 53
99 | 54
100 | 55
101 | 56
102 | 57
103 | 58
104 | 59
105 | 60
106 | 61
107 | 62
108 | 63
109 | 64 1×
110 | 1×
111 | 1×
112 | 1×
113 | 1×
114 | 1×
115 | 1×
116 | 1×
117 | 1×
118 |
119 | 1×
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | 1×
129 | 1×
130 | 1×
131 |
132 |
133 | 1×
134 | 1×
135 | 1×
136 | 1×
137 | 1×
138 | 1×
139 | 1×
140 | 1×
141 |
142 |
143 | 1×
144 |
145 | 1×
146 |
147 | 1×
148 |
149 | 1×
150 | 1×
151 |
152 | 1×
153 |
154 | 1×
155 |
156 |
157 | 1×
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | 1×
169 | 1×
170 |
171 | 1×
172 | import { Component, Input, Injector, Optional } from '@angular/core';
173 | import { LeafletElement } from '../map/map';
174 | import { LeafletGroup } from '../group/group';
175 | import { MapService } from '../services/map.service';
176 | import { GroupService } from '../services/group.service';
177 | import { PopupService } from '../services/popup.service';
178 | import { GuidService } from '../services/globalId.service';
179 | import { HelperService } from '../services/helper.service';
180 | import { GeoJSONCoordinateHandler } from '../helpers/geoJsonReader';
181 |
182 | import * as L from 'leaflet';
183 |
184 | @Component({
185 | moduleId: module.id.toString(),
186 | selector: 'geojson-element',
187 | templateUrl: 'geojson.html',
188 | styleUrls: ['geojson.css']
189 | })
190 |
191 | export class GeoJsonElement extends GeoJSONCoordinateHandler {
192 | originalObject: any = Object.assign({}, this.geojson);
193 | globalId: string = this.guidService.newGuid();
194 |
195 | constructor(
196 | private mapService: MapService,
197 | private groupService: GroupService,
198 | private popupService: PopupService,
199 | private guidService: GuidService,
200 | private helperService: HelperService,
201 | @Optional() private LeafletElement?: LeafletElement,
202 | @Optional() private LeafletGroup?: LeafletGroup) {
203 | super();
204 | }
205 |
206 | ngOnInit() {
207 | //check if any of the two optional injections exist
208 | E if (this.LeafletElement || this.LeafletGroup) {
209 | //polyline shouldn't have a fill
210 | let map = this.mapService.getMap();
211 |
212 | E if (this.geojson) {
213 | super.transformJSONCoordinates(this.geojson, this.LeafletElement.crs);
214 |
215 | let gjson = L.geoJSON(this.geojson);
216 |
217 | I if (this.LeafletGroup) {
218 | this.groupService.addOLayersToGroup(gjson, map, this.mapService, this.LeafletGroup, false, this.globalId);
219 | } else {
220 | gjson.addTo(map);
221 | }
222 | } else {
223 | console.warn("geojson object seems to be undefined");
224 | }
225 | } else {
226 | console.warn("This polyline-element will not be rendered \n the expected parent node of polyline-element should be either leaf-element or leaflet-group");
227 | }
228 |
229 | }
230 |
231 | ngDoCheck() {
232 | let map = this.mapService.getMap();
233 | }
234 | }
235 |
236 |
237 |
238 |
239 |
243 |
244 |
245 |
252 |
253 |
254 |
255 |
--------------------------------------------------------------------------------
/coverage/geojson/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for geojson\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | all files geojson/
20 |
21 |
22 |
23 | 92.11%
24 | Statements
25 | 35/38
26 |
27 |
28 | 60%
29 | Branches
30 | 6/10
31 |
32 |
33 | 100%
34 | Functions
35 | 4/4
36 |
37 |
38 | 91.43%
39 | Lines
40 | 32/35
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | geojson.ts
63 |
64 | 92.11%
65 | 35/38
66 | 60%
67 | 6/10
68 | 100%
69 | 4/4
70 | 91.43%
71 | 32/35
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/coverage/group/group.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for group\group.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 73.33%
24 | Statements
25 | 11/15
26 |
27 |
28 | 100%
29 | Branches
30 | 0/0
31 |
32 |
33 | 25%
34 | Functions
35 | 1/4
36 |
37 |
38 | 69.23%
39 | Lines
40 | 9/13
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34 1×
80 | 1×
81 | 1×
82 | 1×
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | 1×
95 | 1×
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | 1×
105 |
106 |
107 | 1×
108 |
109 |
110 |
111 | 1×
112 | import { Component, Input } from '@angular/core';
113 | import { MapService } from '../services/map.service';
114 | import { GroupService } from '../services/group.service';
115 | import { GuidService } from '../services/globalId.service';
116 | import * as L from 'leaflet';
117 |
118 |
119 | @Component({
120 | moduleId: module.id.toString(),
121 | selector: 'leaflet-group',
122 | templateUrl: 'group.html',
123 | styleUrls: ['group.css'],
124 | providers: [GroupService]
125 | })
126 |
127 | export class LeafletGroup {
128 | @Input() name: string = '';
129 | globalId: string = this.guidService.newGuid();
130 |
131 | constructor(
132 | private mapService: MapService,
133 | private groupService: GroupService,
134 | private guidService: GuidService) {
135 | }
136 |
137 | ngOnInit() {
138 | }
139 |
140 | ngAfterViewInit() {
141 | }
142 |
143 |
144 | }
145 |
146 |
147 |
148 |
149 |
153 |
154 |
155 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/coverage/group/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for group\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 73.33%
24 | Statements
25 | 11/15
26 |
27 |
28 | 100%
29 | Branches
30 | 0/0
31 |
32 |
33 | 25%
34 | Functions
35 | 1/4
36 |
37 |
38 | 69.23%
39 | Lines
40 | 9/13
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | group.ts
63 |
64 | 73.33%
65 | 11/15
66 | 100%
67 | 0/0
68 | 25%
69 | 1/4
70 | 69.23%
71 | 9/13
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/coverage/helpers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for helpers\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | all files helpers/
20 |
21 |
22 |
23 | 58.33%
24 | Statements
25 | 56/96
26 |
27 |
28 | 50%
29 | Branches
30 | 22/44
31 |
32 |
33 | 50%
34 | Functions
35 | 11/22
36 |
37 |
38 | 56.99%
39 | Lines
40 | 53/93
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | coodinateHandler.ts
63 |
64 | 54.55%
65 | 24/44
66 | 27.27%
67 | 6/22
68 | 71.43%
69 | 5/7
70 | 53.49%
71 | 23/43
72 |
73 |
74 |
75 | geoJsonReader.ts
76 |
77 | 61.54%
78 | 32/52
79 | 72.73%
80 | 16/22
81 | 40%
82 | 6/15
83 | 60%
84 | 30/50
85 |
86 |
87 |
88 |
89 |
90 |
91 |
95 |
96 |
97 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/coverage/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for All files
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | /
20 |
21 |
22 |
23 | 59.23%
24 | Statements
25 | 276/466
26 |
27 |
28 | 23.9%
29 | Branches
30 | 38/159
31 |
32 |
33 | 51.61%
34 | Functions
35 | 48/93
36 |
37 |
38 | 57.24%
39 | Lines
40 | 249/435
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | circle/
63 |
64 | 65.22%
65 | 30/46
66 | 14.29%
67 | 2/14
68 | 50%
69 | 2/4
70 | 62.79%
71 | 27/43
72 |
73 |
74 |
75 | geojson/
76 |
77 | 92.11%
78 | 35/38
79 | 60%
80 | 6/10
81 | 100%
82 | 4/4
83 | 91.43%
84 | 32/35
85 |
86 |
87 |
88 | group/
89 |
90 | 73.33%
91 | 11/15
92 | 100%
93 | 0/0
94 | 25%
95 | 1/4
96 | 69.23%
97 | 9/13
98 |
99 |
100 |
101 | helpers/
102 |
103 | 58.33%
104 | 56/96
105 | 50%
106 | 22/44
107 | 50%
108 | 11/22
109 | 56.99%
110 | 53/93
111 |
112 |
113 |
114 | map/
115 |
116 | 83.33%
117 | 35/42
118 | 50%
119 | 5/10
120 | 80%
121 | 4/5
122 | 82.05%
123 | 32/39
124 |
125 |
126 |
127 | models/
128 |
129 | 85%
130 | 17/20
131 | 25%
132 | 1/4
133 | 100%
134 | 2/2
135 | 84.21%
136 | 16/19
137 |
138 |
139 |
140 | services/
141 |
142 | 38.1%
143 | 72/189
144 | 2.6%
145 | 2/77
146 | 34.88%
147 | 15/43
148 | 35.06%
149 | 61/174
150 |
151 |
152 |
153 | test/
154 |
155 | 100%
156 | 20/20
157 | 100%
158 | 0/0
159 | 100%
160 | 9/9
161 | 100%
162 | 19/19
163 |
164 |
165 |
166 |
167 |
168 |
169 |
173 |
174 |
175 |
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/coverage/map/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for map\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 83.33%
24 | Statements
25 | 35/42
26 |
27 |
28 | 50%
29 | Branches
30 | 5/10
31 |
32 |
33 | 80%
34 | Functions
35 | 4/5
36 |
37 |
38 | 82.05%
39 | Lines
40 | 32/39
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | map.ts
63 |
64 | 83.33%
65 | 35/42
66 | 50%
67 | 5/10
68 | 80%
69 | 4/5
70 | 82.05%
71 | 32/39
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/coverage/map/map.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for map\map.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 83.33%
24 | Statements
25 | 35/42
26 |
27 |
28 | 50%
29 | Branches
30 | 5/10
31 |
32 |
33 | 80%
34 | Functions
35 | 4/5
36 |
37 |
38 | 82.05%
39 | Lines
40 | 32/39
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34
80 | 35
81 | 36
82 | 37
83 | 38
84 | 39
85 | 40
86 | 41
87 | 42
88 | 43
89 | 44
90 | 45
91 | 46
92 | 47
93 | 48
94 | 49
95 | 50
96 | 51
97 | 52
98 | 53
99 | 54
100 | 55
101 | 56
102 | 57
103 | 58
104 | 59
105 | 60
106 | 61
107 | 62
108 | 63
109 | 64
110 | 65
111 | 66
112 | 67
113 | 68
114 | 69
115 | 70
116 | 71
117 | 72
118 | 73
119 | 74
120 | 75
121 | 76
122 | 77
123 | 78
124 | 79 1×
125 | 1×
126 | 1×
127 | 1×
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | 1×
138 | 4×
139 | 4×
140 | 4×
141 | 4×
142 | 4×
143 | 4×
144 | 4×
145 | 1×
146 | 4×
147 | 1×
148 |
149 | 3×
150 |
151 | 3×
152 | 3×
153 |
154 |
155 | 1×
156 | 2×
157 |
158 | 2×
159 | 1×
160 | 1×
161 | 1×
162 |
163 |
164 |
165 |
166 |
167 |
168 | 2×
169 |
170 | 2×
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 | 2×
183 |
184 |
185 | 2×
186 | 2×
187 |
188 |
189 | 1×
190 |
191 |
192 | 1×
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | 1×
202 | import { Component, Input, ViewChild, ElementRef, EventEmitter } from '@angular/core';
203 | import { MapService } from '../services/map.service';
204 | import { CoordinateHandler } from '../helpers/coodinateHandler';
205 | import * as L from 'leaflet';
206 |
207 | @Component({
208 | moduleId: module.id.toString(),
209 | selector: 'leaf-element',
210 | templateUrl: 'map.html',
211 | styleUrls: ['map.css'],
212 | providers: [MapService]
213 | })
214 |
215 | export class LeafletElement extends CoordinateHandler {
216 | @Input() lat: number = 52.6;
217 | @Input() lon: number = -1.1;
218 | @Input() zoom: number = 12;
219 | @Input() minZoom: number = 4;
220 | @Input() maxZoom: number = 19;
221 | @Input() layerControl: boolean = false;
222 | @Input() crs: any = L.CRS.EPSG3857;
223 | @Input() zoomControl: boolean;
224 | @Input() maxBounds: L.LatLngBounds = null;
225 | @ViewChild('map') mapElement: ElementRef;
226 |
227 | layerControlObject = null;
228 |
229 | constructor(private mapService: MapService) {
230 | super();
231 | }
232 |
233 | ngOnInit() {
234 | super.assignCartesianPointToLeafletsLatLngSchema();
235 |
236 | if (typeof (this.crs) === "string") {
237 | var splitCrs = this.crs.split(".");
238 | E if (splitCrs[0] === "L") {
239 | this.crs = L[splitCrs[1]][splitCrs[2]];
240 | } else {
241 | console.warn("something is not right, reverting to default EPSG3857");
242 | this.crs = L.CRS.EPSG3857;
243 | }
244 | }
245 |
246 | super.transformPointCoordinates(this.crs);
247 |
248 | let map = L.map(this.mapElement.nativeElement, {
249 | crs: this.crs,
250 | zoomControl: this.zoomControl,
251 | center: L.latLng(this.lat, this.lon),
252 | zoom: this.zoom,
253 | minZoom: this.minZoom,
254 | maxZoom: this.maxZoom,
255 | maxBounds: this.maxBounds,
256 | layers: [],
257 | closePopupOnClick: false,
258 | attributionControl: false
259 | });
260 | this.mapElement.nativeElement.myMapProperty = map;
261 |
262 | //set variables for childrent components
263 | this.mapService.setMap(map);
264 | this.mapService.setLayerControl(this.layerControl);
265 | }
266 |
267 | ngAfterViewInit() {
268 | }
269 |
270 | setLayerControl() {
271 | if (this.layerControl) {
272 | let map = this.mapService.getMap();
273 | if (this.layerControlObject !== null) {
274 | this.layerControlObject.getContainer().innerHTML = '';
275 | }
276 | this.layerControlObject = L.control.layers(this.mapService.getBasemaps(), this.mapService.getOverlays()).addTo(map);
277 | }
278 | }
279 | }
280 |
281 |
282 |
283 |
284 |
288 |
289 |
290 |
297 |
298 |
299 |
300 |
--------------------------------------------------------------------------------
/coverage/models/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for models\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 85%
24 | Statements
25 | 17/20
26 |
27 |
28 | 25%
29 | Branches
30 | 1/4
31 |
32 |
33 | 100%
34 | Functions
35 | 2/2
36 |
37 |
38 | 84.21%
39 | Lines
40 | 16/19
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | path.ts
63 |
64 | 85%
65 | 17/20
66 | 25%
67 | 1/4
68 | 100%
69 | 2/2
70 | 84.21%
71 | 16/19
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/coverage/models/path.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for models\path.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 85%
24 | Statements
25 | 17/20
26 |
27 |
28 | 25%
29 | Branches
30 | 1/4
31 |
32 |
33 | 100%
34 | Functions
35 | 2/2
36 |
37 |
38 | 84.21%
39 | Lines
40 | 16/19
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26 1×
72 |
73 | 1×
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | 1×
82 | 1×
83 | 1×
84 | 1×
85 | 1×
86 | 1×
87 | 1×
88 | 1×
89 | 1×
90 | 1×
91 | 1×
92 | 1×
93 |
94 | 1×
95 | 1×
96 | export class path {
97 | constructor(pathInfo: any) {
98 | I if (pathInfo !== null) {
99 | for (var key in pathInfo) {
100 | if (pathInfo[key] !== undefined) {
101 | this[key] = pathInfo[key];
102 | }
103 | }
104 | }
105 | }
106 | stroke: boolean = true; //Whether to draw stroke along the path. Set it to false to disable borders on polygons or circles.
107 | color: string = '#3388ff'; //Stroke color
108 | weight: number = 3; //Stroke width in pixels
109 | opacity: number = 1; //Stroke opacity
110 | lineCap: string = 'round'; // A string that defines shape to be used at the end of the stroke.
111 | lineJoin: string = 'round'; //A string that defines shape to be used at the corners of the stroke.
112 | dashArray: string = null; //A string that defines the stroke dash pattern. Doesn't work on Canvas-powered layers in some old browsers.
113 | dashOffset: string = null; //A string that defines the distance into the dash pattern to start the dash. Doesn't work on Canvas-powered layers in some old browsers.
114 | fill: boolean = true; //Whether to fill the path with color. Set it to false to disable filling on polygons or circles.
115 | fillColor: string = '#3388ff'; //Fill color. Defaults to the value of the color option
116 | fillOpacity: number = 0.2; // Fill opacity.
117 | fillRule: string = 'evenodd'; // A string that defines how the inside of a shape is determined.
118 | //TODO renderer: Renderer; Use this specific instance of Renderer for this path. Takes precedence over the map's default renderer.
119 | className: string = null; //null Custom class name set on an element. Only for SVG renderer.
120 | }
121 |
122 |
123 |
124 |
125 |
129 |
130 |
131 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/coverage/prettify.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
2 |
--------------------------------------------------------------------------------
/coverage/services/globalId.service.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for services\globalId.service.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 100%
24 | Statements
25 | 10/10
26 |
27 |
28 | 100%
29 | Branches
30 | 2/2
31 |
32 |
33 | 100%
34 | Functions
35 | 4/4
36 |
37 |
38 | 100%
39 | Lines
40 | 7/7
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15 1×
61 |
62 |
63 |
64 | 1×
65 |
66 |
67 |
68 | 1×
69 | 1×
70 | 31×
71 | 31×
72 |
73 |
74 | 1× import { Injectable } from '@angular/core';
75 |
76 |
77 | @Injectable()
78 | export class GuidService {
79 |
80 | constructor() { }
81 |
82 | newGuid() {
83 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
84 | var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
85 | return v.toString(16);
86 | });
87 | }
88 | }
89 |
90 |
91 |
92 |
96 |
97 |
98 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/coverage/services/group.service.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for services\group.service.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 39.13%
24 | Statements
25 | 18/46
26 |
27 |
28 | 0%
29 | Branches
30 | 0/14
31 |
32 |
33 | 25%
34 | Functions
35 | 2/8
36 |
37 |
38 | 38.1%
39 | Lines
40 | 16/42
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34
80 | 35
81 | 36
82 | 37
83 | 38
84 | 39
85 | 40
86 | 41
87 | 42
88 | 43
89 | 44
90 | 45
91 | 46
92 | 47
93 | 48
94 | 49
95 | 50
96 | 51
97 | 52
98 | 53
99 | 54
100 | 55
101 | 56
102 | 57
103 | 58
104 | 59
105 | 60
106 | 61
107 | 62
108 | 63
109 | 64
110 | 65
111 | 66 1×
112 | 1×
113 | 1×
114 | 1×
115 |
116 |
117 |
118 | 1×
119 | 2×
120 | 2×
121 | 2×
122 | 2×
123 |
124 | 2×
125 |
126 | 1×
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | 1×
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | 1×
166 |
167 |
168 |
169 | 1×
170 |
171 |
172 |
173 | 1×
174 |
175 |
176 | 1× import { Injectable } from '@angular/core';
177 | import { Observable } from 'rxjs/Rx';
178 | import { GuidService } from '../services/globalId.service';
179 | import * as L from 'leaflet';
180 |
181 |
182 | @Injectable()
183 | export class GroupService {
184 | private layerGroup: Array<any> = [];
185 | private layerId: Array<any> = [];
186 | private layerGroupNumber: number = 0;
187 | private group: any = {};
188 |
189 | constructor(private guidService: GuidService) { }
190 |
191 | public addOLayersToGroup(overlay, map, mapService, group, replace = false, gId?: String) {
192 | if (!gId) {
193 | gId = this.guidService.newGuid();
194 | }
195 | if (this.layerId.indexOf(gId) === -1) {
196 | this.layerId.push(gId);
197 | }
198 | if (Object.keys(this.group).length !== 0) {
199 | if (replace) {
200 | map.removeLayer(this.group);
201 | if (this.layerId.indexOf(gId) !== -1) {
202 | this.layerGroup[this.layerId.indexOf(gId)] = overlay;
203 | } else {
204 | this.layerGroup.push(overlay);
205 | }
206 | this.group = L.layerGroup(this.getLayerGroup());
207 | this.group.addTo(map);
208 | } else {
209 | this.layerGroup.push(overlay);
210 | this.group.addLayer(overlay);
211 | }
212 | }
213 | if (!replace) {
214 | this.layerGroup.push(overlay);
215 | this.group = L.layerGroup(this.getLayerGroup());
216 | this.group.addTo(map);
217 | }
218 |
219 | mapService.addOverlay(this.getGroup(), group.name, group.globalId);
220 | }
221 |
222 | public getObservableGroup() {
223 | return Observable.create(observer => {
224 | var group = this.getGroup();
225 | observer.next(group);
226 | observer.complete();
227 | });
228 | }
229 |
230 | public getGroup() {
231 | return this.group;
232 | }
233 |
234 | public getLayerGroup() {
235 | return this.layerGroup;
236 | }
237 |
238 | public getLayerNumber() {
239 | return this.layerGroupNumber;
240 | }
241 | }
242 |
243 |
244 |
245 |
249 |
250 |
251 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/coverage/services/helper.service.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for services\helper.service.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 40%
24 | Statements
25 | 6/15
26 |
27 |
28 | 0%
29 | Branches
30 | 0/10
31 |
32 |
33 | 66.67%
34 | Functions
35 | 2/3
36 |
37 |
38 | 30.77%
39 | Lines
40 | 4/13
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26 1×
72 |
73 |
74 |
75 | 1×
76 |
77 |
78 |
79 | 1×
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 1× import { Injectable } from '@angular/core';
97 |
98 |
99 | @Injectable()
100 | export class HelperService {
101 |
102 | constructor() { }
103 |
104 | arrayCompare(a, b) {
105 | if (a.length != b.length) {
106 | return false;
107 | }
108 | for (var i in a) {
109 | // Don't forget to check for arrays in our arrays.
110 | if (a[i] instanceof Array && b[i] instanceof Array) {
111 | if (!this.arrayCompare(a[i], b[i])) {
112 | return false;
113 | }
114 | }
115 | else if (a[i] != b[i]) {
116 | return false;
117 | }
118 | }
119 | return true;
120 | }
121 | }
122 |
123 |
124 |
125 |
129 |
130 |
131 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/coverage/services/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for services\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | all files services/
20 |
21 |
22 |
23 | 38.1%
24 | Statements
25 | 72/189
26 |
27 |
28 | 2.6%
29 | Branches
30 | 2/77
31 |
32 |
33 | 34.88%
34 | Functions
35 | 15/43
36 |
37 |
38 | 35.06%
39 | Lines
40 | 61/174
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | globalId.service.ts
63 |
64 | 100%
65 | 10/10
66 | 100%
67 | 2/2
68 | 100%
69 | 4/4
70 | 100%
71 | 7/7
72 |
73 |
74 |
75 | group.service.ts
76 |
77 | 39.13%
78 | 18/46
79 | 0%
80 | 0/14
81 | 25%
82 | 2/8
83 | 38.1%
84 | 16/42
85 |
86 |
87 |
88 | helper.service.ts
89 |
90 | 40%
91 | 6/15
92 | 0%
93 | 0/10
94 | 66.67%
95 | 2/3
96 | 30.77%
97 | 4/13
98 |
99 |
100 |
101 | map.service.ts
102 |
103 | 36.78%
104 | 32/87
105 | 0%
106 | 0/22
107 | 25%
108 | 5/20
109 | 36.14%
110 | 30/83
111 |
112 |
113 |
114 | popup.service.ts
115 |
116 | 19.35%
117 | 6/31
118 | 0%
119 | 0/29
120 | 25%
121 | 2/8
122 | 13.79%
123 | 4/29
124 |
125 |
126 |
127 |
128 |
129 |
130 |
134 |
135 |
136 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/coverage/services/popup.service.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for services\popup.service.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 19.35%
24 | Statements
25 | 6/31
26 |
27 |
28 | 0%
29 | Branches
30 | 0/29
31 |
32 |
33 | 25%
34 | Functions
35 | 2/8
36 |
37 |
38 | 13.79%
39 | Lines
40 | 4/29
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34
80 | 35
81 | 36
82 | 37
83 | 38
84 | 39
85 | 40
86 | 41
87 | 42
88 | 43
89 | 44
90 | 45
91 | 46
92 | 47 1×
93 |
94 |
95 |
96 | 1×
97 |
98 |
99 |
100 | 1×
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | 1× import { Injectable } from '@angular/core';
139 |
140 |
141 | @Injectable()
142 | export class PopupService {
143 |
144 | constructor() { }
145 |
146 | public enablePopup(mouseover, onclick, element, text) {
147 | if (mouseover && onclick) {
148 | mouseover = undefined;
149 | console.warn('you can not use mouseover and onclick at the same time, mouseover is going to be depressed');
150 | }
151 | if (mouseover) {
152 | if (mouseover === 'true' && text) {
153 | mouseover = text;
154 | } else if (mouseover === true && !text) {
155 | mouseover = "true";
156 | }
157 | element.bindPopup(mouseover);
158 | element.on('mouseover', function () {
159 | this.openPopup();
160 | }).on('mouseout', function () {
161 | this.closePopup();
162 | });
163 | }
164 | if (onclick) {
165 | if (onclick === 'true' && text) {
166 | onclick = text;
167 | } else if (onclick === true && !text) {
168 | onclick = "true";
169 | }
170 | element.bindPopup(onclick);
171 | element.on('click', function () {
172 | this.openPopup();
173 | })
174 | }
175 | if (!mouseover && !onclick && text) {
176 | element.bindPopup(text);
177 | element.on('mouseover', function () {
178 | this.openPopup();
179 | }).on('mouseout', function () {
180 | this.closePopup();
181 | });
182 | }
183 | }
184 | }
185 |
186 |
187 |
188 |
192 |
193 |
194 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/coverage/sort-arrow-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elasticrash/ngx.leaflet.component/83c75124fc71209990268876b2914ba921113b61/coverage/sort-arrow-sprite.png
--------------------------------------------------------------------------------
/coverage/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for test\
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 100%
24 | Statements
25 | 20/20
26 |
27 |
28 | 100%
29 | Branches
30 | 0/0
31 |
32 |
33 | 100%
34 | Functions
35 | 9/9
36 |
37 |
38 | 100%
39 | Lines
40 | 19/19
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | File
50 |
51 | Statements
52 |
53 | Branches
54 |
55 | Functions
56 |
57 | Lines
58 |
59 |
60 |
61 |
62 | main.test.ts
63 |
64 | 100%
65 | 20/20
66 | 100%
67 | 0/0
68 | 100%
69 | 8/8
70 | 100%
71 | 19/19
72 |
73 |
74 |
75 | tsloader.ts
76 |
77 | 100%
78 | 0/0
79 | 100%
80 | 0/0
81 | 100%
82 | 1/1
83 | 100%
84 | 0/0
85 |
86 |
87 |
88 |
89 |
90 |
91 |
95 |
96 |
97 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/coverage/test/main.test.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for test\main.test.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 100%
24 | Statements
25 | 20/20
26 |
27 |
28 | 100%
29 | Branches
30 | 0/0
31 |
32 |
33 | 100%
34 | Functions
35 | 8/8
36 |
37 |
38 | 100%
39 | Lines
40 | 19/19
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14
60 | 15
61 | 16
62 | 17
63 | 18
64 | 19
65 | 20
66 | 21
67 | 22
68 | 23
69 | 24
70 | 25
71 | 26
72 | 27
73 | 28
74 | 29
75 | 30
76 | 31
77 | 32
78 | 33
79 | 34
80 | 35
81 | 36
82 | 37
83 | 38 1×
84 |
85 | 1×
86 | 1×
87 | 1×
88 | 1×
89 | 1×
90 | 1×
91 | 1×
92 | 1×
93 |
94 |
95 |
96 |
97 |
98 |
99 | 1×
100 |
101 |
102 | 1×
103 |
104 |
105 |
106 |
107 | 1×
108 | 1×
109 |
110 |
111 |
112 |
113 | 1×
114 | 1×
115 | 1×
116 | 1×
117 | 1×
118 | 1×
119 |
120 | import 'core-js'; // ES6 + reflect-metadata
121 | // zone.js
122 | import 'zone.js/dist/zone';
123 | import 'zone.js/dist/long-stack-trace-zone';
124 | import 'zone.js/dist/proxy.js';
125 | import 'zone.js/dist/sync-test';
126 | import 'zone.js/dist/jasmine-patch';
127 | import 'zone.js/dist/async-test';
128 | import 'zone.js/dist/fake-async-test';
129 | import 'leaflet/dist/leaflet';
130 |
131 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
132 | declare var __karma__: any;
133 | declare var require: any;
134 |
135 | // Prevent Karma from running prematurely.
136 | __karma__.loaded = function () { };
137 | declare var System: any;
138 |
139 | Promise.all([
140 | System.import('@angular/core/testing'),
141 | System.import('@angular/platform-browser-dynamic/testing')
142 | ])
143 | // First, initialize the Angular testing environment.
144 | .then(([testing, testingBrowser]) => {
145 | testing.getTestBed().initTestEnvironment(
146 | testingBrowser.BrowserDynamicTestingModule,
147 | testingBrowser.platformBrowserDynamicTesting()
148 | );
149 | })
150 | .then(() => require.context('../map', true, /\.spec\.ts/))
151 | .then(context => context.keys().map(context))
152 | .then(() => require.context('../geojson', true, /\.spec\.ts/))
153 | .then(context => context.keys().map(context))
154 | .then(() => require.context('../circle', true, /\.spec\.ts/))
155 | .then(context => context.keys().map(context))
156 | // Finally, start Karma to run the tests.
157 | .then(__karma__.start, __karma__.error);
158 |
159 |
160 |
161 |
165 |
166 |
167 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/coverage/test/mock.component.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for test/mock.component.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 | all files / test/ mock.component.ts
20 |
21 |
22 |
23 | 100%
24 | Statements
25 | 6/6
26 |
27 |
28 | 50%
29 | Branches
30 | 1/2
31 |
32 |
33 | 100%
34 | Functions
35 | 3/3
36 |
37 |
38 | 100%
39 | Lines
40 | 5/5
41 |
42 |
43 |
44 |
45 |
46 | 1
47 | 2
48 | 3
49 | 4
50 | 5
51 | 6
52 | 7
53 | 8
54 | 9
55 | 10
56 | 11
57 | 12
58 | 13
59 | 14 1×
60 |
61 | 1×
62 | 2×
63 |
64 |
65 |
66 |
67 |
68 |
69 | 2×
70 |
71 | 2×
72 | import { Component } from '@angular/core';
73 |
74 | export function MockComponent(options: Component): Component {
75 | let metadata: Component = {
76 | selector: options.selector,
77 | template: options.template || '',
78 | inputs: options.inputs,
79 | outputs: options.outputs
80 | };
81 |
82 | class Mock {}
83 |
84 | return Component(metadata)(Mock);
85 | }
86 |
87 |
88 |
89 |
93 |
94 |
95 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/coverage/test/tsloader.ts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Code coverage report for test\tsloader.ts
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 | 100%
24 | Statements
25 | 0/0
26 |
27 |
28 | 100%
29 | Branches
30 | 0/0
31 |
32 |
33 | 100%
34 | Functions
35 | 1/1
36 |
37 |
38 | 100%
39 | Lines
40 | 0/0
41 |
42 |
43 |
44 |
45 |
46 | 1 require('./main.test.ts');
47 |
48 |
49 |
50 |
54 |
55 |
56 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 | basePath: '',
4 | frameworks: ['jasmine'],
5 | files: [
6 | { pattern: 'src/test/tsloader.js', watched: false },
7 | ],
8 | exclude: [
9 | ],
10 | preprocessors: {
11 | 'src/test/tsloader.js': ['webpack', 'sourcemap','coverage'],
12 | },
13 | webpack: require('./webpack.config')({ env: 'test' }),
14 | reporters: ['spec', 'coverage', 'remap-coverage'],
15 | port: 9876,
16 | colors: true,
17 | logLevel: config.LOG_DEBUG,
18 | autoWatch: true,
19 | browsers: ['ChromeHeadless'],
20 | coverageReporter: {
21 | reporters: [
22 | { type: 'json', subdir: '.', file: 'coverage.json' },
23 | { type : 'text-summary'},
24 | ]
25 | },
26 | singleRun: true,
27 | concurrency: Infinity
28 | });
29 | };
--------------------------------------------------------------------------------
/ngx.leaflet.components.ts:
--------------------------------------------------------------------------------
1 | export * from './public_api';
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngx.leaflet.components",
3 | "version": "2.0.0",
4 | "description": "an angular.io component collection for leaflet",
5 | "main": "./bundles/src/ngx.leaflet.components.umd.js",
6 | "jsnext:main": "./esm5/src/ngx.leaflet.components.js",
7 | "module": "./esm5/src/ngx.leaflet.components.js",
8 | "es2015": "./esm2015/src/ngx.leaflet.components.js",
9 | "types": "./src/ngx.leaflet.components.d.ts",
10 | "scripts": {
11 | "start": "npm run clean && tsc",
12 | "tsc": "tsc",
13 | "tsc:w": "tsc -w",
14 | "ngc": "ngc",
15 | "build": "node build.js",
16 | "pretest": "node cleanup.js",
17 | "test": "karma start karma.conf.js",
18 | "coverage": "http-server -c-1 -o -p 9875 ./coverage",
19 | "remap": "node_modules/.bin/remap-istanbul -i coverage/coverage.json -o coverage -t html",
20 | "documentation": "./node_modules/.bin/compodoc -p tsconfig.json"
21 | },
22 | "keywords": [
23 | "angular",
24 | "javascript",
25 | "typescript",
26 | "leaflet",
27 | "spatial"
28 | ],
29 | "repository": {
30 | "type": "git",
31 | "url": "http://github.com/elasticrash/ngx.leaflet.component.git"
32 | },
33 | "author": "Stefanos Kouroupis",
34 | "contributors": [
35 | {
36 | "name": "Giorgos Papapdakis",
37 | "url": "https://github.com/xalikoutis"
38 | }
39 | ],
40 | "license": "ISC",
41 | "bugs": {
42 | "url": "https://github.com/elasticrash/ngx.leaflet.component/issues"
43 | },
44 | "peerDependencies": {
45 | "tslib": "1.9.2",
46 | "@angular/core": ">=6.0.0",
47 | "@angular/http": ">=6.0.0",
48 | "@angular/common": ">=6.0.0",
49 | "rxjs": ">=6.0.0",
50 | "leaflet": ">=1.0.0",
51 | "typescript": ">=2.7.2"
52 | },
53 | "homepage": "https://github.com/elasticrash/ngx.leaflet.component#readme",
54 | "devDependencies": {
55 | "@angular/common": "6.0.5",
56 | "@angular/compiler": "6.0.5",
57 | "@angular/compiler-cli": "6.0.5",
58 | "@angular/core": "6.0.5",
59 | "@angular/http": "6.0.5",
60 | "@angular/platform-browser": "6.0.5",
61 | "@angular/platform-browser-dynamic": "6.0.5",
62 | "@compodoc/compodoc": "1.1.3",
63 | "@types/geojson": "7946.0.3",
64 | "@types/jasmine": "2.8.8",
65 | "@types/leaflet": "1.2.7",
66 | "angular2-template-loader": "https://github.com/elasticrash/angular2-template-loader.git",
67 | "awesome-typescript-loader": "5.0.0",
68 | "chalk": "2.3.0",
69 | "codelyzer": "4.0.0",
70 | "core-js": "^2.5.0",
71 | "css-loader": "^0.26.4",
72 | "es-module-loader": "^1.3.5",
73 | "es6-shim": "^0.35.3",
74 | "html-loader": "^0.4.5",
75 | "http-server": "0.11.1",
76 | "istanbul-instrumenter-loader": "^1.2.0",
77 | "jasmine": "^2.7.0",
78 | "jasmine-core": "^2.7.0",
79 | "jasmine-spec-reporter": "2.5.0",
80 | "karma": "1.2.0",
81 | "karma-chrome-launcher": "^2.2.0",
82 | "karma-cli": "^1.0.1",
83 | "karma-coverage": "^1.1.1",
84 | "karma-jasmine": "^1.1.0",
85 | "karma-phantomjs-launcher": "^1.0.4",
86 | "karma-remap-coverage": "^0.1.4",
87 | "karma-sourcemap-loader": "^0.3.7",
88 | "karma-spec-reporter": "0.0.26",
89 | "karma-webpack": "2.0.6",
90 | "leaflet": ">=1.0.0",
91 | "node-sass": "^4.6.0",
92 | "node-static": "^0.7.9",
93 | "phantomjs-prebuilt": "2.1.16",
94 | "plugin-typescript": "^5.3.3",
95 | "protractor": "~4.0.13",
96 | "reflect-metadata": "0.1.10",
97 | "remap-istanbul": "^0.8.4",
98 | "rollup": "^0.51.7",
99 | "rollup-plugin-commonjs": "^8.2.6",
100 | "rollup-plugin-license": "0.5.0",
101 | "rollup-plugin-node-resolve": "3.0.0",
102 | "rollup-plugin-sourcemaps": "0.4.2",
103 | "rxjs": "6.2.1",
104 | "shelljs": "0.7.8",
105 | "source-map-loader": "0.2.3",
106 | "source-map-support": "^0.4.15",
107 | "ts-loader": "3.1.1",
108 | "ts-node": "1.2.1",
109 | "tslint": "^5.10.0",
110 | "typedoc": "^0.8.0",
111 | "typescript": "2.7.2",
112 | "uglify-js": "3.1.6",
113 | "webpack": "^3.8.1",
114 | "zone.js": "^0.8.26"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './src/ngx.leaflet.components';
--------------------------------------------------------------------------------
/rollup.config.esm.js:
--------------------------------------------------------------------------------
1 | import sourcemaps from 'rollup-plugin-sourcemaps';
2 | import commonjs from 'rollup-plugin-commonjs';
3 |
4 | const path = require('path');
5 |
6 | export default {
7 | output: {
8 | format: 'es',
9 | sourcemap: false
10 | },
11 | plugins: [
12 | sourcemaps()
13 | , commonjs({
14 | include: ['node_modules/rxjs/**']
15 | })],
16 | onwarn: () => { return }
17 | }
--------------------------------------------------------------------------------
/rollup.config.umd.js:
--------------------------------------------------------------------------------
1 | import resolve from 'rollup-plugin-node-resolve';
2 | import sourcemaps from 'rollup-plugin-sourcemaps';
3 | import commonjs from 'rollup-plugin-commonjs';
4 |
5 | const globals = {
6 | '@angular/core': 'ng.core',
7 | '@angular/http': 'ng.http',
8 | '@angular/common': 'ng.common',
9 | 'rxjs/Observable': 'Rx',
10 | 'rxjs/add/operator/map': 'Rx.Observable.prototype',
11 | 'rxjs/add/operator/catch': 'Rx.Observable.prototype',
12 | 'leaflet': 'L'
13 | };
14 |
15 | export default {
16 | external: Object.keys(globals),
17 | plugins: [resolve(), sourcemaps(), commonjs({
18 | include: ['node_modules/rxjs/**']
19 | })],
20 | onwarn: () => { return },
21 | output: {
22 | format: 'umd',
23 | name: 'ng.ngxLeafletComponents',
24 | globals: globals,
25 | external: [
26 | '@angular/core',
27 | '@angular/http',
28 | 'rxjs/Observable',
29 | 'rxjs/add/operator/map',
30 | 'rxjs/add/operator/catch',
31 | 'leaflet'
32 | ],
33 | sourcemap: false,
34 | exports: 'named'
35 | }
36 | }
--------------------------------------------------------------------------------
/src/circle/circle.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 | import { By } from '@angular/platform-browser';
3 | import { DebugElement } from '@angular/core';
4 | import { CircleElement } from '../circle/circle';
5 | import { MapService } from '../services/map.service';
6 | import { GroupService } from '../services/group.service';
7 | import { PopupService } from '../services/popup.service';
8 | import { MockComponent } from '../test/mock.component';
9 | import { LeafletElement } from '../map/map';
10 | import { GuidService } from '../services/globalId.service';
11 |
12 | describe('CircleElement', () => {
13 |
14 | const mock: any = MockComponent(
15 | {
16 | selector: "app-element", outputs: [],
17 | template: " "
18 | });
19 |
20 | beforeEach(() => {
21 | TestBed.configureTestingModule({
22 | declarations: [mock,
23 | LeafletElement, CircleElement],
24 | providers: [
25 | MapService,
26 | GroupService,
27 | PopupService,
28 | GuidService
29 | ]
30 | }).compileComponents();
31 | });
32 |
33 | it('circle-element works well', async(() => {
34 | const fixture = TestBed.createComponent(mock);
35 | // const el = fixture.debugElement.nativeElement as HTMLElement;
36 | // fixture.detectChanges();
37 | expect(1).toEqual(1);
38 | }));
39 | });
40 |
--------------------------------------------------------------------------------
/src/circle/circle.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, ElementRef, ViewChild, OnInit, AfterViewInit } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { PopupService } from '../services/popup.service';
7 | import { CoordinateHandler } from '../helpers/coordinateHandler';
8 | import { Path } from '../models/path';
9 | import { Ipath } from '../interfaces/path';
10 | import * as L from 'leaflet';
11 |
12 | @Component({
13 | selector: 'circle-element',
14 | template: `
`,
15 | styles: ['']
16 | })
17 |
18 | export class CircleElement extends CoordinateHandler implements OnInit, AfterViewInit {
19 | @Input() public lat: number = 52.6;
20 | @Input() public lon: number = -1.1;
21 | @Input() public radius: number = 20;
22 | @Input() public mouseover: string | undefined = undefined;
23 | @Input() public onclick: string | undefined = undefined;
24 | @Input() public Options: any = new Path(null);
25 | @ViewChild('ngel') public ngEl: ElementRef;
26 |
27 | public circle: any = null;
28 |
29 | constructor(
30 | private mapService: MapService,
31 | private popupService: PopupService,
32 | @Optional() private groupService?: GroupService,
33 | @Optional() private leafletElement?: LeafletElement,
34 | @Optional() private leafletGroup?: LeafletGroup) {
35 | super();
36 | }
37 |
38 | public ngOnInit() {
39 | super.assignCartesianPointToLeafletsLatLngSchema();
40 |
41 | // check if any of the two optional injections exist
42 | if (this.leafletElement || this.leafletGroup) {
43 | const inheritedOptions: any = new Path(this.Options);
44 | const map = this.mapService.getMap();
45 |
46 | super.transformPointCoordinates(this.leafletElement.crs);
47 |
48 | this.circle = L.circle([this.lat, this.lon], this.radius, inheritedOptions);
49 |
50 | if (this.leafletGroup) {
51 | this.groupService.addOLayersToGroup(this.circle, map, this.mapService, this.leafletGroup);
52 | } else {
53 | this.circle.addTo(map);
54 | }
55 | } else {
56 | // tslint:disable-next-line:no-console
57 | console.warn(`This circle-element will not be rendered
58 | the expected parent node of circle-element should be either leaf-element or leaflet-group`);
59 | }
60 | }
61 |
62 | public ngAfterViewInit() {
63 | if (this.leafletElement || this.leafletGroup) {
64 | let textInput;
65 | if (this.ngEl.nativeElement.childNodes.length > 0) {
66 | const textNode = this.ngEl.nativeElement.childNodes[0];
67 | textInput = textNode.nodeValue;
68 | }
69 |
70 | // add popup methods on element only if any of the tests are not undefined
71 | if (this.mouseover !== undefined || this.onclick !== undefined || textInput !== undefined) {
72 | this.popupService.enablePopup(this.mouseover, this.onclick, this.circle, textInput);
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/circle/index.ts:
--------------------------------------------------------------------------------
1 | export * from './circle';
2 |
--------------------------------------------------------------------------------
/src/circlemarker/circlemarker.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, ElementRef, ViewChild, AfterViewInit, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { PopupService } from '../services/popup.service';
7 | import { CoordinateHandler } from '../helpers/coordinateHandler';
8 | import { Path } from '../models/path';
9 | import { Ipath } from '../interfaces/path';
10 | import * as L from 'leaflet';
11 |
12 | @Component({
13 | selector: 'circle-marker-element',
14 | template: `
`,
15 | styles: ['']
16 | })
17 |
18 | export class CircleMarkerElement extends CoordinateHandler implements OnInit, AfterViewInit {
19 | @Input() public lat: number = 52.6;
20 | @Input() public lon: number = -1.1;
21 | @Input() public mouseover: string | undefined = undefined;
22 | @Input() public onclick: string | undefined = undefined;
23 | @Input() public Options: any = new Path(null);
24 | @ViewChild('ngel') public ngEl: ElementRef;
25 | public circle: any = null;
26 |
27 | constructor(
28 | private mapService: MapService,
29 | private popupService: PopupService,
30 | @Optional() private groupService?: GroupService,
31 | @Optional() private leafletElement?: LeafletElement,
32 | @Optional() private leafletGroup?: LeafletGroup) {
33 | super();
34 | }
35 |
36 | public ngOnInit() {
37 | super.assignCartesianPointToLeafletsLatLngSchema();
38 | // check if any of the two optional injections exist
39 | if (this.leafletElement || this.leafletGroup) {
40 | const inheritedOptions: any = new Path(this.Options);
41 | const map = this.mapService.getMap();
42 |
43 | const elementPosition: any = super.transformPointCoordinates(this.leafletElement.crs);
44 |
45 | this.circle = L.circleMarker([this.lat, this.lon], inheritedOptions);
46 |
47 | if (this.leafletGroup) {
48 | this.groupService.addOLayersToGroup(this.circle, map, this.mapService, this.leafletGroup);
49 | } else {
50 | this.circle.addTo(map);
51 | }
52 | } else {
53 | // tslint:disable-next-line:no-console
54 | console.warn(`This circle-element will not be rendered
55 | the expected parent node of circle-element should be either leaf-element or leaflet-group`);
56 | }
57 | }
58 |
59 | public ngAfterViewInit() {
60 | let textInput;
61 | if (this.ngEl.nativeElement.childNodes.length > 0) {
62 | const textNode = this.ngEl.nativeElement.childNodes[0];
63 | textInput = textNode.nodeValue;
64 | }
65 |
66 | // add popup methods on element only if any of the tests are not undefined
67 | if (this.mouseover !== undefined || this.onclick !== undefined || textInput !== undefined) {
68 | this.popupService.enablePopup(this.mouseover, this.onclick, this.circle, textInput);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/circlemarker/index.ts:
--------------------------------------------------------------------------------
1 | export * from './circlemarker';
2 |
--------------------------------------------------------------------------------
/src/geojson/geojson.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 | import { By } from '@angular/platform-browser';
3 | import { DebugElement } from '@angular/core';
4 | import { GeoJsonElement } from './geojson';
5 | import { MapService } from '../services/map.service';
6 | import { GroupService } from '../services/group.service';
7 | import { PopupService } from '../services/popup.service';
8 | import { GuidService } from '../services/globalId.service';
9 | import { HelperService } from '../services/helper.service';
10 | import { LeafletElement } from '../map/map';
11 | import { LeafletGroup } from '../group/group';
12 | import { MockComponent } from '../test/mock.component';
13 |
14 | describe('GeoJsonElement', () => {
15 |
16 | const g = {
17 | type: "FeatureCollection",
18 | features: [{
19 | type: "Feature",
20 | geometry: {
21 | type: "Point",
22 | coordinates: [375000, 4202000]
23 | },
24 | properties: {
25 | prop0: "value0"
26 | }
27 | }, {
28 | type: "Feature",
29 | geometry: {
30 | type: "LineString",
31 | coordinates: [[376000, 4202500], [377000, 4203500]]
32 | },
33 | properties: {
34 | prop0: "value1"
35 | }
36 | }]
37 | };
38 | const mock: any = MockComponent(
39 | {
40 | selector: "app-element", outputs: [],
41 | template: " "
43 | });
44 |
45 | beforeEach(() => {
46 | TestBed.configureTestingModule({
47 | declarations: [mock, LeafletElement, GeoJsonElement],
48 | providers: [
49 | MapService,
50 | GroupService,
51 | PopupService,
52 | GuidService,
53 | HelperService
54 | ]
55 | }).compileComponents();
56 | });
57 |
58 | it('geojson component test', async(() => {
59 | const appMock = TestBed.createComponent(mock);
60 | appMock.detectChanges();
61 | const el = appMock.debugElement.nativeElement as HTMLElement;
62 | expect(el.tagName).toEqual("DIV");
63 | }));
64 | });
--------------------------------------------------------------------------------
/src/geojson/geojson.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, DoCheck, Optional } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { PopupService } from '../services/popup.service';
7 | import { GuidService } from '../services/globalId.service';
8 | import { HelperService } from '../services/helper.service';
9 | import { GeoJSONCoordinateHandler } from '../helpers/geoJsonReader';
10 |
11 | import * as L from 'leaflet';
12 |
13 | @Component({
14 | selector: 'geojson-element',
15 | template: ``,
16 | styles: ['']
17 | })
18 |
19 | export class GeoJsonElement extends GeoJSONCoordinateHandler implements OnInit, DoCheck {
20 | public originalObject: any = Object.assign({}, this.geojson);
21 | public globalId: string = this.guidService.newGuid();
22 |
23 | constructor(
24 | private mapService: MapService,
25 | private popupService: PopupService,
26 | private guidService: GuidService,
27 | private helperService: HelperService,
28 | @Optional() private groupService?: GroupService,
29 | @Optional() private leafletElement?: LeafletElement,
30 | @Optional() private leafletGroup?: LeafletGroup) {
31 | super();
32 | }
33 |
34 | public ngOnInit() {
35 | // check if any of the two optional injections exist
36 | if (this.leafletElement || this.leafletGroup) {
37 | // polyline shouldn't have a fill
38 | const map = this.mapService.getMap();
39 |
40 | if (this.geojson) {
41 | super.transformJSONCoordinates(this.geojson, this.leafletElement.crs);
42 |
43 | const gjson = L.geoJSON(this.geojson);
44 |
45 | if (this.leafletGroup) {
46 | this.groupService.addOLayersToGroup(gjson, map, this.mapService, this.leafletGroup, false, this.globalId);
47 | } else {
48 | gjson.addTo(map);
49 | }
50 | } else {
51 | // tslint:disable-next-line:no-console
52 | console.warn("geojson object seems to be undefined");
53 | }
54 | } else {
55 | // tslint:disable-next-line:no-console
56 | console.warn(`This polyline-element will not be rendered
57 | the expected parent node of polyline-element should be either leaf-element or leaflet-group`);
58 | }
59 |
60 | }
61 |
62 | public ngDoCheck() {
63 | const map = this.mapService.getMap();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/geojson/index.ts:
--------------------------------------------------------------------------------
1 | export * from './geojson';
2 |
--------------------------------------------------------------------------------
/src/group/group.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 | import { MapService } from '../services/map.service';
3 | import { GroupService } from '../services/group.service';
4 | import { GuidService } from '../services/globalId.service';
5 |
6 | @Component({
7 | selector: 'leaflet-group',
8 | template: ``,
9 | styles: [''],
10 | providers: [GroupService]
11 | })
12 |
13 | export class LeafletGroup {
14 | @Input() public name: string = '';
15 | public globalId: string = this.guidService.newGuid();
16 |
17 | constructor(
18 | private mapService: MapService,
19 | private groupService: GroupService,
20 | private guidService: GuidService) {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/group/index.ts:
--------------------------------------------------------------------------------
1 | export * from './group';
2 |
--------------------------------------------------------------------------------
/src/helpers/coordinateHandler.ts:
--------------------------------------------------------------------------------
1 | import { Input } from '@angular/core';
2 |
3 | export class CoordinateHandler {
4 | @Input() public lat: number;
5 | @Input() public lon: number;
6 | @Input() public x: number;
7 | @Input() public y: number;
8 | @Input() public latlngs: any;
9 | @Input() public xys: number;
10 |
11 | public assignCartesianPointToLeafletsLatLngSchema() {
12 | if (this.x !== undefined) {
13 | this.lon = this.x;
14 | }
15 |
16 | if (this.y !== undefined) {
17 | this.lat = this.y;
18 | }
19 | }
20 |
21 | public assignCartesianArrayToLeafletsLatLngSchema(arr?) {
22 | if (this.xys !== undefined) {
23 | if (!arr) {
24 | arr = this.xys;
25 | }
26 |
27 | for (const v of arr) {
28 | if (typeof (arr[0]) !== "number") {
29 | this.assignCartesianArrayToLeafletsLatLngSchema(v);
30 | } else {
31 | arr.reverse();
32 | }
33 | }
34 | this.latlngs = this.xys;
35 | }
36 | }
37 |
38 | public transformPointCoordinates(crs) {
39 | /**
40 | * this is because leaflet default CRS is 3857 (so it can render wms properly)
41 | * but uses 4326 everywhere else so if CRS is 3857 don't reproject coordinates
42 | * also proj4 by default unprojects (inverse) to wgs84 (4326) which is handy but
43 | * doesnt match leaflet's default projection. Generally I don't really agree on
44 | * how leaflet doesn't handle projections on a global state
45 | */
46 | if (crs.code && crs.code !== "EPSG:3857") {
47 | const newlatlng = crs.unproject({ y: this.lat, x: this.lon });
48 | this.setNewLatLng(newlatlng);
49 | } else {
50 | const newlatlng = { lat: this.lat, lng: this.lon };
51 | this.setNewLatLng(newlatlng);
52 | }
53 | }
54 |
55 | public setNewLatLng(newlatlng) {
56 | this.lat = newlatlng.lat;
57 | this.lon = newlatlng.lng;
58 | }
59 |
60 | public transformArrayCoordinates(crs, arr?) {
61 | if (!arr) {
62 | arr = this.latlngs;
63 | }
64 | for (let i = 0; i < arr.length; i++) {
65 | if (typeof (arr[0]) !== "number") {
66 | arr[i] = this.transformArrayCoordinates(crs, arr[i]);
67 | } else {
68 | if (crs.code && crs.code !== "EPSG:3857") {
69 | const trasformed = crs.unproject({ x: arr[0], y: arr[1] });
70 | arr = { lat: trasformed.lat, lng: trasformed.lng };
71 | } else {
72 | arr = { lat: arr[0], lng: arr[1] };
73 | }
74 | }
75 | }
76 | return arr;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/helpers/geoJsonReader.ts:
--------------------------------------------------------------------------------
1 | import { Input } from '@angular/core';
2 |
3 | export class GeoJSONCoordinateHandler {
4 | @Input() public geojson: any = {};
5 |
6 | public transformJSONCoordinates(geoJSON: any, crs: any) {
7 | /**
8 | * 7. GeoJSON Types Are Not Extensible
9 | * Implementations MUST NOT extend the fixed set of GeoJSON types:
10 | * FeatureCollection, Feature, Point, LineString, MultiPoint, Polygon,
11 | * MultiLineString, MultiPolygon, and GeometryCollection.
12 | */
13 | if (geoJSON.type === "FeatureCollection") {
14 | const featureCollection = geoJSON;
15 | featureCollection.features.forEach((feature) => {
16 | this.transformJSONCoordinates(feature, crs);
17 | });
18 | }
19 | if (geoJSON.type === "Feature") {
20 | const feature = geoJSON;
21 | this.transformJSONCoordinates(feature.geometry, crs);
22 | }
23 | if (geoJSON.type === "Point") {
24 | const point = geoJSON;
25 | this.transformPointCoordinates(point.coordinates, crs);
26 | }
27 | if (geoJSON.type === "LineString") {
28 | const lineString = geoJSON;
29 | lineString.coordinates.forEach((point) => {
30 | this.transformPointCoordinates(point, crs);
31 | });
32 | }
33 | if (geoJSON.type === "MultiPoint") {
34 | const multiPoint = geoJSON;
35 | multiPoint.coordinates.forEach((point) => {
36 | this.transformPointCoordinates(point, crs);
37 | });
38 | }
39 | if (geoJSON.type === "Polygon") {
40 | const polygon = geoJSON;
41 | polygon.coordinates.forEach((polygonElement) => {
42 | polygonElement.forEach((point) => {
43 | this.transformPointCoordinates(point, crs);
44 | });
45 | });
46 | }
47 | if (geoJSON.type === "MultiLineString") {
48 | const multiLineString = geoJSON;
49 | multiLineString.coordinates.forEach((lineString) => {
50 | lineString.forEach((point) => {
51 | this.transformPointCoordinates(point, crs);
52 | });
53 | });
54 | }
55 | if (geoJSON.type === "MultiPolygon") {
56 | const multiPolygon = geoJSON;
57 | multiPolygon.coordinates.forEach((polygon) => {
58 | polygon.forEach((polygonElement) => {
59 | polygonElement.forEach((point) => {
60 | this.transformPointCoordinates(point, crs);
61 | });
62 | });
63 | });
64 | }
65 | if (geoJSON.type === "GeometryCollection") {
66 | const geometryCollection = geoJSON;
67 | geometryCollection.geometries.forEach((geometry) => {
68 | this.transformJSONCoordinates(geometry, crs);
69 | });
70 | }
71 | }
72 |
73 | public transformPointCoordinates(point, crs) {
74 | /**
75 | * this is because leaflet default CRS is 3857 (so it can render wms properly)
76 | * but uses 4326 everywhere else so if CRS is 3857 don't reproject coordinates
77 | * also proj4 by default unprojects (inverse) to wgs84 (4326) which is handy but
78 | * doesnt match leaflet's default projection. Generally I don't really agree on
79 | * how leaflet doesn't handle projections on a global state
80 | */
81 | if (crs.code && crs.code !== "EPSG:3857") {
82 | const newlatlng = crs.unproject({ x: point[0], y: point[1] });
83 | point[1] = newlatlng.lat;
84 | point[0] = newlatlng.lng;
85 | return point;
86 | } else {
87 | return point;
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/imageoverlay/image-overlay.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { MapService } from '../services/map.service';
4 | import { CoordinateHandler } from '../helpers/coordinateHandler';
5 | import * as L from 'leaflet';
6 |
7 | @Component({
8 | selector: 'image-overlay-element',
9 | template: ``,
10 | styles: ['']
11 | })
12 |
13 | export class ImageOverlayElement extends CoordinateHandler implements OnInit {
14 | @Input() public bounds: any = [[-26.5, -25], [1021.5, 1023]];
15 | @Input() public imagepath: string = '';
16 | @Input() public name: string = '';
17 | @Input() public opacity: number = 1;
18 | @Input() public type: string = 'overlay';
19 | public latlngs: any;
20 |
21 | constructor(
22 | private mapService: MapService,
23 | @Optional() private leafletElement?: LeafletElement) {
24 | super();
25 | }
26 |
27 | public ngOnInit() {
28 | this.latlngs = this.bounds;
29 |
30 | if (this.leafletElement) {
31 | const map = this.mapService.getMap();
32 | super.transformArrayCoordinates(this.leafletElement.crs);
33 |
34 | let layer = null;
35 |
36 | layer = L.imageOverlay(this.imagepath, this.bounds).setOpacity(this.opacity);
37 |
38 | if (layer !== {}) {
39 | if (this.type === "overlay") {
40 | this.mapService.addOverlay(layer, this.name);
41 | layer.addTo(map);
42 | } else if (this.type === "basemap") {
43 | this.mapService.addBasemap(layer, this.name);
44 | }
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/imageoverlay/index.ts:
--------------------------------------------------------------------------------
1 | export * from './image-overlay';
2 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { LeafletElement } from './map/map';
2 | import { AttributionControl } from './map/attribution/attribution';
3 | import { ScaleControl } from './map/scale/scale';
4 | import { ZoomControl } from './map/zoom/zoom';
5 | import { WatermarkControl } from './map/watermark/watermark';
6 |
7 | import { LayerElement } from './layer/layer';
8 | import { ImageOverlayElement } from './imageoverlay/image-overlay';
9 | import { MarkerElement } from './marker/marker';
10 | import { CircleElement } from './circle/circle';
11 | import { CircleMarkerElement } from './circlemarker/circlemarker';
12 | import { PolygonElement } from './polygon/polygon';
13 | import { PolylineElement } from './polyline/polyline';
14 | import { GeoJsonElement } from './geojson/geojson';
15 |
16 | import { PopupElement } from './popup/popup';
17 | import { LeafletGroup } from './group/group';
18 |
19 | import { MapService } from './services/map.service';
20 | import { GroupService } from './services/group.service';
21 | import { PopupService } from './services/popup.service';
22 | import { GuidService } from './services/globalId.service';
23 | import { HelperService } from './services/helper.service';
24 |
25 | export const CandTLeafletComponent = [
26 | // map and controls
27 | LeafletElement,
28 | AttributionControl,
29 | ScaleControl,
30 | ZoomControl,
31 | WatermarkControl,
32 | // layers and vectors
33 | LayerElement,
34 | ImageOverlayElement,
35 | MarkerElement,
36 | CircleElement,
37 | CircleMarkerElement,
38 | PolygonElement,
39 | PolylineElement,
40 | GeoJsonElement,
41 | PopupElement,
42 | // rest
43 | LeafletGroup
44 | ];
45 |
46 | export const CandTLeafletService = [MapService,
47 | GroupService,
48 | PopupService,
49 | GuidService,
50 | HelperService];
51 |
--------------------------------------------------------------------------------
/src/interfaces/path.ts:
--------------------------------------------------------------------------------
1 | export interface Ipath {
2 | stroke: boolean;
3 | color: string;
4 | weight: number;
5 | opacity: number;
6 | lineJoin: string;
7 | dashArray: string;
8 | dashOffset: string;
9 | fill: boolean;
10 | fillColor: string;
11 | fillOpacity: number;
12 | fillRule: string;
13 | className: string;
14 | }
15 |
--------------------------------------------------------------------------------
/src/layer/index.ts:
--------------------------------------------------------------------------------
1 | export * from './layer';
2 |
--------------------------------------------------------------------------------
/src/layer/layer.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, OnInit } from '@angular/core';
2 | import { MapService } from '../services/map.service';
3 | import * as L from 'leaflet';
4 |
5 | @Component({
6 | selector: 'layer-element',
7 | template: ``,
8 | styles: ['']
9 | })
10 |
11 | export class LayerElement implements OnInit {
12 | @Input() public slippyLayer: string = '';
13 | @Input() public wmsLayer: string = '';
14 | @Input() public name: string = '';
15 | @Input() public opacity: number = 1;
16 | @Input() public type: string = 'overlay';
17 | @Input() public attribution: string = null;
18 |
19 | constructor(private mapService: MapService) {
20 | }
21 |
22 | public ngOnInit() {
23 | this.mapService.increaseNumber();
24 | const map = this.mapService.getMap();
25 | let layer = null;
26 | if (this.slippyLayer !== "") {
27 | layer = L.tileLayer(this.slippyLayer, {
28 | attribution: this.attribution,
29 | });
30 | }
31 | if (this.wmsLayer !== "" && this.name !== "") {
32 | layer = L.tileLayer.wms(this.wmsLayer, {
33 | layers: this.name,
34 | attribution: this.attribution
35 | }).setOpacity(this.opacity);
36 | }
37 |
38 | if (layer !== {}) {
39 | if (this.type === "overlay") {
40 | this.mapService.addOverlay(layer, this.name);
41 | layer.addTo(map);
42 | } else if (this.type === "basemap") {
43 | this.mapService.addBasemap(layer, this.name);
44 | layer.addTo(map);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/map/attribution/attribution.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map';
3 | import { MapService } from '../../services/map.service';
4 | import { AttributionModel } from '../../models/AttributionModel';
5 | import * as L from 'leaflet';
6 |
7 | @Component({
8 | selector: 'attribution-control',
9 | template: ``,
10 | styles: ['']
11 | })
12 | export class AttributionControl implements OnInit {
13 | @Input() public Options: any = new AttributionModel(null);
14 | constructor(
15 | private mapService: MapService,
16 | @Optional() private leafletElement?: LeafletElement) { }
17 |
18 | public ngOnInit() {
19 | if (this.leafletElement) {
20 | const map = this.mapService.getMap();
21 | L.control.attribution(this.Options).addTo(map);
22 | } else {
23 | // tslint:disable-next-line:no-console
24 | console.warn(`This attribution-control will not be rendered
25 | the expected parent node of attribution-control should be either leaf-element or layer-element`);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/map/attribution/index.ts:
--------------------------------------------------------------------------------
1 | export * from './attribution';
2 |
--------------------------------------------------------------------------------
/src/map/index.ts:
--------------------------------------------------------------------------------
1 | export * from './map';
2 | export * from './attribution/attribution';
3 | export * from './scale/scale';
4 | export * from './zoom/zoom';
5 | export * from './watermark/watermark';
6 |
--------------------------------------------------------------------------------
/src/map/map.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 | import { By } from '@angular/platform-browser';
3 | import { DebugElement } from '@angular/core';
4 | import { LeafletElement } from './map';
5 | import { MapService } from '../services/map.service';
6 |
7 |
8 | describe('LeafletElement', () => {
9 |
10 | beforeEach(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [LeafletElement], // declare the test component
13 | providers: [{ provide: MapService }]
14 | }).compileComponents();
15 | });
16 |
17 | it('works well', async(() => {
18 | const fixture = TestBed.createComponent(LeafletElement);
19 | fixture.componentInstance.lat = 52.6;
20 | fixture.detectChanges();
21 | const el = fixture.debugElement.nativeElement as HTMLElement;
22 | expect(fixture.componentInstance.lat).toBe(52.6);
23 | }))
24 | });
25 |
26 | describe('sub map test', () => {
27 | it('never fails', () => {
28 | expect(1).toBe(1);
29 | });
30 | });
--------------------------------------------------------------------------------
/src/map/map.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ViewChild, ElementRef, OnInit } from '@angular/core';
2 | import { MapService } from '../services/map.service';
3 | import { CoordinateHandler } from '../helpers/coordinateHandler';
4 | import * as L from 'leaflet';
5 |
6 | @Component({
7 | selector: 'leaf-element',
8 | template: `
9 | `,
12 | styles: [
13 | ':host {width: 100%;height:100%;}' +
14 | ':host .map-container {position: absolute;display: block;top: 0px;left: 0px;right: 0px;bottom: 0px;}' +
15 | 'leaf-element{width:100%;}' +
16 | '.leaflet-pane {z-index: 0 !important;}' +
17 | '.leaflet-bottom.leaflet-left {z-index: 1 !important;}'],
18 | providers: [MapService]
19 | })
20 |
21 | export class LeafletElement extends CoordinateHandler implements OnInit {
22 | @Input() public lat: number = 52.6;
23 | @Input() public lon: number = -1.1;
24 | @Input() public zoom: number = 12;
25 | @Input() public minZoom: number = 4;
26 | @Input() public maxZoom: number = 19;
27 | @Input() public layerControl: boolean = false;
28 | @Input() public crs: any = L.CRS.EPSG3857;
29 | @Input() public zoomControl: boolean;
30 | @Input() public maxBounds: L.LatLngBounds = null;
31 | @ViewChild('map') public mapElement: ElementRef;
32 |
33 | public layerControlObject = null;
34 |
35 | constructor(private mapService: MapService) {
36 | super();
37 | }
38 |
39 | public ngOnInit() {
40 | super.assignCartesianPointToLeafletsLatLngSchema();
41 |
42 | if (typeof (this.crs) === "string") {
43 | const splitCrs = this.crs.split(".");
44 | if (splitCrs[0] === "L") {
45 | this.crs = L[splitCrs[1]][splitCrs[2]];
46 | } else {
47 | // tslint:disable-next-line:no-console
48 | console.warn("something is not right, reverting to default EPSG3857");
49 | this.crs = L.CRS.EPSG3857;
50 | }
51 | }
52 |
53 | super.transformPointCoordinates(this.crs);
54 |
55 | const map = L.map(this.mapElement.nativeElement, {
56 | crs: this.crs,
57 | zoomControl: this.zoomControl,
58 | center: L.latLng(this.lat, this.lon),
59 | zoom: this.zoom,
60 | minZoom: this.minZoom,
61 | maxZoom: this.maxZoom,
62 | maxBounds: this.maxBounds,
63 | layers: [],
64 | closePopupOnClick: false,
65 | attributionControl: false
66 | });
67 | this.mapElement.nativeElement.myMapProperty = map;
68 |
69 | // set variables for childrent components
70 | this.mapService.setMap(map);
71 | this.mapService.setLayerControl(this.layerControl);
72 | }
73 |
74 | public setLayerControl() {
75 | if (this.layerControl) {
76 | const map = this.mapService.getMap();
77 | if (this.layerControlObject !== null) {
78 | this.layerControlObject.getContainer().innerHTML = '';
79 | }
80 | this.layerControlObject = L.control.layers(this.mapService.getBasemaps(),
81 | this.mapService.getOverlays()).addTo(map);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/map/scale/index.ts:
--------------------------------------------------------------------------------
1 | export * from './scale';
2 |
--------------------------------------------------------------------------------
/src/map/scale/scale.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map';
3 | import { MapService } from '../../services/map.service';
4 | import { ScaleModel } from '../../models/scaleModel';
5 | import * as L from 'leaflet';
6 |
7 |
8 | @Component({
9 | selector: 'scale-control',
10 | template: ``,
11 | styles: ['']
12 | })
13 | export class ScaleControl implements OnInit {
14 | @Input() public Options: any = new ScaleModel(null);
15 | constructor(
16 | private mapService: MapService,
17 | @Optional() private leafletElement?: LeafletElement) {
18 | }
19 |
20 | public ngOnInit() {
21 | if (this.leafletElement) {
22 | const map = this.mapService.getMap();
23 | L.control.scale(this.Options).addTo(map);
24 | } else {
25 | // tslint:disable-next-line:no-console
26 | console.warn(`This scale-control will not be rendered
27 | the expected parent node of scale-control should be leaf-element`);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/map/watermark/index.ts:
--------------------------------------------------------------------------------
1 | export * from './watermark';
2 |
--------------------------------------------------------------------------------
/src/map/watermark/watermark.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { MapService } from '../../services/map.service';
3 | import { LeafletElement } from '../map';
4 | import * as L from 'leaflet';
5 |
6 | @Component({
7 | selector: 'watermark-element',
8 | template: ``,
9 | styles: ['']
10 | })
11 |
12 | export class WatermarkControl implements OnInit {
13 | @Input() public url: string;
14 | @Input() public imagewidth: number;
15 | @Input() public imageheight: number;
16 |
17 | constructor(
18 | private mapService: MapService,
19 | @Optional() private leafletElement?: LeafletElement) { }
20 |
21 | public ngOnInit() {
22 | const self = this;
23 | if (this.leafletElement) {
24 | const map = this.mapService.getMap();
25 | if (this.url) {
26 | L.Control['Watermark'] = {} as any;
27 |
28 | L.Control['Watermark'] = L.Control.extend({
29 | onAdd: (fmap) => {
30 | const basediv: any = L.DomUtil.create('div', 'watermark');
31 |
32 | const howManyInX = Math.ceil(fmap.getSize().x / self.imagewidth);
33 | const howManyInY = Math.ceil(fmap.getSize().y / self.imageheight);
34 |
35 | const numberOfLogo = howManyInX * howManyInY;
36 |
37 | let i = 0;
38 | for (i; i < numberOfLogo; i++) {
39 | const img: any = L.DomUtil.create('img', 'watermark-elements', basediv);
40 | img.src = self.url;
41 | img.style.width = self.imagewidth + 'px';
42 | }
43 | return basediv;
44 | },
45 |
46 | onRemove: (fmap) => {
47 | // TODO
48 | }
49 | });
50 |
51 | L.control['watermark'] = (opts) => {
52 | return new L.Control['Watermark'](opts);
53 | };
54 | }
55 |
56 | L.control['watermark']({ position: "bottomleft" }).addTo(map);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/map/zoom/index.ts:
--------------------------------------------------------------------------------
1 | export * from './zoom';
2 |
--------------------------------------------------------------------------------
/src/map/zoom/zoom.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map';
3 | import { MapService } from '../../services/map.service';
4 | import { ΖoomModel } from '../../models/zoomModel';
5 | import * as L from 'leaflet';
6 |
7 | @Component({
8 | selector: 'zoom-control',
9 | template: ``,
10 | styles: ['']
11 | })
12 | export class ZoomControl implements OnInit {
13 | @Input() public Options: any = new ΖoomModel(null);
14 | constructor(
15 | private mapService: MapService,
16 | @Optional() private leafletElement?: LeafletElement) {
17 | }
18 |
19 | public ngOnInit() {
20 | if (this.leafletElement) {
21 | const map = this.mapService.getMap();
22 | L.control.zoom(this.Options).addTo(map);
23 | } else {
24 | // tslint:disable-next-line:no-console
25 | console.warn(`This zoom-control will not be rendered
26 | the expected parent node of zoom-control should be leaf-element`);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/marker/index.ts:
--------------------------------------------------------------------------------
1 | export * from './marker';
2 |
--------------------------------------------------------------------------------
/src/marker/marker.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, ElementRef, ViewChild, OnInit } from '@angular/core';
2 | import { HttpClient, HttpHeaders } from '@angular/common/http';
3 | import { MapService } from '../services/map.service';
4 | import { GroupService } from '../services/group.service';
5 | import { PopupService } from '../services/popup.service';
6 | import { LeafletElement } from '../map/map';
7 | import { LeafletGroup } from '../group/group';
8 | import { CoordinateHandler } from '../helpers/coordinateHandler';
9 | import { Observable } from 'rxjs';
10 | import { map } from 'rxjs/operators';
11 | import * as L from 'leaflet';
12 |
13 | @Component({
14 | selector: 'marker-element',
15 | template: `
`,
16 | styles: [''],
17 | providers: [PopupService]
18 | })
19 |
20 | export class MarkerElement extends CoordinateHandler implements OnInit {
21 | @Input() public lat: number = 52.6;
22 | @Input() public lon: number = -1.1;
23 | @Input() public mouseover: string | undefined = undefined;
24 | @Input() public onclick: string | undefined = undefined;
25 | @Input() public iconUrl: string = "";
26 | @ViewChild('ngel') public ngEl: ElementRef;
27 | public marker: any = null;
28 |
29 | constructor(
30 | private mapService: MapService,
31 | private popupService: PopupService,
32 | private http: HttpClient,
33 | @Optional() private groupService?: GroupService,
34 | @Optional() private leafletElement?: LeafletElement,
35 | @Optional() private leafletGroup?: LeafletGroup) {
36 | super();
37 | }
38 |
39 | public ngOnInit() {
40 | super.assignCartesianPointToLeafletsLatLngSchema();
41 | const model = this;
42 | if (this.leafletElement || this.leafletGroup) {
43 |
44 | const mapObject = this.mapService.getMap();
45 |
46 | super.transformPointCoordinates(this.leafletElement.crs);
47 |
48 | if (this.iconUrl === "") {
49 | this.marker = L.marker([this.lat, this.lon]);
50 | this.createMarkerlayer(this.marker, mapObject);
51 | } else {
52 | this.imageExists(this.iconUrl, (exists) => {
53 |
54 | model.getImage().subscribe(
55 | (image) => {
56 | const img = document.createElement("img");
57 | window.URL.createObjectURL(image.blob());
58 | const reader = new FileReader();
59 | reader.onload = () => {
60 | img.src = reader.result;
61 | const myIcon = L.icon({
62 | iconUrl: model.iconUrl,
63 | iconSize: [img.width, img.height],
64 | iconAnchor: [img.width / 2, img.height - 1],
65 | popupAnchor: [0, -img.height]
66 | });
67 |
68 | const obj = { icon: myIcon, options: null };
69 | model.marker = L.marker([model.lat, model.lon], obj);
70 | model.createMarkerlayer(model.marker, mapObject);
71 | };
72 | reader.readAsDataURL(image.blob());
73 | }, (err) => {
74 | // tslint:disable-next-line:no-console
75 | console.log(err);
76 | });
77 | });
78 | }
79 | } else {
80 | // tslint:disable-next-line:no-console
81 | console.warn(`This marker-element will not be rendered
82 | the expected parent node of marker-element should be either leaf-element or leaflet-group`);
83 | }
84 | }
85 |
86 | public createMarkerlayer(marker, mapObject) {
87 | let textInput;
88 | if (this.ngEl.nativeElement.childNodes.length > 0) {
89 | const textNode = this.ngEl.nativeElement.childNodes[0];
90 | textInput = textNode.nodeValue;
91 | }
92 |
93 | // add popup methods on element only if any of the tests are not undefined
94 | if (this.mouseover !== undefined || this.onclick !== undefined || textInput !== undefined) {
95 | this.popupService.enablePopup(this.mouseover, this.onclick, this.marker, textInput);
96 | }
97 |
98 | // only if the parent is map should the marker-element should be directly added to the map
99 | if (this.leafletGroup) {
100 | this.groupService.addOLayersToGroup(marker, mapObject, this.mapService, this.leafletGroup);
101 | } else {
102 | marker.addTo(mapObject);
103 | }
104 | }
105 |
106 | public imageExists(url, callback) {
107 | const img = new Image();
108 | img.onload = () => { callback(true); };
109 | img.onerror = () => { callback(false); };
110 | img.src = url;
111 | }
112 |
113 | public getImage(): any {
114 | const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
115 | return this.http.get(this.iconUrl, {
116 | headers,
117 | responseType: "blob"
118 | }).pipe(map((res: Response) => res)).toPromise()
119 | .catch((error: any) => Observable.throw('Server error'));
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/models/attributionModel.ts:
--------------------------------------------------------------------------------
1 | export class AttributionModel {
2 | // The HTML text shown before the attributions. Pass false to disable.
3 | public prefix: string = "Leaflet";
4 | // The position of the control (one of the map corners).
5 | // Possible values are 'topleft', 'topright', 'bottomleft' or 'bottomright'
6 | public position: string = "bottomright";
7 |
8 | constructor(options: any) {
9 | if (options !== null) {
10 | for (const key in options) {
11 | if (options[key] !== undefined) {
12 | this[key] = options[key];
13 | }
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/models/path.ts:
--------------------------------------------------------------------------------
1 | export class Path {
2 | // Whether to draw stroke along the path. Set it to false to disable borders on polygons or circles.
3 | public stroke: boolean = true;
4 | // Stroke color
5 | public color: string = '#3388ff';
6 | // Stroke width in pixels
7 | public weight: number = 3;
8 | // Stroke opacity
9 | public opacity: number = 1;
10 | // A string that defines shape to be used at the end of the stroke.
11 | public lineCap: string = 'round';
12 | // A string that defines shape to be used at the corners of the stroke.
13 | public lineJoin: string = 'round';
14 | // A string that defines the stroke dash pattern. Doesn't work on Canvas-powered layers in some old browsers.
15 | public dashArray: string = null;
16 | // A string that defines the distance into the dash pattern to start the dash.
17 | // Doesn't work on Canvas-powered layers in some old browsers.
18 | public dashOffset: string = null;
19 | // Whether to fill the path with color.Set it to false to disable filling on polygons or circles.
20 | public fill: boolean = true;
21 | // Fill color. Defaults to the value of the color option
22 | public fillColor: string = '#3388ff';
23 | // Fill opacity.
24 | public fillOpacity: number = 0.2;
25 | // A string that defines how the inside of a shape is determined.
26 | public fillRule: string = 'evenodd';
27 | // TODO renderer: Renderer;
28 | // Use this specific instance of Renderer for this path. Takes precedence over the map's default renderer.
29 | // null Custom class name set on an element. Only for SVG renderer.
30 | public className: string = null;
31 | constructor(pathInfo: any) {
32 | const source: any = pathInfo;
33 | const copy: any = this;
34 | if (source !== null) {
35 | for (const key in source) {
36 | if (source[key] !== undefined) {
37 | copy[key] = source[key];
38 | }
39 | }
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/models/scaleModel.ts:
--------------------------------------------------------------------------------
1 | export class ScaleModel {
2 | // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500).
3 | public maxWidth: number = 100;
4 | // Whether to show the metric scale line (m/km).
5 | public metric: boolean = true;
6 | // Whether to show the imperial scale line (mi/ft).
7 | public imperial: boolean = true;
8 | // If true, the control is updated on moveend, otherwise it's always up-to-date (updated on move).
9 | public updateWhenIdle: boolean = true;
10 | // The position of the control (one of the map corners).
11 | // Possible values are 'topleft', 'topright', 'bottomleft' or 'bottomright'
12 | public position: string = "bottomleft";
13 |
14 | constructor(options: any) {
15 | const source: any = options;
16 | const copy: any = this;
17 |
18 | if (source !== null) {
19 | for (const key in source) {
20 | if (source[key] !== undefined) {
21 | copy[key] = source[key];
22 | }
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/models/zoomModel.ts:
--------------------------------------------------------------------------------
1 | export class ΖoomModel {
2 | // The text set on the 'zoom in' button.
3 | public zoomInText: string = "+";
4 | // The title set on the 'zoom in' button.
5 | public zoomInTitle: string = "Zoom in";
6 | // The text set on the 'zoom out' button.
7 | public zoomOutText: string = "-";
8 | // The title set on the 'zoom out' button.
9 | public zoomOutTitle: string = "Zoom out";
10 | // The position of the control (one of the map corners).
11 | // Possible values are 'topleft', 'topright', 'bottomleft' or 'bottomright'
12 | public position: string = "topright";
13 | constructor(options: any) {
14 | const source: any = options;
15 | const copy: any = this;
16 |
17 | if (source !== null) {
18 | for (const key in source) {
19 | if (source[key] !== undefined) {
20 | copy[key] = source[key];
21 | }
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ngx.leaflet.components.ts:
--------------------------------------------------------------------------------
1 | export { LeafletElement } from './map/map';
2 | export { CoordinateHandler } from './helpers/coordinateHandler';
3 | export { GeoJSONCoordinateHandler } from './helpers/geoJsonReader';
4 | export { AttributionControl } from './map/attribution/attribution';
5 | export { ScaleControl } from './map/scale/scale';
6 | export { ZoomControl } from './map/zoom/zoom';
7 | export { WatermarkControl } from './map/watermark/watermark';
8 | export { LayerElement } from './layer/layer';
9 | export { ImageOverlayElement } from './imageoverlay/image-overlay';
10 | export { MarkerElement } from './marker/marker';
11 | export { CircleElement } from './circle/circle';
12 | export { CircleMarkerElement } from './circlemarker/circlemarker';
13 | export { PolygonElement } from './polygon/polygon';
14 | export { PolylineElement } from './polyline/polyline';
15 | export { GeoJsonElement } from './geojson/geojson';
16 | export { PopupElement } from './popup/popup';
17 | export { LeafletGroup } from './group/group';
18 | export { MapService } from './services/map.service';
19 | export { GroupService } from './services/group.service';
20 | export { PopupService } from './services/popup.service';
21 | export { GuidService } from './services/globalId.service';
22 | export { HelperService } from './services/helper.service';
23 | export { AttributionModel } from './models/AttributionModel';
24 | export { Path } from './models/path';
25 | export { ScaleModel } from './models/scaleModel';
26 | export { ΖoomModel } from './models/zoomModel';
27 | export { ngxLeafletModule } from './ngx.leaflet.module';
28 |
--------------------------------------------------------------------------------
/src/ngx.leaflet.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from "@angular/core";
2 | import { LeafletElement } from './map/map';
3 | import { AttributionControl } from './map/attribution/attribution';
4 | import { ScaleControl } from './map/scale/scale';
5 | import { ZoomControl } from './map/zoom/zoom';
6 | import { WatermarkControl } from './map/watermark/watermark';
7 |
8 | import { LayerElement } from './layer/layer';
9 | import { ImageOverlayElement } from './imageoverlay/image-overlay';
10 | import { MarkerElement } from './marker/marker';
11 | import { CircleElement } from './circle/circle';
12 | import { CircleMarkerElement } from './circlemarker/circlemarker';
13 | import { PolygonElement } from './polygon/polygon';
14 | import { PolylineElement } from './polyline/polyline';
15 | import { GeoJsonElement } from './geojson/geojson';
16 |
17 | import { PopupElement } from './popup/popup';
18 | import { LeafletGroup } from './group/group';
19 |
20 | import { MapService } from './services/map.service';
21 | import { GroupService } from './services/group.service';
22 | import { PopupService } from './services/popup.service';
23 | import { GuidService } from './services/globalId.service';
24 | import { HelperService } from './services/helper.service';
25 | import { HttpModule } from '@angular/http';
26 | import { ElementRef } from "@angular/core";
27 | import { CommonModule } from "@angular/common";
28 |
29 | @NgModule({
30 | imports: [
31 | CommonModule,
32 | HttpModule
33 | ],
34 | declarations: [
35 | LeafletElement,
36 | AttributionControl,
37 | ScaleControl,
38 | ZoomControl,
39 | WatermarkControl,
40 | LayerElement,
41 | ImageOverlayElement,
42 | MarkerElement,
43 | CircleElement,
44 | CircleMarkerElement,
45 | PolygonElement,
46 | PolylineElement,
47 | GeoJsonElement,
48 | PopupElement,
49 | LeafletGroup
50 | ],
51 | providers: [
52 | PopupService,
53 | GuidService,
54 | HelperService
55 | ],
56 | exports: [
57 | LeafletElement,
58 | AttributionControl,
59 | ScaleControl,
60 | ZoomControl,
61 | WatermarkControl,
62 | LayerElement,
63 | ImageOverlayElement,
64 | MarkerElement,
65 | CircleElement,
66 | CircleMarkerElement,
67 | PolygonElement,
68 | PolylineElement,
69 | GeoJsonElement,
70 | PopupElement,
71 | LeafletGroup
72 | ]
73 | })
74 |
75 | export class ngxLeafletModule { }
76 |
--------------------------------------------------------------------------------
/src/polygon/index.ts:
--------------------------------------------------------------------------------
1 | export * from './polygon';
2 |
--------------------------------------------------------------------------------
/src/polygon/polygon.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, ElementRef, ViewChild, OnInit, AfterViewInit, DoCheck } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { PopupService } from '../services/popup.service';
7 | import { GuidService } from '../services/globalId.service';
8 | import { HelperService } from '../services/helper.service';
9 | import { CoordinateHandler } from '../helpers/coordinateHandler';
10 | import { Path } from '../models/path';
11 | import * as L from 'leaflet';
12 |
13 | @Component({
14 | selector: 'polygon-element',
15 | template: `
`,
16 | styles: ['']
17 | })
18 |
19 | export class PolygonElement extends CoordinateHandler implements OnInit, AfterViewInit, DoCheck {
20 | @Input() public latlngs: any = [[[52.65, -1.2], [52.645, -1.15], [52.696, -1.155], [52.697, -1.189]],
21 | [[52.66, -1.19], [52.665, -1.16], [52.686, -1.161], [52.687, -1.179]]];
22 | @Input() public Options: Path = new Path(null);
23 | @Input() public mouseover: string | undefined = undefined;
24 | @Input() public onclick: string | undefined = undefined;
25 | @ViewChild('ngel') public ngEl: ElementRef;
26 | public polygon: any = null;
27 | public originalObject: any = [...this.latlngs];
28 | public globalId: string = this.guidService.newGuid();
29 |
30 | constructor(
31 | private mapService: MapService,
32 | private popupService: PopupService,
33 | private guidService: GuidService,
34 | private helperService: HelperService,
35 | @Optional() private groupService?: GroupService,
36 | @Optional() private leafletElement?: LeafletElement,
37 | @Optional() private leafletGroup?: LeafletGroup) {
38 | super();
39 | }
40 |
41 | public ngOnInit() {
42 | super.assignCartesianArrayToLeafletsLatLngSchema();
43 | // check if any of the two optional injections exist
44 | if (this.leafletElement || this.leafletGroup) {
45 | const inheritedOptions: any = new Path(this.Options);
46 | const map = this.mapService.getMap();
47 |
48 | super.transformArrayCoordinates(this.leafletElement.crs);
49 |
50 | this.polygon = L.polygon([this.latlngs], inheritedOptions);
51 |
52 | if (this.leafletGroup) {
53 | this.groupService.addOLayersToGroup(
54 | this.polygon, map, this.mapService, this.leafletGroup, false, this.globalId);
55 | } else {
56 | this.polygon.addTo(map);
57 | }
58 | } else {
59 | // tslint:disable-next-line:no-console
60 | console.warn(`This polygon-element will not be rendered
61 | the expected parent node of polygon-element should be either leaf-element or leaflet-group`);
62 | }
63 | }
64 |
65 | public ngAfterViewInit() {
66 | let textInput;
67 | if (this.ngEl.nativeElement.childNodes.length > 0) {
68 | const textNode = this.ngEl.nativeElement.childNodes[0];
69 | textInput = textNode.nodeValue;
70 | }
71 |
72 | // add popup methods on element only if any of the tests are not undefined
73 | if (this.mouseover !== undefined || this.onclick !== undefined || textInput !== undefined) {
74 | this.popupService.enablePopup(this.mouseover, this.onclick, this.polygon, textInput);
75 | }
76 | }
77 |
78 | public ngDoCheck() {
79 | const map = this.mapService.getMap();
80 |
81 | const same: boolean = this.helperService.arrayCompare(this.originalObject, this.latlngs);
82 |
83 | if (!same) {
84 | this.originalObject = [...this.latlngs];
85 | // if the layer is part of a group
86 | const inheritedOptions: any = new Path(this.Options);
87 |
88 | if (this.leafletGroup) {
89 | this.polygon = L.polygon([this.latlngs], inheritedOptions);
90 | this.groupService.addOLayersToGroup(this.polygon, map, this.mapService, this.leafletGroup, true, this.globalId);
91 | } else {
92 | map.removeLayer(this.polygon);
93 | this.polygon = L.polygon([this.latlngs], inheritedOptions);
94 | this.polygon.addTo(map);
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/polyline/index.ts:
--------------------------------------------------------------------------------
1 | export * from './polyline';
2 |
--------------------------------------------------------------------------------
/src/polyline/polyline.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, ElementRef, ViewChild, OnInit, AfterViewInit, DoCheck } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { PopupService } from '../services/popup.service';
7 | import { GuidService } from '../services/globalId.service';
8 | import { HelperService } from '../services/helper.service';
9 | import { CoordinateHandler } from '../helpers/coordinateHandler';
10 | import { Path } from '../models/path';
11 | import { Ipath } from '../interfaces/path';
12 | import * as L from 'leaflet';
13 |
14 | @Component({
15 | selector: 'polyline-element',
16 | template: `
`,
17 | styles: ['']
18 | })
19 |
20 | export class PolylineElement extends CoordinateHandler implements OnInit, AfterViewInit, DoCheck {
21 | @Input() public latlngs: any = [[52.6, -1.1], [52.605, -1.1], [52.606, -1.105], [52.697, -1.109]];
22 | @Input() public Options: any = new Path(null);
23 | @Input() public mouseover: string | undefined = undefined;
24 | @Input() public onclick: string | undefined = undefined;
25 | @ViewChild('ngel') public ngEl: ElementRef;
26 | public polyline: any = null;
27 | public originalObject: any = [...this.latlngs];
28 | public globalId: string = this.guidService.newGuid();
29 |
30 | constructor(
31 | private mapService: MapService,
32 | private popupService: PopupService,
33 | private guidService: GuidService,
34 | private helperService: HelperService,
35 | @Optional() private groupService?: GroupService,
36 | @Optional() private leafletElement?: LeafletElement,
37 | @Optional() private leafletGroup?: LeafletGroup) {
38 | super();
39 | }
40 |
41 | public ngOnInit() {
42 | super.assignCartesianArrayToLeafletsLatLngSchema();
43 | // check if any of the two optional injections exist
44 | if (this.leafletElement || this.leafletGroup) {
45 | // polyline shouldn't have a fill
46 | this.Options.fill = false;
47 | const inheritedOptions: any = new Path(this.Options);
48 | const map = this.mapService.getMap();
49 |
50 | super.transformArrayCoordinates(this.leafletElement.crs);
51 |
52 | this.polyline = L.polyline(this.latlngs, inheritedOptions);
53 |
54 | if (this.leafletGroup) {
55 | this.groupService.addOLayersToGroup(
56 | this.polyline, map, this.mapService, this.leafletGroup, false, this.globalId);
57 | } else {
58 | this.polyline.addTo(map);
59 | }
60 | } else {
61 | // tslint:disable-next-line:no-console
62 | console.warn(`This polyline-element will not be rendered
63 | the expected parent node of polyline-element should be either leaf-element or leaflet-group`);
64 | }
65 | }
66 |
67 | public ngAfterViewInit() {
68 | let textInput;
69 | if (this.ngEl.nativeElement.childNodes.length > 0) {
70 | const textNode = this.ngEl.nativeElement.childNodes[0];
71 | textInput = textNode.nodeValue;
72 | }
73 |
74 | // add popup methods on element only if any of the tests are not undefined
75 | if (this.mouseover !== undefined || this.onclick !== undefined || textInput !== undefined) {
76 | this.popupService.enablePopup(this.mouseover, this.onclick, this.polyline, textInput);
77 | }
78 | }
79 |
80 | public ngDoCheck() {
81 | const map = this.mapService.getMap();
82 |
83 | const same: boolean = this.helperService.arrayCompare(this.originalObject, this.latlngs);
84 |
85 | if (!same) {
86 | this.originalObject = [...this.latlngs];
87 | // if the layer is part of a group
88 | this.Options.fill = false;
89 | const inheritedOptions: any = new Path(this.Options);
90 |
91 | if (this.leafletGroup) {
92 | this.polyline = L.polyline(this.latlngs, inheritedOptions);
93 | this.groupService.addOLayersToGroup(
94 | this.polyline, map, this.mapService, this.leafletGroup, true, this.globalId);
95 | } else {
96 | map.removeLayer(this.polyline);
97 | this.polyline = L.polyline(this.latlngs, inheritedOptions);
98 | this.polyline.addTo(map);
99 | }
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/popup/index.ts:
--------------------------------------------------------------------------------
1 | export * from './popup';
2 |
--------------------------------------------------------------------------------
/src/popup/popup.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, Optional, OnInit } from '@angular/core';
2 | import { LeafletElement } from '../map/map';
3 | import { LeafletGroup } from '../group/group';
4 | import { MapService } from '../services/map.service';
5 | import { GroupService } from '../services/group.service';
6 | import { CoordinateHandler } from '../helpers/coordinateHandler';
7 | import * as L from 'leaflet';
8 |
9 | @Component({
10 | selector: 'popup-element',
11 | template: ``,
12 | styles: ['']
13 | })
14 |
15 | export class PopupElement extends CoordinateHandler implements OnInit {
16 | @Input() public lat: number = 52.6;
17 | @Input() public lon: number = -1.9;
18 | @Input() public content: string = "nice popup";
19 |
20 | constructor(
21 | private mapService: MapService,
22 | @Optional() private groupService?: GroupService,
23 | @Optional() private leafletElement?: LeafletElement,
24 | @Optional() private leafletGroup?: LeafletGroup) {
25 | super();
26 | }
27 |
28 | public ngOnInit() {
29 | super.assignCartesianPointToLeafletsLatLngSchema();
30 | // check if any of the two optional injections exist
31 | if (this.leafletElement || this.leafletGroup) {
32 |
33 | const map = this.mapService.getMap();
34 |
35 | this.transformPointCoordinates(this.leafletElement.crs);
36 |
37 | const popup = L.popup({ autoClose: false, keepInView: true })
38 | .setLatLng([this.lat, this.lon]).setContent(this.content);
39 |
40 | if (this.leafletGroup) {
41 | this.groupService.addOLayersToGroup(popup, map, this.mapService, this.leafletGroup);
42 | } else {
43 | popup.addTo(map);
44 | }
45 | } else {
46 | // tslint:disable-next-line:no-console
47 | console.warn(`This popup-element will not be rendered
48 | the expected parent node of popup-element should be either leaf-element or leaflet-group`);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/services/globalId.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable()
4 | export class GuidService {
5 |
6 | public newGuid() {
7 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
8 | const r = Math.random() * 16 | 0;
9 | const v = c === 'x' ? r : (r & 0x3 | 0x8);
10 | return v.toString(16);
11 | });
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/services/group.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import { GuidService } from '../services/globalId.service';
4 | import * as L from 'leaflet';
5 |
6 | @Injectable()
7 | export class GroupService {
8 | private layerGroup: any[] = [];
9 | private layerId: any[] = [];
10 | private layerGroupNumber: number = 0;
11 | private group: any = {};
12 |
13 | constructor(private guidService: GuidService) { }
14 |
15 | public addOLayersToGroup(overlay, map, mapService, group, replace = false, gId?: string) {
16 | if (!gId) {
17 | gId = this.guidService.newGuid();
18 | }
19 | if (this.layerId.indexOf(gId) === -1) {
20 | this.layerId.push(gId);
21 | }
22 | if (Object.keys(this.group).length !== 0) {
23 | if (replace) {
24 | map.removeLayer(this.group);
25 | if (this.layerId.indexOf(gId) !== -1) {
26 | this.layerGroup[this.layerId.indexOf(gId)] = overlay;
27 | } else {
28 | this.layerGroup.push(overlay);
29 | }
30 | this.group = L.layerGroup(this.getLayerGroup());
31 | this.group.addTo(map);
32 | } else {
33 | this.layerGroup.push(overlay);
34 | this.group.addLayer(overlay);
35 | }
36 | }
37 | if (!replace) {
38 | this.layerGroup.push(overlay);
39 | this.group = L.layerGroup(this.getLayerGroup());
40 | this.group.addTo(map);
41 | }
42 |
43 | mapService.addOverlay(this.getGroup(), group.name, group.globalId);
44 | }
45 |
46 | public getObservableGroup() {
47 | return Observable.create((observer) => {
48 | const group = this.getGroup();
49 | observer.next(group);
50 | observer.complete();
51 | });
52 | }
53 |
54 | public getGroup() {
55 | return this.group;
56 | }
57 |
58 | public getLayerGroup() {
59 | return this.layerGroup;
60 | }
61 |
62 | public getLayerNumber() {
63 | return this.layerGroupNumber;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/services/helper.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable()
4 | export class HelperService {
5 |
6 | public arrayCompare(a, b) {
7 | if (a.length !== b.length) {
8 | return false;
9 | }
10 | for (const i in a) {
11 | // Don't forget to check for arrays in our arrays.
12 | if (a[i] instanceof Array && b[i] instanceof Array) {
13 | if (!this.arrayCompare(a[i], b[i])) {
14 | return false;
15 | }
16 | } else if (a[i] !== b[i]) {
17 | return false;
18 | }
19 | }
20 | return true;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/services/map.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import * as L from 'leaflet';
4 |
5 | @Injectable()
6 | export class MapService {
7 | private map;
8 | private basemaps: any = {};
9 | private overlays: any = {};
10 | private layerControlflag: boolean = false;
11 | private layersInControlNumber: number = 0;
12 | private layerControlObject: any = {};
13 | private groupIdentifiers: string[] = [];
14 | private groupNames: string[] = [];
15 |
16 | public setMap(map) {
17 | this.map = map;
18 | }
19 | public getMap() {
20 | return this.map;
21 | }
22 |
23 | public setLayerControl(state) {
24 | this.layerControlflag = state;
25 | }
26 | public getLayerControl() {
27 | return this.layerControlflag;
28 | }
29 |
30 | public addBasemap(basemap, name) {
31 | if (name === '') {
32 | name = 'unknown layer';
33 | }
34 | if (this.basemaps[name] === undefined) {
35 | this.basemaps[name] = basemap;
36 | } else {
37 | name = this.getUniqueName(name);
38 | this.addBasemap(basemap, name);
39 | }
40 | }
41 |
42 | public getUniqueName(name) {
43 | let nameindex: number = 0;
44 | let newName: string = name;
45 | if (name.indexOf('(') !== -1) {
46 | nameindex = +(name.split('(')[1].split(')')[0]);
47 | nameindex += 1;
48 | newName = name.split('(')[0];
49 | } else {
50 | nameindex = 1;
51 | }
52 | return name = newName + '(' + nameindex + ')';
53 | }
54 |
55 | public addOverlay(overlay, name: string, gId?: string) {
56 | if (this.groupIdentifiers.indexOf(gId) !== -1) {
57 | const index = this.groupIdentifiers.indexOf(gId);
58 | const existingName: string = this.groupNames[index];
59 | this.overlays[existingName] = overlay;
60 | } else {
61 | if (name === '') {
62 | name = 'unknown group';
63 | }
64 | if (this.overlays[name] === undefined) {
65 | this.groupNames.push(name);
66 | this.groupIdentifiers.push(gId);
67 | this.overlays[name] = overlay;
68 | } else {
69 | name = this.getUniqueName(name);
70 | if (this.groupNames.indexOf(name) === -1) {
71 | this.groupNames.push(name);
72 | this.groupIdentifiers.push(gId);
73 | } else {
74 | this.addOverlay(overlay, name);
75 | }
76 | }
77 | }
78 |
79 | this.addControl();
80 | }
81 |
82 | public getBasemaps() {
83 | return this.basemaps;
84 | }
85 |
86 | public getOverlays() {
87 | return this.overlays;
88 | }
89 |
90 | public getObservableOverlays() {
91 | return Observable.create((observer) => {
92 | observer.next(this.overlays);
93 | observer.complete();
94 | });
95 | }
96 |
97 | public getObservableBasemaps() {
98 | return Observable.create((observer) => {
99 | observer.next(this.basemaps);
100 | observer.complete();
101 | });
102 | }
103 |
104 | public refreshOverlays(remove, add) {
105 | const overlays = this.getOverlays();
106 | for (const key in overlays) {
107 | if (overlays[key] instanceof Array) {
108 | overlays[key].forEach((element, index, arr) => {
109 | if (element._leaflet_id === remove._leaflet_id) {
110 | arr[index] = add;
111 | }
112 | });
113 | }
114 | }
115 | }
116 |
117 | public increaseNumber() {
118 | this.layersInControlNumber += 1;
119 | }
120 |
121 | public getLayerNumber() {
122 | return this.layersInControlNumber;
123 | }
124 |
125 | public addControl() {
126 | if (this.layerControlflag) {
127 | const map = this.getMap();
128 | if (Object.keys(this.layerControlObject).length !== 0) {
129 | this.layerControlObject.getContainer().innerHTML = '';
130 | map.removeControl(this.layerControlObject);
131 | }
132 | this.layerControlObject = L.control.layers(this.getBasemaps(), this.getOverlays()).addTo(map);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/services/popup.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable()
4 | export class PopupService {
5 |
6 | public enablePopup(mouseover, onclick, element, text) {
7 | if (mouseover && onclick) {
8 | mouseover = undefined;
9 | // tslint:disable-next-line:no-console
10 | console.warn('you can not use mouseover and onclick at the same time, mouseover is going to be depressed');
11 | }
12 | if (mouseover) {
13 | if (mouseover === 'true' && text) {
14 | mouseover = text;
15 | } else if (mouseover === true && !text) {
16 | mouseover = "true";
17 | }
18 | element.bindPopup(mouseover);
19 | element.on('mouseover', function(this: { openPopup: any, closePopup: any }) {
20 | this.openPopup();
21 | }).on('mouseout', function(this: { openPopup: any, closePopup: any }) {
22 | this.closePopup();
23 | });
24 | }
25 | if (onclick) {
26 | if (onclick === 'true' && text) {
27 | onclick = text;
28 | } else if (onclick === true && !text) {
29 | onclick = "true";
30 | }
31 | element.bindPopup(onclick);
32 | element.on('click', function(this: { openPopup: any, closePopup: any }) {
33 | this.openPopup();
34 | });
35 | }
36 | if (!mouseover && !onclick && text) {
37 | element.bindPopup(text);
38 | element.on('mouseover', function(this: { openPopup: any, closePopup: any }) {
39 | this.openPopup();
40 | }).on('mouseout', function(this: { openPopup: any, closePopup: any }) {
41 | this.closePopup();
42 | });
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/main.test.ts:
--------------------------------------------------------------------------------
1 | import 'core-js'; // ES6 + reflect-metadata
2 | // zone.js
3 | import 'zone.js/dist/zone';
4 | import 'zone.js/dist/long-stack-trace-zone';
5 | import 'zone.js/dist/proxy.js';
6 | import 'zone.js/dist/sync-test';
7 | import 'zone.js/dist/jasmine-patch';
8 | import 'zone.js/dist/async-test';
9 | import 'zone.js/dist/fake-async-test';
10 | import 'leaflet/dist/leaflet';
11 |
12 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
13 | declare var __karma__: any;
14 | declare var require: any;
15 |
16 | // Prevent Karma from running prematurely.
17 | __karma__.loaded = () => {
18 | // TODO
19 | };
20 | declare var System: any;
21 |
22 | Promise.all([
23 | System.import('@angular/core/testing'),
24 | System.import('@angular/platform-browser-dynamic/testing')
25 | ])
26 | // First, initialize the Angular testing environment.
27 | .then(([testing, testingBrowser]) => {
28 | testing.getTestBed().initTestEnvironment(
29 | testingBrowser.BrowserDynamicTestingModule,
30 | testingBrowser.platformBrowserDynamicTesting()
31 | );
32 | })
33 | .then(() => require.context('../map', true, /\.spec\.ts/))
34 | .then((context) => context.keys().map(context))
35 | .then(() => require.context('../geojson', true, /\.spec\.ts/))
36 | .then((context) => context.keys().map(context))
37 | .then(() => require.context('../circle', true, /\.spec\.ts/))
38 | .then((context) => context.keys().map(context))
39 | // Finally, start Karma to run the tests.
40 | .then(__karma__.start, __karma__.error);
41 |
--------------------------------------------------------------------------------
/src/test/mock.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, EventEmitter } from '@angular/core';
2 |
3 | export function MockComponent(options: Component): Component {
4 | const metadata: Component = {
5 | selector: options.selector,
6 | template: options.template || '',
7 | inputs: options.inputs,
8 | outputs: options.outputs || []
9 | };
10 |
11 | class Mock { }
12 | metadata.outputs.forEach((method) => {
13 | Mock.prototype[method] = new EventEmitter();
14 | });
15 |
16 | return Component(metadata)(Mock as any);
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/tsloader.js:
--------------------------------------------------------------------------------
1 | require('./main.test.ts');
2 | //# sourceMappingURL=tsloader.js.map
--------------------------------------------------------------------------------
/src/test/tsloader.ts:
--------------------------------------------------------------------------------
1 | require('./main.test.ts');
2 |
--------------------------------------------------------------------------------
/tsconfig-build.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": ".",
4 | "baseUrl": ".",
5 | "paths": {
6 | "@angular/*": [
7 | "node_modules/@angular/*"
8 | ],
9 | "leaflet/*": [
10 | "node_modules/leaflet/*"
11 | ],
12 | "rxjs/*": [
13 | "node_modules/rxjs/*"
14 | ]
15 | },
16 | "outDir": "dist",
17 | "declaration": true,
18 | "strict": true,
19 | "strictNullChecks": false,
20 | "noImplicitAny": false,
21 | "moduleResolution": "node",
22 | "module": "es2015",
23 | "target": "es2015",
24 | "typeRoots": [
25 | "node_modules/@types"
26 | ],
27 | "lib": [
28 | "es2015",
29 | "dom"
30 | ],
31 | "types": [
32 | "node",
33 | "jasmine",
34 | "leaflet",
35 | "geojson"
36 | ],
37 | "skipLibCheck": true,
38 | "experimentalDecorators": true,
39 | "emitDecoratorMetadata": true,
40 | "sourceMap": true,
41 | "inlineSources": true
42 | },
43 | "files": [
44 | "public_api.ts",
45 | "node_modules/zone.js/dist/zone.js.d.ts"
46 | ],
47 | "angularCompilerOptions": {
48 | "skipTemplateCodegen": false,
49 | "annotateForClosureCompiler": true,
50 | "strictMetadataEmit": true,
51 | "skipMetadataEmit": true,
52 | "flatModuleOutFile": "ngx.leaflet.components.js",
53 | "flatModuleId": "ngx.leaflet.components"
54 | }
55 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "emitDecoratorMetadata": true,
4 | "experimentalDecorators": true,
5 | "noImplicitAny": false,
6 | "target": "es5",
7 | "module": "commonjs",
8 | "moduleResolution": "node",
9 | "removeComments": true,
10 | "sourceMap": true,
11 | "declaration": true,
12 | "outDir": "./dist",
13 | "typeRoots": [
14 | "node_modules/@types"
15 | ],
16 | "lib": [
17 | "es2015",
18 | "dom"
19 | ],
20 | "types": [
21 | "node",
22 | "jasmine",
23 | "leaflet",
24 | "geojson"
25 | ]
26 | },
27 | "awesomeTypeScriptLoaderOptions": {
28 | "useWebpackText": true
29 | },
30 | "exclude": [
31 | "node_modules"
32 | ]
33 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rulesDirectory": [
4 | "node_modules/codelyzer"
5 | ],
6 | "rules": {
7 | "angular-whitespace": [
8 | true,
9 | "check-interpolation",
10 | "check-pipe"
11 | ],
12 | "banana-in-box": true,
13 | "templates-no-negated-async": true,
14 | "directive-selector": [
15 | true,
16 | "attribute",
17 | [
18 | "dir-prefix1",
19 | "dir-prefix2"
20 | ],
21 | "camelCase"
22 | ],
23 | "component-selector": [
24 | false,
25 | "element",
26 | "kebab-case"
27 | ],
28 | "object-literal-sort-keys": false,
29 | "use-input-property-decorator": true,
30 | "use-output-property-decorator": true,
31 | "use-host-property-decorator": true,
32 | "no-attribute-parameter-decorator": true,
33 | "no-input-rename": true,
34 | "no-output-rename": true,
35 | "no-forward-ref": true,
36 | "no-bitwise": false,
37 | "use-view-encapsulation": false,
38 | "use-life-cycle-interface": true,
39 | "use-pipe-transform-interface": true,
40 | "pipe-naming": [
41 | true,
42 | "camelCase",
43 | "Pipe"
44 | ],
45 | "component-class-suffix": [
46 | false
47 | ],
48 | "directive-class-suffix": [
49 | false
50 | ],
51 | "ordered-imports": [
52 | false
53 | ],
54 | "quotemark": [
55 | false
56 | ],
57 | "trailing-comma": [
58 | false
59 | ]
60 | }
61 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var path = require('path');
3 |
4 | module.exports = () => {
5 | return {
6 | entry: {
7 | main: './src/index.ts'
8 | },
9 | output: {
10 | path: './dist',
11 | filename: '[name].bundle.js'
12 | },
13 | plugins: [
14 | // Workaround for https://github.com/angular/angular/issues/11580
15 | new webpack.ContextReplacementPlugin(
16 | /angular(\\|\/)core(\\|\/)(@angular|esm5)/,
17 | path.resolve(__dirname, './src')
18 | )
19 | ],
20 | resolve: {
21 | extensions: ['.js', '.ts', '.html']
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.ts$/,
27 | loaders:
28 | [
29 | 'awesome-typescript-loader?' + JSON.stringify({
30 | sourceMap: false,
31 | inlineSourceMap: true
32 | }),
33 | 'angular2-template-loader'
34 | ]
35 | },
36 | {
37 | test: /\.html$/,
38 | loader: 'html-loader'
39 | },
40 | {
41 | test: /\.css$/,
42 | loader: 'css-loader'
43 | },
44 | {
45 | test: /\.ts$/,
46 | loader: 'istanbul-instrumenter-loader',
47 | exclude: [
48 | 'node_modules',
49 | 'test',
50 | /\.(e2e|spec)\.ts$/
51 | ],
52 | enforce: 'post'
53 | }
54 | ]
55 | },
56 | devtool: 'inline-source-map'
57 | }
58 | };
--------------------------------------------------------------------------------