Skip to content

Commit

Permalink
feat(geom): implements MultiPoint, MultiLinestring and MultiPolygon
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel-girard authored and Damien Marest committed Apr 9, 2019
1 parent d42e1fa commit 8d813c8
Show file tree
Hide file tree
Showing 20 changed files with 482 additions and 198 deletions.
68 changes: 67 additions & 1 deletion documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ The `GeometryPolygonComponent` (`aol-geometry-polygon`) defines a polygon.
<aol-feature>
<aol-geometry-polygon>
<aol-collection-coordinates
[coordinates]="[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]"
[coordinates]="[[[5, 45],[5.05, 45.05],[5.05, 44.95],[4.95, 44.95]]]"
[srid]="'EPSG:4326'"
>
</aol-collection-coordinates>
Expand All @@ -223,6 +223,72 @@ The `GeometryPolygonComponent` (`aol-geometry-polygon`) defines a polygon.
</aol-feature>
```

### MultiPoint component

The `GeometryMultiPointComponent` (`aol-geometry-multipoint`) defines a collection of points.

#### MultiPoint component example

```html
<aol-feature>
<aol-geometry-multipoint>
<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-multipoint>
<aol-style>
<aol-style-circle [radius]="10">
<aol-style-stroke [color]="'black'" [width]="width"></aol-style-stroke>
<aol-style-fill [color]="'green'"></aol-style-fill>
</aol-style-circle>
</aol-style>
</aol-feature>
```

### MultiLinestring component

The `GeometryMultiLinestringComponent` (`aol-geometry-multilinestring`) defines a collection of multilines.

#### MultiLinestring component example

```html
<aol-feature>
<aol-geometry-multilinestring>
<aol-collection-coordinates
[coordinates]="[[[5.0, 45.01],[5.01, 45.03]],[[6.0, 45.01],[6.01, 45.03]]]"
[srid]="'EPSG:4326'">
</aol-collection-coordinates>
</aol-geometry-multilinestring>
<aol-style>
<aol-style-stroke [color]="'red'"></aol-style-stroke>
</aol-style>
</aol-feature>
```

### MultiPolygon component

The `GeometryMultiPolygonComponent` (`aol-geometry-multipolygon`) defines a collection polygons.

#### MultiPolygon component example

```html
<aol-feature>
<aol-geometry-multipolygon>
<aol-collection-coordinates
[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]]]"
[srid]="'EPSG:4326'"
>
</aol-collection-coordinates>
</aol-geometry-multipolygon>
<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>
```

## Style components

`StyleComponents` (`<aol-style-*>`) provide ways to altering the look of vector features.
Expand Down
97 changes: 97 additions & 0 deletions projects/ngx-openlayers/src/lib/collectioncoordinates.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Component, Input, OnChanges, OnInit, Optional, SimpleChanges } from '@angular/core';
import { MapComponent } from './map.component';
import { GeometryLinestringComponent } from './geom/geometrylinestring.component';
import { GeometryPolygonComponent } from './geom/geometrypolygon.component';
import { GeometryMultiPointComponent } from './geom/geometrymultipoint.component';
import { GeometryMultiLinestringComponent } from './geom/geometrymultilinestring.component';
import { GeometryMultiPolygonComponent } from './geom/geometrymultipolygon.component';
import { Coordinate } from 'ol/coordinate';
import { transform } from 'ol/proj';

@Component({
selector: 'aol-collection-coordinates',
template: `
<div class="aol-collection-coordinates"></div>
`,
})
export class CollectionCoordinatesComponent implements OnChanges, OnInit {
private host: any;
private mapSrid = 'EPSG:3857';

@Input()
coordinates: Coordinate[] | Coordinate[][] | Coordinate[][][];
@Input()
srid = 'EPSG:3857';

constructor(
private map: MapComponent,
@Optional() geometryLinestring: GeometryLinestringComponent,
@Optional() geometryPolygon: GeometryPolygonComponent,
@Optional() geometryMultipoint: GeometryMultiPointComponent,
@Optional() geometryMultilinestring: GeometryMultiLinestringComponent,
@Optional() geometryMultipolygon: GeometryMultiPolygonComponent
) {
if (!!geometryLinestring) {
this.host = geometryLinestring;
} else if (!!geometryPolygon) {
this.host = geometryPolygon;
} else if (!!geometryMultipoint) {
this.host = geometryMultipoint;
} else if (!!geometryMultilinestring) {
this.host = geometryMultilinestring;
} else if (!!geometryMultipolygon) {
this.host = geometryMultipolygon;
} else {
throw new Error('aol-collection-coordinates must be a child of a geometry component');
}
}

ngOnInit() {
this.map.instance.on('change:view', e => this.onMapViewChanged(e));
this.mapSrid = this.map.instance
.getView()
.getProjection()
.getCode();
this.transformCoordinates();
}

ngOnChanges(changes: SimpleChanges) {
this.transformCoordinates();
}

private onMapViewChanged(event) {
this.mapSrid = event.target
.get(event.key)
.getProjection()
.getCode();
this.transformCoordinates();
}

private transformCoordinates() {
let transformedCoordinates: Coordinate[] | Coordinate[][] | Coordinate[][][];

if (this.srid === this.mapSrid) {
transformedCoordinates = this.coordinates;
} else {
switch (this.host.componentType) {
case 'geometry-linestring':
case 'geometry-multipoint':
transformedCoordinates = (<Coordinate[]>this.coordinates).map(c => transform(c, this.srid, this.mapSrid));
break;
case 'geometry-polygon':
case 'geometry-multilinestring':
transformedCoordinates = (<Coordinate[][]>this.coordinates).map(cc =>
cc.map(c => transform(c, this.srid, this.mapSrid))
);
break;
case 'geometry-multipolygon':
transformedCoordinates = (<Coordinate[][][]>this.coordinates).map(ccc =>
ccc.map(cc => cc.map(c => transform(c, this.srid, this.mapSrid)))
);
break;
}
}

this.host.instance.setCoordinates(transformedCoordinates);
}
}
109 changes: 29 additions & 80 deletions projects/ngx-openlayers/src/lib/coordinate.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { Component, Optional, OnChanges, Input, SimpleChanges } from '@angular/core';
import { Projection, transform } from 'ol/proj';
import { Component, Optional, OnChanges, Input, SimpleChanges, OnInit } from '@angular/core';
import { transform } from 'ol/proj';
import { MapComponent } from './map.component';
import {
GeometryPointComponent,
GeometryLinestringComponent,
GeometryPolygonComponent,
GeometryCircleComponent,
} from './geometry.components';
import { GeometryPointComponent } from './geom/geometrypoint.component';
import { GeometryCircleComponent } from './geom/geometrycircle.component';
import { ViewComponent } from './view.component';
import { OverlayComponent } from './overlay.component';
import { Coordinate } from 'ol/coordinate';

@Component({
selector: 'aol-coordinate',
template: `
<div class="aol-coordinate"></div>
`,
})
export class CoordinateComponent implements OnChanges {
export class CoordinateComponent implements OnChanges, OnInit {
private host: any;
private mapSrid = 'EPSG:3857';

@Input()
x: number;
Expand Down Expand Up @@ -46,18 +42,34 @@ export class CoordinateComponent implements OnChanges {
}
}

ngOnInit() {
this.map.instance.on('change:view', e => this.onMapViewChanged(e));
this.mapSrid = this.map.instance
.getView()
.getProjection()
.getCode();
this.transformCoordinates();
}

ngOnChanges(changes: SimpleChanges) {
let referenceProjection: Projection;
let referenceProjectionCode: string;
let transformedCoordinates: number[];
this.transformCoordinates();
}

private onMapViewChanged(event) {
this.mapSrid = event.target
.get(event.key)
.getProjection()
.getCode();
this.transformCoordinates();
}

referenceProjection = this.map.instance.getView().getProjection();
referenceProjectionCode = referenceProjection ? referenceProjection.getCode() : 'EPSG:3857';
private transformCoordinates() {
let transformedCoordinates: number[];

if (this.srid === referenceProjectionCode) {
if (this.srid === this.mapSrid) {
transformedCoordinates = [this.x, this.y];
} else {
transformedCoordinates = transform([this.x, this.y], this.srid, referenceProjectionCode);
transformedCoordinates = transform([this.x, this.y], this.srid, this.mapSrid);
}

switch (this.host.componentType) {
Expand All @@ -74,66 +86,3 @@ export class CoordinateComponent implements OnChanges {
}
}
}

@Component({
selector: 'aol-collection-coordinates',
template: `
<div class="aol-collection-coordinates"></div>
`,
})
export class CollectionCoordinatesComponent implements OnChanges {
private host: any;

@Input()
coordinates: [number, number][];
@Input()
srid = 'EPSG:3857';

constructor(
private map: MapComponent,
@Optional() geometryLinestring: GeometryLinestringComponent,
@Optional() geometryPolygon: GeometryPolygonComponent
) {
// console.log('creating aol-collection-coordinates');
if (!!geometryLinestring) {
this.host = geometryLinestring;
} else if (!!geometryPolygon) {
this.host = geometryPolygon;
} else {
throw new Error('aol-collection-coordinates must be a child of a geometry component');
}
}

ngOnChanges(changes: SimpleChanges) {
let referenceProjection: Projection;
let referenceProjectionCode: string;
let transformedCoordinates: Array<Coordinate>;

// console.log('coordinates change: ', this.coordinates);

referenceProjection = this.map.instance.getView().getProjection();
referenceProjectionCode = referenceProjection ? referenceProjection.getCode() : 'EPSG:3857';

if (this.srid === referenceProjectionCode) {
transformedCoordinates = this.coordinates;
} else {
transformedCoordinates = [];
this.coordinates.forEach(
function(coordinate: Coordinate) {
transformedCoordinates.push(transform(coordinate, this.srid, referenceProjectionCode));
}.bind(this)
);
}
switch (this.host.componentType) {
case 'geometry-linestring':
this.host.instance.setCoordinates(transformedCoordinates);
break;
case 'geometry-polygon':
this.host.instance.setCoordinates([transformedCoordinates]);
break;
default:
throw new Error('aol-collection-coordinates host is of unknown type: ' + this.host.componentType);
// break;
}
}
}
30 changes: 30 additions & 0 deletions projects/ngx-openlayers/src/lib/geom/geometrycircle.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Component, Input, OnInit } from '@angular/core';
import { FeatureComponent } from '../feature.component';
import { Circle } from 'ol/geom';
import { SimpleGeometryComponent } from './simplegeometry.component';
import { MapComponent } from '../map.component';

@Component({
selector: 'aol-geometry-circle',
template: `
<ng-content></ng-content>
`,
})
export class GeometryCircleComponent extends SimpleGeometryComponent implements OnInit {
public componentType = 'geometry-circle';
public instance: Circle;

@Input()
get radius(): number {
return this.instance.getRadius();
}
set radius(radius: number) {
this.instance.setRadius(radius);
}

constructor(map: MapComponent, host: FeatureComponent) {
super(map, host);
// defaulting coordinates to [0,0]. To be overridden in child component.
this.instance = new Circle([0, 0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, OnInit } from '@angular/core';
import { FeatureComponent } from '../feature.component';
import { SimpleGeometryComponent } from './simplegeometry.component';
import { MapComponent } from '../map.component';
import { LineString } from 'ol/geom';

@Component({
selector: 'aol-geometry-linestring',
template: `
<ng-content></ng-content>
`,
})
export class GeometryLinestringComponent extends SimpleGeometryComponent implements OnInit {
public componentType = 'geometry-linestring';
public instance: LineString;

constructor(map: MapComponent, host: FeatureComponent) {
super(map, host);
}

ngOnInit() {
this.instance = new LineString([[0, 0], [1, 1]]);
super.ngOnInit();
}
}
Loading

0 comments on commit 8d813c8

Please sign in to comment.