刷新 Angular 10 ESRI 地图上的图层而不刷新整个地图
Refreshing Layers on an Angular 10 ESRI Map Without Refreshing the Entire Map
我在 Angular 10 中创建了一个 Esri 地图。用户可以 select 通过组按钮在地图上添加图层。所以输入将是一个数组,例如:['0','1','2']。数字是地图图层编号。所有这些功能都运行良好,但我必须在不刷新整个地图的情况下添加图层。请在下面找到代码。
import {
Component,
OnInit,
ViewChild,
ElementRef,
Input,
Output,
EventEmitter,
OnDestroy,
} from '@angular/core';
import { loadModules } from 'esri-loader';
import esri = __esri; // Esri TypeScript Types
import { empty } from 'rxjs';
@Component({
selector: 'app-esri-adv-map',
templateUrl: './esri-adv-map.component.html',
styleUrls: ['./esri-adv-map.component.css'],
})
export class EsriAdvMapComponent implements OnInit {
@Output() mapLoadedEvent = new EventEmitter<boolean>();
@ViewChild('mapViewNode', { static: true }) private mapViewEl: ElementRef;
view: any;
private _zoom = 15;
private _basemap = 'hybrid';
private _loaded = false;
private _view: esri.MapView = null;
private _nextBasemap = 'streets';
public _selectedLayer: Array<string>;
public onLayerChange(val: Array<string>) {
// eg: val = ['0','1','2'];
this._selectedLayer = val;
this.ngOnInit();
}
constructor() {}
async initializeMap() {
try {
// Load the modules for the ArcGIS API for JavaScript
const [
EsriMap,
EsriMapView,
FeatureLayer,
BasemapToggle,
BasemapGallery,
] = await loadModules([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer',
'esri/widgets/BasemapToggle',
'esri/widgets/BasemapGallery',
]);
// Configure the Map
const mapProperties: esri.MapProperties = {
basemap: this._basemap,
};
const map: esri.Map = new EsriMap(mapProperties);
// Initialize the MapView
const mapViewProperties: esri.MapViewProperties = {
container: this.mapViewEl.nativeElement,
center: this._center,
zoom: this._zoom,
map: map,
};
this._view = new EsriMapView(mapViewProperties);
// Add layers to the map according to the selection
let layerArray = this._selectedLayer;
console.log(layerArray);
if (typeof layerArray != 'undefined') {
layerArray.forEach((layer) => {
const addLayer = new FeatureLayer({
url:
'https://gis.dogis.org/arcgis/rest/services/test/MapServer/' +
layer,
});
map.add(addLayer);
});
}
// Basemap toglle section
var basemapToggle = new BasemapToggle({
view: this._view,
nextBasemap: this._nextBasemap,
});
this._view.ui.add(basemapToggle, 'top-right');
await this._view.when();
return this._view;
} catch (error) {
console.log('EsriLoader: ', error);
}
}
ngOnInit(): void {
this.initializeMap().then((mapView) => {
console.log('mapView ready: ', this._view.ready);
this._loaded = this._view.ready;
this.mapLoadedEvent.emit(true);
});
}
}
函数'onLayerChange()'来自分组按钮。一旦事件被触发,然后调用 'ngOnInit()' 加载带有 selected 图层的地图。但是我们如何才能只加载图层,而不是整个地图呢?
谢谢
不需要“re-initialize”组件。
我认为简单的解决方案是创建所有图层,将其添加到地图,然后只使用图层的 visible
属性。
例如,假设您将图层索引保存在 layerMapIdxArray
中(可能的要素图层的索引)。让我们添加一个包含可能层的字典 layersDic
并初始化它们。
layersMapIdxArray: number[] = ['0', '1', '4', '3', '8', '7']; // example
layersDic = {};
initLayersDic () {
for (const idx of layersMapIdxArray) {
this.layersDic[idx] = new FeatureLayer({
url: `https://gis.dogis.org/arcgis/rest/services/test/MapServer/${idx}`,
visible: false // <- with this starts off
});
map.add(this.layersDic[idx]);
}
}
然后在您的按钮组中单击(我猜)事件处理程序,只需相应地更新可见的 属性。
public onLayerChange(val: Array<string>) {
// eg: val = ['0','1','2'];
this.visibleFalseAllLayer(); // here you reset the layers visibility
// now turn on the selected layers
for (const v of val) {
this.layersDic[idx].visible = true;
}
}
就是这样!
顺便说一句,代码是表达逻辑的示例,我没有编译它。
我在 Angular 10 中创建了一个 Esri 地图。用户可以 select 通过组按钮在地图上添加图层。所以输入将是一个数组,例如:['0','1','2']。数字是地图图层编号。所有这些功能都运行良好,但我必须在不刷新整个地图的情况下添加图层。请在下面找到代码。
import {
Component,
OnInit,
ViewChild,
ElementRef,
Input,
Output,
EventEmitter,
OnDestroy,
} from '@angular/core';
import { loadModules } from 'esri-loader';
import esri = __esri; // Esri TypeScript Types
import { empty } from 'rxjs';
@Component({
selector: 'app-esri-adv-map',
templateUrl: './esri-adv-map.component.html',
styleUrls: ['./esri-adv-map.component.css'],
})
export class EsriAdvMapComponent implements OnInit {
@Output() mapLoadedEvent = new EventEmitter<boolean>();
@ViewChild('mapViewNode', { static: true }) private mapViewEl: ElementRef;
view: any;
private _zoom = 15;
private _basemap = 'hybrid';
private _loaded = false;
private _view: esri.MapView = null;
private _nextBasemap = 'streets';
public _selectedLayer: Array<string>;
public onLayerChange(val: Array<string>) {
// eg: val = ['0','1','2'];
this._selectedLayer = val;
this.ngOnInit();
}
constructor() {}
async initializeMap() {
try {
// Load the modules for the ArcGIS API for JavaScript
const [
EsriMap,
EsriMapView,
FeatureLayer,
BasemapToggle,
BasemapGallery,
] = await loadModules([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer',
'esri/widgets/BasemapToggle',
'esri/widgets/BasemapGallery',
]);
// Configure the Map
const mapProperties: esri.MapProperties = {
basemap: this._basemap,
};
const map: esri.Map = new EsriMap(mapProperties);
// Initialize the MapView
const mapViewProperties: esri.MapViewProperties = {
container: this.mapViewEl.nativeElement,
center: this._center,
zoom: this._zoom,
map: map,
};
this._view = new EsriMapView(mapViewProperties);
// Add layers to the map according to the selection
let layerArray = this._selectedLayer;
console.log(layerArray);
if (typeof layerArray != 'undefined') {
layerArray.forEach((layer) => {
const addLayer = new FeatureLayer({
url:
'https://gis.dogis.org/arcgis/rest/services/test/MapServer/' +
layer,
});
map.add(addLayer);
});
}
// Basemap toglle section
var basemapToggle = new BasemapToggle({
view: this._view,
nextBasemap: this._nextBasemap,
});
this._view.ui.add(basemapToggle, 'top-right');
await this._view.when();
return this._view;
} catch (error) {
console.log('EsriLoader: ', error);
}
}
ngOnInit(): void {
this.initializeMap().then((mapView) => {
console.log('mapView ready: ', this._view.ready);
this._loaded = this._view.ready;
this.mapLoadedEvent.emit(true);
});
}
}
函数'onLayerChange()'来自分组按钮。一旦事件被触发,然后调用 'ngOnInit()' 加载带有 selected 图层的地图。但是我们如何才能只加载图层,而不是整个地图呢? 谢谢
不需要“re-initialize”组件。
我认为简单的解决方案是创建所有图层,将其添加到地图,然后只使用图层的 visible
属性。
例如,假设您将图层索引保存在 layerMapIdxArray
中(可能的要素图层的索引)。让我们添加一个包含可能层的字典 layersDic
并初始化它们。
layersMapIdxArray: number[] = ['0', '1', '4', '3', '8', '7']; // example
layersDic = {};
initLayersDic () {
for (const idx of layersMapIdxArray) {
this.layersDic[idx] = new FeatureLayer({
url: `https://gis.dogis.org/arcgis/rest/services/test/MapServer/${idx}`,
visible: false // <- with this starts off
});
map.add(this.layersDic[idx]);
}
}
然后在您的按钮组中单击(我猜)事件处理程序,只需相应地更新可见的 属性。
public onLayerChange(val: Array<string>) {
// eg: val = ['0','1','2'];
this.visibleFalseAllLayer(); // here you reset the layers visibility
// now turn on the selected layers
for (const v of val) {
this.layersDic[idx].visible = true;
}
}
就是这样!
顺便说一句,代码是表达逻辑的示例,我没有编译它。