diff --git a/src/components/layers/layer.component.ts b/src/components/layers/layer.component.ts
index e54955a9..647fa582 100644
--- a/src/components/layers/layer.component.ts
+++ b/src/components/layers/layer.component.ts
@@ -17,7 +17,7 @@ export abstract class LayerComponent implements OnInit, OnChanges, OnDestroy {
@Input() precompose: (evt: ol.events.Event) => void;
@Input() postcompose: (evt: ol.events.Event) => void;
- constructor(protected host: LayerGroupComponent | MapComponent) {
+ constructor(public host: LayerGroupComponent | MapComponent) {
}
ngOnInit() {
@@ -27,11 +27,9 @@ export abstract class LayerComponent implements OnInit, OnChanges, OnDestroy {
if (this.postcompose !== null && this.postcompose !== undefined) {
this.instance.on('postcompose', this.postcompose);
}
- this.host.instance.getLayers().push(this.instance);
}
ngOnDestroy() {
- this.host.instance.getLayers().remove(this.instance);
}
ngOnChanges(changes: SimpleChanges) {
@@ -56,3 +54,35 @@ export abstract class LayerComponent implements OnInit, OnChanges, OnDestroy {
this.instance.setProperties(properties, false);
}
}
+
+
+export class LayersHelper {
+ /**
+ * Update OpenLayers layers (from a Map or a LayerGroup for example) from a given LayerComponent list.
+ * It helps to keep OpenLayers natural orders after adding, deleting and moving layers
+ * @param {ol.Collection
} olLayers
+ * @param {LayerComponent[]} viewLayers
+ */
+ static updateLayers(olLayers: ol.Collection, viewLayers: LayerComponent[]) {
+ viewLayers.forEach((layer, index) => {
+ let olIndex = olLayers.getArray().indexOf(layer.instance);
+ if (olIndex < 0) {
+ // New layer: we add it to the map
+ olLayers.insertAt(index, layer.instance);
+ // console.log(`~~ updateLayers: new layer at pos ${index}`, layer.instance);
+ } else if (index !== olIndex) {
+ // layer has moved inside the layers list
+ olLayers.removeAt(olIndex);
+ olLayers.insertAt(index, layer.instance);
+ // console.log(`~~ updateLayers: existing layer at pos ${olIndex} moving to pos ${index}`, layer.instance);
+ }
+ });
+ // Remove the layers that have disapeared from childrenLayers
+ if (olLayers.getLength() > viewLayers.length) {
+ for (let i = viewLayers.length; i < olLayers.getLength(); i++) {
+ olLayers.removeAt(i);
+ // console.log(`~~ updateLayers: remove layer at pos ${i}`);
+ }
+ }
+ }
+}
diff --git a/src/components/layers/layergroup.component.ts b/src/components/layers/layergroup.component.ts
index 48350d24..80392ae6 100644
--- a/src/components/layers/layergroup.component.ts
+++ b/src/components/layers/layergroup.component.ts
@@ -1,15 +1,21 @@
-import { Component, OnDestroy, OnInit, SkipSelf, Inject, Optional } from '@angular/core';
+import {
+ Component, OnDestroy, OnInit, SkipSelf, Inject, Optional, ViewChildren, QueryList,
+ AfterViewInit, ContentChildren, forwardRef
+} from '@angular/core';
import { layer } from 'openlayers';
-import { LayerComponent } from './layer.component';
+import { LayersHelper, LayerComponent } from './layer.component';
import { MapComponent } from '../map.component';
@Component({
selector: 'aol-layer-group',
- template: ``
+ template: ``,
+ providers: [{provide: LayerComponent, useExisting: forwardRef(() => LayerGroupComponent) }]
})
-export class LayerGroupComponent extends LayerComponent implements OnInit, OnDestroy {
+export class LayerGroupComponent extends LayerComponent implements AfterViewInit, OnInit, OnDestroy {
public instance: ol.layer.Group;
+ @ContentChildren(LayerComponent, {descendants: true}) childrenLayers: QueryList;
+
constructor(map: MapComponent,
@SkipSelf() @Optional() group?: LayerGroupComponent) {
super(group || map);
@@ -20,4 +26,21 @@ export class LayerGroupComponent extends LayerComponent implements OnInit, OnDes
this.instance = new layer.Group(this);
super.ngOnInit();
}
+
+ ngAfterViewInit() {
+ // console.log('layerGroup.AfterViewInit', this.childrenLayers);
+ // Update layers when new layers are added/moved/removed
+ this.childrenLayers.changes.subscribe(
+ () => LayersHelper.updateLayers(
+ this.instance.getLayers(),
+ // Filter is a temporary fix waiting for https://github.com/angular/angular/issues/10098
+ this.childrenLayers.filter(l => l.host === this)
+ )
+ );
+ // Initialization: add all the children layers
+ // Filter is a temporary fix waiting for https://github.com/angular/angular/issues/10098
+ this.childrenLayers.filter(l => l.host === this).forEach((layer) => {
+ this.instance.getLayers().push(layer.instance);
+ });
+ }
}
diff --git a/src/components/layers/layerimage.component.ts b/src/components/layers/layerimage.component.ts
index e5e8ff22..5e679841 100644
--- a/src/components/layers/layerimage.component.ts
+++ b/src/components/layers/layerimage.component.ts
@@ -1,5 +1,5 @@
import {
- Component, EventEmitter, Input, OnChanges, OnInit, Optional,
+ Component, EventEmitter, forwardRef, Input, OnChanges, OnInit, Optional,
SimpleChanges
} from '@angular/core';
import { Extent, layer, source } from 'openlayers';
@@ -9,7 +9,8 @@ import { LayerGroupComponent } from './layergroup.component';
@Component({
selector: 'aol-layer-image',
- template: ``
+ template: ``,
+ providers: [{provide: LayerComponent, useExisting: forwardRef(() => LayerImageComponent) }]
})
export class LayerImageComponent extends LayerComponent implements OnInit, OnChanges {
public source: source.Image;
diff --git a/src/components/layers/layertile.component.ts b/src/components/layers/layertile.component.ts
index 4f268f39..ec940724 100644
--- a/src/components/layers/layertile.component.ts
+++ b/src/components/layers/layertile.component.ts
@@ -1,6 +1,6 @@
import {
Component, OnDestroy, OnInit, Input, Optional, OnChanges,
- SimpleChanges
+ SimpleChanges, forwardRef
} from '@angular/core';
import { layer, source } from 'openlayers';
import { MapComponent } from '../map.component';
@@ -9,7 +9,8 @@ import { LayerGroupComponent } from './layergroup.component';
@Component({
selector: 'aol-layer-tile',
- template: ``
+ template: ``,
+ providers: [{provide: LayerComponent, useExisting: forwardRef(() => LayerTileComponent) }]
})
export class LayerTileComponent extends LayerComponent implements OnInit, OnDestroy, OnChanges {
public source: source.Tile;
diff --git a/src/components/layers/layervector.component.ts b/src/components/layers/layervector.component.ts
index 8d9b8398..9d62de89 100644
--- a/src/components/layers/layervector.component.ts
+++ b/src/components/layers/layervector.component.ts
@@ -1,6 +1,6 @@
import {
Component, OnDestroy, OnInit, Input, Optional, OnChanges,
- SimpleChanges
+ SimpleChanges, forwardRef
} from '@angular/core';
import { layer, source } from 'openlayers';
import { MapComponent } from '../map.component';
@@ -9,7 +9,8 @@ import { LayerGroupComponent } from './layergroup.component';
@Component({
selector: 'aol-layer-vector',
- template: ``
+ template: ``,
+ providers: [{provide: LayerComponent, useExisting: forwardRef(() => LayerVectorComponent) }]
})
export class LayerVectorComponent extends LayerComponent implements OnInit, OnDestroy, OnChanges {
public source: source.Vector;
diff --git a/src/components/layers/layervectortile.component.ts b/src/components/layers/layervectortile.component.ts
index fc9c1bd1..ba4f5fc0 100644
--- a/src/components/layers/layervectortile.component.ts
+++ b/src/components/layers/layervectortile.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, Input, Optional, SimpleChanges, OnChanges } from '@angular/core';
+import {Component, OnInit, Input, Optional, SimpleChanges, OnChanges, forwardRef} from '@angular/core';
import { layer, style, StyleFunction } from 'openlayers';
import { MapComponent } from '../map.component';
import { LayerComponent } from './layer.component';
@@ -6,7 +6,8 @@ import { LayerGroupComponent } from './layergroup.component';
@Component({
selector: 'aol-layer-vectortile',
- template: ``
+ template: ``,
+ providers: [{provide: LayerComponent, useExisting: forwardRef(() => LayerVectorTileComponent) }]
})
export class LayerVectorTileComponent extends LayerComponent implements OnInit, OnChanges {
diff --git a/src/components/map.component.ts b/src/components/map.component.ts
index d7401a03..87a49cf2 100644
--- a/src/components/map.component.ts
+++ b/src/components/map.component.ts
@@ -1,11 +1,12 @@
import {
Component, OnInit, ElementRef, Input, Output, EventEmitter, AfterViewInit,
- SimpleChanges, OnChanges
+ SimpleChanges, OnChanges, QueryList, ContentChildren, forwardRef
} from '@angular/core';
import {
Map, MapBrowserEvent, MapEvent, render, ObjectEvent, control,
interaction
} from 'openlayers';
+import { LayerComponent, LayersHelper } from './layers';
@Component({
selector: 'aol-map',
@@ -16,6 +17,8 @@ export class MapComponent implements OnInit, AfterViewInit, OnChanges {
public instance: Map;
public componentType: string = 'map';
+ @ContentChildren(LayerComponent, {descendants: true}) childrenLayers: QueryList;
+
@Input() width: string = '100%';
@Input() height: string = '100%';
@Input() pixelRatio: number;
@@ -86,5 +89,19 @@ export class MapComponent implements OnInit, AfterViewInit, OnChanges {
ngAfterViewInit() {
this.instance.updateSize();
+
+ // Update layers when new layers are added/moved/removed
+ this.childrenLayers.changes.subscribe(
+ () => LayersHelper.updateLayers(
+ this.instance.getLayers(),
+ // Filter is a temporary fix waiting for https://github.com/angular/angular/issues/10098
+ this.childrenLayers.filter(l => l.host === this)
+ )
+ );
+ // Initialization: add all the layers
+ // Filter is a temporary fix waiting for https://github.com/angular/angular/issues/10098
+ this.childrenLayers.filter(l => l.host === this).forEach((layer) => {
+ this.instance.getLayers().push(layer.instance);
+ });
}
}