Skip to content

Commit f0d4dd1

Browse files
samuel-girardNeonox31
authored andcommitted
feat(geom): implements MultiPoint, MultiLinestring and MultiPolygon
BREAKING CHANGE: The coordinates input on CollectionCoordinatesComponent is not anymore limited to type [number, number][], but it supports all types of coordinates. That means the existing code must be updated for polygons: Old style: ```html <aol-feature> <aol-geometry-polygon> <aol-collection-coordinates [coordinates]="[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]" [srid]="'EPSG:4326'" > </aol-collection-coordinates> </aol-geometry-polygon> <aol-style> <aol-style-stroke [color]="'red'"></aol-style-stroke> <aol-style-fill [color]="[255,0,0,0.5]"></aol-style-fill> </aol-style> </aol-feature> ``` New style: ```html <aol-feature> <aol-geometry-polygon> <aol-collection-coordinates [coordinates]="[[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]]" [srid]="'EPSG:4326'" > </aol-collection-coordinates> </aol-geometry-polygon> <aol-style> <aol-style-stroke [color]="'red'"></aol-style-stroke> <aol-style-fill [color]="[255,0,0,0.5]"></aol-style-fill> </aol-style> </aol-feature> ``` Notice the [coordinates] input is now a [number, number][][], as defined in GeoJSON. This also allows to display polygon with holes, which is not possible with the current code.
1 parent 27b1529 commit f0d4dd1

20 files changed

+482
-198
lines changed

