angular - 基于 Bootstrap 选择输入更新 ngx-leaflet 映射
问题描述
我有一个应用程序,当您基于此示例在 ngx-leaflet 中单击地图上的多边形时,它会更新 Bootstrap 选择输入下拉菜单。我还希望能够从选择输入中选择一个多边形名称,并具有与单击事件相同的功能——在这种情况下,fitBounds
用于平移和缩放到选定的多边形。
我在我的 HTML 模板中添加了事件绑定,该模板会检测下拉菜单中的每个新选择。onChange()
我向那个事件传递了一个新函数。但我很难过从这里去哪里。在点击事件中,我可以e.target
用来访问所选多边形的边界。但在里面onChange()
,我只能访问所选多边形的名称,但实际上我并没有与该多边形相关联的几何图形。那么如何使用下拉选择输入来选择多边形名称并让地图更新与该名称关联的多边形?(请注意,我希望得到灵活的响应,因为我想做的不仅仅是fitBounds()
在这个示例之外的实际应用程序中。)
这是我的示例代码:
polygons.geojson(在assets
文件夹中)
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#555555",
"fill-opacity": 0.5,
"name": "poly1"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-121.95098876953125,
46.82966386051541
],
[
-121.78482055664061,
46.82966386051541
],
[
-121.78482055664061,
46.91368905872705
],
[
-121.95098876953125,
46.91368905872705
],
[
-121.95098876953125,
46.82966386051541
]
]
]
}
},
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#555555",
"fill-opacity": 0.5,
"name": "poly2"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-121.77726745605469,
46.83107318799318
],
[
-121.62963867187499,
46.83107318799318
],
[
-121.62963867187499,
46.913220009605624
],
[
-121.77726745605469,
46.913220009605624
],
[
-121.77726745605469,
46.83107318799318
]
]
]
}
}
]
}
app.component.html
<div class="map"
leaflet
[leafletLayers]="layers"
[leafletFitBounds]="fitBounds"></div>
<div class="form-group">
<select [(ngModel)]="selected" class="form-control" id="selectRegion" [value]="clicked" (change)="onChange()">
<option *ngFor="let region of regions">{{ region }}</option>
</select>
</div>
app.component.ts
import {Component, NgZone, OnInit} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as L from 'leaflet';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
layers: L.Layer[];
fitBounds = [[46.67, -122.25], [47.01, -121.302]];
regions = [];
clicked = '';
selected = '';
constructor(private http: HttpClient, private zone: NgZone) { }
ngOnInit() {
// read in geojson of poly
this.http.get<any>('/assets/polygons.geojson')
.subscribe(poly => {
const tileLayer = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png', {
subdomains: 'abcd',
maxZoom: 19
});
const polyLayer = L.geoJSON(poly, {
onEachFeature: this.onEachFeature.bind(this)
});
this.layers = [ tileLayer, polyLayer ];
});
}
// loop through each feature of polyLayer
onEachFeature(feature, layer) {
this.zone.run(() => {
// push polygon names to regions array
this.regions.push(feature.properties.name);
layer.on('click', <LeafletMouseEvent> (e) => {
this.zone.run(() => {
this.fitBounds = e.target.getBounds();
this.clicked = e.target.feature.properties.name;
});
});
});
}
onChange() {
console.log(this.selected);
}
}
解决方案
我能够通过首先polyLayer
在我的 App Component 类的顶部初始化为 null 属性来解决这个问题constructor()
。因此,我在其余代码中更新了polyLayer
to的实例。this.polyLayer
有了这个,我现在可以访问里面的多边形onChange()
,用 过滤eachLayer()
,并适应地图的边界:
app.component.ts 更新
import {Component, NgZone, OnInit} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as L from 'leaflet';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
layers: L.Layer[];
fitBounds = [[46.67, -122.25], [47.01, -121.302]];
regions = [];
clicked = '';
selected = '';
polyLayer = null;
constructor(private http: HttpClient, private zone: NgZone) { }
ngOnInit() {
// read in geojson of poly
this.http.get<any>('/assets/polygons.geojson')
.subscribe(poly => {
const tileLayer = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png', {
subdomains: 'abcd',
maxZoom: 19
});
this.polyLayer = L.geoJSON(poly, {
onEachFeature: this.onEachFeature.bind(this)
});
this.layers = [ tileLayer, this.polyLayer ];
});
}
// loop through each feature of polyLayer
onEachFeature(feature, layer) {
this.zone.run(() => {
// push polygon names to regions array
this.regions.push(feature.properties.name);
layer.on('click', <LeafletMouseEvent> (e) => {
this.zone.run(() => {
this.fitBounds = e.target.getBounds();
this.clicked = e.target.feature.properties.name;
});
});
});
}
onChange() {
let that = this;
// console.log(this.polyLayer._layers);
this.polyLayer.eachLayer(function(layer){
if(layer.feature.properties.name === that.selected){
that.fitBounds = layer.getBounds();
}
});
}
}
推荐阅读
- python - 标签被“plt.savefig”切断,但在 jupyter 笔记本中没有
- java - 使用 Flyway 在 Quarkus 上进行反应性休眠
- mysql - 如何在 Sequelize 中获取特定案例的关联元素
- nuxt.js - Nuxt 构建 - “错误:生成 ENOMEM” - 达到 NPROC 限制
- python - 如何修复“异常:进程 0 以信号 SIGSEGV 终止”错误以及单个 gpu 代码是否正常工作?
- html - 使用 CORS 下载 HTML 锚标记
- css - 如何使用css在android浏览器上进行弹性滚动
- c++ - 如何替换放大/缩小功能中已弃用的函数`QWheelEvent::delta()`?
- sql - SQL联合加入问题
- laravel - 如何使用 Laravel API 和 VUE 客户端创建登录功能