documentation/README.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ The `GeometryPolygonComponent` (`aol-geometry-polygon`) defines a polygon.
211211
<aol-feature>
212212
<aol-geometry-polygon>
213213
<aol-collection-coordinates
214-
[coordinates]="[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]"
214+
[coordinates]="[[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]]"
215215
[srid]="'EPSG:4326'"
216216
>
217217
</aol-collection-coordinates>
@@ -223,6 +223,72 @@ The `GeometryPolygonComponent` (`aol-geometry-polygon`) defines a polygon.
223223
</aol-feature>
224224
```
225225

226+
### MultiPoint component
227+
228+
The `GeometryMultiPointComponent` (`aol-geometry-multipoint`) defines a collection of points.
229+
230+
#### MultiPoint component example
231+
232+
```html
233+
<aol-feature>
234+
<aol-geometry-multipoint>
235+
<aol-collection-coordinates
236+
[coordinates]="[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]"
237+
[srid]="'EPSG:4326'"
238+
>
239+
</aol-collection-coordinates>
240+
</aol-geometry-multipoint>
241+
<aol-style>
242+
<aol-style-circle [radius]="10">
243+
<aol-style-stroke [color]="'black'" [width]="width"></aol-style-stroke>
244+
<aol-style-fill [color]="'green'"></aol-style-fill>
245+
</aol-style-circle>
246+
</aol-style>
247+
</aol-feature>
248+
```
249+
250+
### MultiLinestring component
251+
252+
The `GeometryMultiLinestringComponent` (`aol-geometry-multilinestring`) defines a collection of multilines.
253+
254+
#### MultiLinestring component example
255+
256+
```html
257+
<aol-feature>
258+
<aol-geometry-multilinestring>
259+
<aol-collection-coordinates
260+
[coordinates]="[[[5.0, 45.01],[5.01, 45.03]],[[6.0, 45.01],[6.01, 45.03]]]"
261+
[srid]="'EPSG:4326'">
262+
</aol-collection-coordinates>
263+
</aol-geometry-multilinestring>
264+
<aol-style>
265+
<aol-style-stroke [color]="'red'"></aol-style-stroke>
266+
</aol-style>
267+
</aol-feature>
268+
```
269+
270+
### MultiPolygon component
271+
272+
The `GeometryMultiPolygonComponent` (`aol-geometry-multipolygon`) defines a collection polygons.
273+
274+
#### MultiPolygon component example
275+
276+
```html
277+
<aol-feature>
278+
<aol-geometry-multipolygon>
279+
<aol-collection-coordinates
280+
[coordinates]="[[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]],[[6, 45],[6.05, 45.05],[6.05, 44.95],[5.95, 44.95]]]"
281+
[srid]="'EPSG:4326'"
282+
>
283+
</aol-collection-coordinates>
284+
</aol-geometry-multipolygon>
285+
<aol-style>
286+
<aol-style-stroke [color]="'red'"></aol-style-stroke>
287+
<aol-style-fill [color]="[255,0,0,0.5]"></aol-style-fill>
288+
</aol-style>
289+
</aol-feature>
290+
```
291+
226292
## Style components
227293

228294
`StyleComponents` (`<aol-style-*>`) provide ways to altering the look of vector features.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { Component, Input, OnChanges, OnInit, Optional, SimpleChanges } from '@angular/core';
2+
import { MapComponent } from './map.component';
3+
import { GeometryLinestringComponent } from './geom/geometrylinestring.component';
4+
import { GeometryPolygonComponent } from './geom/geometrypolygon.component';
5+
import { GeometryMultiPointComponent } from './geom/geometrymultipoint.component';
6+
import { GeometryMultiLinestringComponent } from './geom/geometrymultilinestring.component';
7+
import { GeometryMultiPolygonComponent } from './geom/geometrymultipolygon.component';
8+
import { Coordinate } from 'ol/coordinate';
9+
import { transform } from 'ol/proj';
10+
11+
@Component({
12+
selector: 'aol-collection-coordinates',
13+
template: `
14+
<div class="aol-collection-coordinates"></div>
15+
`,
16+
})
17+
export class CollectionCoordinatesComponent implements OnChanges, OnInit {
18+
private host: any;
19+
private mapSrid = 'EPSG:3857';
20+
21+
@Input()
22+
coordinates: Coordinate[] | Coordinate[][] | Coordinate[][][];
23+
@Input()
24+
srid = 'EPSG:3857';
25+
26+
constructor(
27+
private map: MapComponent,
28+
@Optional() geometryLinestring: GeometryLinestringComponent,
29+
@Optional() geometryPolygon: GeometryPolygonComponent,
30+
@Optional() geometryMultipoint: GeometryMultiPointComponent,
31+
@Optional() geometryMultilinestring: GeometryMultiLinestringComponent,
32+
@Optional() geometryMultipolygon: GeometryMultiPolygonComponent
33+
) {
34+
if (!!geometryLinestring) {
35+
this.host = geometryLinestring;
36+
} else if (!!geometryPolygon) {
37+
this.host = geometryPolygon;
38+
} else if (!!geometryMultipoint) {
39+
this.host = geometryMultipoint;
40+
} else if (!!geometryMultilinestring) {
41+
this.host = geometryMultilinestring;
42+
} else if (!!geometryMultipolygon) {
43+
this.host = geometryMultipolygon;
44+
} else {
45+
throw new Error('aol-collection-coordinates must be a child of a geometry component');
46+
}
47+
}
48+
49+
ngOnInit() {
50+
this.map.instance.on('change:view', e => this.onMapViewChanged(e));
51+
this.mapSrid = this.map.instance
52+
.getView()
53+
.getProjection()
54+
.getCode();
55+
this.transformCoordinates();
56+
}
57+
58+
ngOnChanges(changes: SimpleChanges) {
59+
this.transformCoordinates();
60+
}
61+
62+
private onMapViewChanged(event) {
63+
this.mapSrid = event.target
64+
.get(event.key)
65+
.getProjection()
66+
.getCode();
67+
this.transformCoordinates();
68+
}
69+
70+
private transformCoordinates() {
71+
let transformedCoordinates: Coordinate[] | Coordinate[][] | Coordinate[][][];
72+
73+
if (this.srid === this.mapSrid) {
74+
transformedCoordinates = this.coordinates;
75+
} else {
76+
switch (this.host.componentType) {
77+
case 'geometry-linestring':
78+
case 'geometry-multipoint':
79+
transformedCoordinates = (<Coordinate[]>this.coordinates).map(c => transform(c, this.srid, this.mapSrid));
80+
break;
81+
case 'geometry-polygon':
82+
case 'geometry-multilinestring':
83+
transformedCoordinates = (<Coordinate[][]>this.coordinates).map(cc =>
84+
cc.map(c => transform(c, this.srid, this.mapSrid))
85+
);
86+
break;
87+
case 'geometry-multipolygon':
88+
transformedCoordinates = (<Coordinate[][][]>this.coordinates).map(ccc =>
89+
ccc.map(cc => cc.map(c => transform(c, this.srid, this.mapSrid)))
90+
);
91+
break;
92+
}
93+
}
94+
95+
this.host.instance.setCoordinates(transformedCoordinates);
96+
}
97+
}
Lines changed: 29 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
import { Component, Optional, OnChanges, Input, SimpleChanges } from '@angular/core';
2-
import { Projection, transform } from 'ol/proj';
1+
import { Component, Optional, OnChanges, Input, SimpleChanges, OnInit } from '@angular/core';
2+
import { transform } from 'ol/proj';
33
import { MapComponent } from './map.component';
4-
import {
5-
GeometryPointComponent,
6-
GeometryLinestringComponent,
7-
GeometryPolygonComponent,
8-
GeometryCircleComponent,
9-
} from './geometry.components';
4+
import { GeometryPointComponent } from './geom/geometrypoint.component';
5+
import { GeometryCircleComponent } from './geom/geometrycircle.component';
106
import { ViewComponent } from './view.component';
117
import { OverlayComponent } from './overlay.component';
12-
import { Coordinate } from 'ol/coordinate';
138

149
@Component({
1510
selector: 'aol-coordinate',
1611
template: `
1712
<div class="aol-coordinate"></div>
1813
`,
1914
})
20-
export class CoordinateComponent implements OnChanges {
15+
export class CoordinateComponent implements OnChanges, OnInit {
2116
private host: any;
17+
private mapSrid = 'EPSG:3857';
2218

2319
@Input()
2420
x: number;
@@ -46,18 +42,34 @@ export class CoordinateComponent implements OnChanges {
4642
}
4743
}
4844

45+
ngOnInit() {
46+
this.map.instance.on('change:view', e => this.onMapViewChanged(e));
47+
this.mapSrid = this.map.instance
48+
.getView()
49+
.getProjection()
50+
.getCode();
51+
this.transformCoordinates();
52+
}
53+
4954
ngOnChanges(changes: SimpleChanges) {
50-
let referenceProjection: Projection;
51-
let referenceProjectionCode: string;
52-
let transformedCoordinates: number[];
55+
this.transformCoordinates();
56+
}
57+
58+
private onMapViewChanged(event) {
59+
this.mapSrid = event.target
60+
.get(event.key)
61+
.getProjection()
62+
.getCode();
63+
this.transformCoordinates();
64+
}
5365

54-
referenceProjection = this.map.instance.getView().getProjection();
55-
referenceProjectionCode = referenceProjection ? referenceProjection.getCode() : 'EPSG:3857';
66+
private transformCoordinates() {
67+
let transformedCoordinates: number[];
5668

57-
if (this.srid === referenceProjectionCode) {
69+
if (this.srid === this.mapSrid) {
5870
transformedCoordinates = [this.x, this.y];
5971
} else {
60-
transformedCoordinates = transform([this.x, this.y], this.srid, referenceProjectionCode);
72+
transformedCoordinates = transform([this.x, this.y], this.srid, this.mapSrid);
6173
}
6274

6375
switch (this.host.componentType) {
@@ -74,66 +86,3 @@ export class CoordinateComponent implements OnChanges {
7486
}
7587
}
7688
}
77-
78-
@Component({
79-
selector: 'aol-collection-coordinates',
80-
template: `
81-
<div class="aol-collection-coordinates"></div>
82-
`,
83-
})
84-
export class CollectionCoordinatesComponent implements OnChanges {
85-
private host: any;
86-
87-
@Input()
88-
coordinates: [number, number][];
89-
@Input()
90-
srid = 'EPSG:3857';
91-
92-
constructor(
93-
private map: MapComponent,
94-
@Optional() geometryLinestring: GeometryLinestringComponent,
95-
@Optional() geometryPolygon: GeometryPolygonComponent
96-
) {
97-
// console.log('creating aol-collection-coordinates');
98-
if (!!geometryLinestring) {
99-
this.host = geometryLinestring;
100-
} else if (!!geometryPolygon) {
101-
this.host = geometryPolygon;
102-
} else {
103-
throw new Error('aol-collection-coordinates must be a child of a geometry component');
104-
}
105-
}
106-
107-
ngOnChanges(changes: SimpleChanges) {
108-
let referenceProjection: Projection;
109-
let referenceProjectionCode: string;
110-
let transformedCoordinates: Array<Coordinate>;
111-
112-
// console.log('coordinates change: ', this.coordinates);
113-
114-
referenceProjection = this.map.instance.getView().getProjection();
115-
referenceProjectionCode = referenceProjection ? referenceProjection.getCode() : 'EPSG:3857';
116-
117-
if (this.srid === referenceProjectionCode) {
118-
transformedCoordinates = this.coordinates;
119-
} else {
120-
transformedCoordinates = [];
121-
this.coordinates.forEach(
122-
function(coordinate: Coordinate) {
123-
transformedCoordinates.push(transform(coordinate, this.srid, referenceProjectionCode));
124-
}.bind(this)
125-
);
126-
}
127-
switch (this.host.componentType) {
128-
case 'geometry-linestring':
129-
this.host.instance.setCoordinates(transformedCoordinates);
130-
break;
131-
case 'geometry-polygon':
132-
this.host.instance.setCoordinates([transformedCoordinates]);
133-
break;
134-
default:
135-
throw new Error('aol-collection-coordinates host is of unknown type: ' + this.host.componentType);
136-
// break;
137-
}
138-
}
139-
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Component, Input, OnInit } from '@angular/core';
2+
import { FeatureComponent } from '../feature.component';
3+
import { Circle } from 'ol/geom';
4+
import { SimpleGeometryComponent } from './simplegeometry.component';
5+
import { MapComponent } from '../map.component';
6+
7+
@Component({
8+
selector: 'aol-geometry-circle',
9+
template: `
10+
<ng-content></ng-content>
11+
`,
12+
})
13+
export class GeometryCircleComponent extends SimpleGeometryComponent implements OnInit {
14+
public componentType = 'geometry-circle';
15+
public instance: Circle;
16+
17+
@Input()
18+
get radius(): number {
19+
return this.instance.getRadius();
20+
}
21+
set radius(radius: number) {
22+
this.instance.setRadius(radius);
23+
}
24+
25+
constructor(map: MapComponent, host: FeatureComponent) {
26+
super(map, host);
27+
// defaulting coordinates to [0,0]. To be overridden in child component.
28+
this.instance = new Circle([0, 0]);
29+
}
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { FeatureComponent } from '../feature.component';
3+
import { SimpleGeometryComponent } from './simplegeometry.component';
4+
import { MapComponent } from '../map.component';
5+
import { LineString } from 'ol/geom';
6+
7+
@Component({
8+
selector: 'aol-geometry-linestring',
9+
template: `
10+
<ng-content></ng-content>
11+
`,
12+
})
13+
export class GeometryLinestringComponent extends SimpleGeometryComponent implements OnInit {
14+
public componentType = 'geometry-linestring';
15+
public instance: LineString;
16+
17+
constructor(map: MapComponent, host: FeatureComponent) {
18+
super(map, host);
19+
}
20+
21+
ngOnInit() {
22+
this.instance = new LineString([[0, 0], [1, 1]]);
23+
super.ngOnInit();
24+
}
25+
}

0 commit comments

Comments
 (0)