使用 bringToFront() 为不在带有 ngx-leaflet 的层事件中的传单层设置样式
Using bringToFront() to style leaflet layers that are NOT in a layer event with ngx-leaflet
我有一个多面体,我想对其进行过滤、放入独特的图层并设置不同的样式。我加载 geoJson,应用通用样式,并使用 onEachFeature
根据条件将图层放入 featureGroups 中。仍在 onEachFeature
内,我将样式应用于每个功能组。这很好用。
问题是多边形笔划重叠,这是 leaflet/svg 中解决的一个常见问题。我知道使用 bringToFront
来解决这个问题,但我似乎无法在我的 ngx-leaflet angular 应用程序中使用它。当我在点击事件中测试 bringToFront
时,它起作用了。但我希望多边形样式本身(没有事件)被带到前面。
下面是一些示例代码(来自 ngx-leaflet-tutorial-ngcli
):
states.geojson(在/assets
目录中)
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3520", "name_len": 3520 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -111.006268677999884, 31.327184550000098 ], [ -114.822108114999963, 32.500239563000022 ], [ -114.720794720599827, 32.7245646349499 ], [ -114.535858197098094, 32.738236510006914 ], [ -114.460736126870756, 32.854911313806042 ], [ -114.501727338146111, 33.019413268207757 ], [ -114.696746868872879, 33.089359557497573 ], [ -114.7235046809962, 33.32124432236759 ], [ -114.726898235864894, 33.411478697383984 ], [ -114.532611127401594, 33.568558775367194 ], [ -114.515936321603931, 33.963627135284071 ], [ -114.119061321722597, 34.293216978480757 ], [ -114.368963665640649, 34.471537291312927 ], [ -114.616961713112516, 34.879300963268804 ], [ -114.638861126739585, 35.123539243841037 ], [ -114.571942181186671, 35.212552915984247 ], [ -114.741278119289746, 36.013627134784429 ], [ -114.707147260337763, 36.108841977775057 ], [ -114.554779095678725, 36.16052654906099 ], [ -114.123895306323277, 36.045853697290283 ], [ -114.042010541153502, 36.219779478340229 ], [ -114.040203900289725, 37.003129088436651 ], [ -109.046624798995254, 36.999808775254735 ], [ -109.047430462999856, 31.327391256000041 ], [ -111.006268677999884, 31.327184550000098 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3524", "name_len": 3524 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -108.137503214999924, 31.777544657000064 ], [ -108.215121216999904, 31.777751364000025 ], [ -108.214811157999918, 31.327442932000068 ], [ -109.047430462999856, 31.327391256000041 ], [ -109.046624798995254, 36.999808775254735 ], [ -103.000799603418955, 36.999808775254735 ], [ -103.065594524767505, 32.00168865790522 ], [ -106.66217655600326, 32.000297056863644 ], [ -106.506052409999938, 31.770258281000068 ], [ -108.137503214999924, 31.777544657000064 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3526", "name_len": 3526 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -111.05023808032314, 41.999833189050435 ], [ -111.049920696982554, 40.999833189250239 ], [ -109.046331829550297, 40.999833189250239 ], [ -109.046624798995254, 36.999808775254735 ], [ -114.040203900289725, 37.003129088436651 ], [ -114.042547649554365, 42.000077329804924 ], [ -111.05023808032314, 41.999833189050435 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3522", "name_len": 3522 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -109.046331829550297, 40.999833189250239 ], [ -102.051800580432428, 40.99958904939507 ], [ -102.039569135107456, 36.999808775254735 ], [ -109.046624798995254, 36.999808775254735 ], [ -109.046331829550297, 40.999833189250239 ] ] ] } }
]
}
app.component.html
<div class="map"
leaflet
[leafletFitBounds]="fitBounds"
[leafletLayers]="layers">
</div>
app.component.ts
import { Component, 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 {
tiles = L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
detectRetina: true
});
layers: L.Layer[];
redGroup = L.featureGroup();
blueGroup = L.featureGroup();
fitBounds = null;
constructor(
private http: HttpClient,
) { }
ngOnInit() {
this.http.get<any>('assets/states.geojson')
.subscribe(data => {
const tmp = L.geoJSON(data, {
style: () => ({
weight: 2,
fillOpacity: 1,
opacity: 1
}),
onEachFeature: this.onEachFeature.bind(this)
});
this.fitBounds = L.geoJSON(data).getBounds();
// this.redGroup.bringToFront();
this.layers = [ this.tiles, this.redGroup, this.blueGroup ];
// this.layers = [ this.tiles, this.redGroup.bringToFront(), this.blueGroup ];
// this.redGroup.bringToFront();
});
}
onEachFeature(feature, layer) {
if (feature.properties.name_len <= 3522) {
layer.addTo(this.redGroup);
// this.redGroup.bringToFront();
} else {
layer.addTo(this.blueGroup);
}
this.blueGroup.setStyle({fillColor: 'lightblue', color: 'blue'});
this.redGroup.setStyle({
fillColor: 'pink', color: 'red'
});
this.redGroup.bringToFront();
layer.on('click', (e) => {
e.target.setStyle({color: 'yellow'}).bringToFront();
});
}
}
我注释掉了所有将 redGroup
推到前面的失败尝试。正如你所看到的,当你点击一个多边形时,黄色笔划被推到前面 bringToFront
。但是在我的初始加载中,我希望 redGroup
中的红色描边显示在 blueGroup
中的蓝色描边之上。我该怎么做?
根据@reblace 的指导,我需要在 onEachFeature
底部超时后调用代码,如下所示:
setTimeout(() => {
this.redGroup.bringToFront();
}, 0);
我有一个多面体,我想对其进行过滤、放入独特的图层并设置不同的样式。我加载 geoJson,应用通用样式,并使用 onEachFeature
根据条件将图层放入 featureGroups 中。仍在 onEachFeature
内,我将样式应用于每个功能组。这很好用。
问题是多边形笔划重叠,这是 leaflet/svg 中解决的一个常见问题。我知道使用 bringToFront
来解决这个问题,但我似乎无法在我的 ngx-leaflet angular 应用程序中使用它。当我在点击事件中测试 bringToFront
时,它起作用了。但我希望多边形样式本身(没有事件)被带到前面。
下面是一些示例代码(来自 ngx-leaflet-tutorial-ngcli
):
states.geojson(在/assets
目录中)
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3520", "name_len": 3520 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -111.006268677999884, 31.327184550000098 ], [ -114.822108114999963, 32.500239563000022 ], [ -114.720794720599827, 32.7245646349499 ], [ -114.535858197098094, 32.738236510006914 ], [ -114.460736126870756, 32.854911313806042 ], [ -114.501727338146111, 33.019413268207757 ], [ -114.696746868872879, 33.089359557497573 ], [ -114.7235046809962, 33.32124432236759 ], [ -114.726898235864894, 33.411478697383984 ], [ -114.532611127401594, 33.568558775367194 ], [ -114.515936321603931, 33.963627135284071 ], [ -114.119061321722597, 34.293216978480757 ], [ -114.368963665640649, 34.471537291312927 ], [ -114.616961713112516, 34.879300963268804 ], [ -114.638861126739585, 35.123539243841037 ], [ -114.571942181186671, 35.212552915984247 ], [ -114.741278119289746, 36.013627134784429 ], [ -114.707147260337763, 36.108841977775057 ], [ -114.554779095678725, 36.16052654906099 ], [ -114.123895306323277, 36.045853697290283 ], [ -114.042010541153502, 36.219779478340229 ], [ -114.040203900289725, 37.003129088436651 ], [ -109.046624798995254, 36.999808775254735 ], [ -109.047430462999856, 31.327391256000041 ], [ -111.006268677999884, 31.327184550000098 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3524", "name_len": 3524 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -108.137503214999924, 31.777544657000064 ], [ -108.215121216999904, 31.777751364000025 ], [ -108.214811157999918, 31.327442932000068 ], [ -109.047430462999856, 31.327391256000041 ], [ -109.046624798995254, 36.999808775254735 ], [ -103.000799603418955, 36.999808775254735 ], [ -103.065594524767505, 32.00168865790522 ], [ -106.66217655600326, 32.000297056863644 ], [ -106.506052409999938, 31.770258281000068 ], [ -108.137503214999924, 31.777544657000064 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3526", "name_len": 3526 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -111.05023808032314, 41.999833189050435 ], [ -111.049920696982554, 40.999833189250239 ], [ -109.046331829550297, 40.999833189250239 ], [ -109.046624798995254, 36.999808775254735 ], [ -114.040203900289725, 37.003129088436651 ], [ -114.042547649554365, 42.000077329804924 ], [ -111.05023808032314, 41.999833189050435 ] ] ] } },
{ "type": "Feature", "properties": { "adm1_code": "Admin-1 scale rank", "diss_me": 2, "name": "USA-3522", "name_len": 3522 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -109.046331829550297, 40.999833189250239 ], [ -102.051800580432428, 40.99958904939507 ], [ -102.039569135107456, 36.999808775254735 ], [ -109.046624798995254, 36.999808775254735 ], [ -109.046331829550297, 40.999833189250239 ] ] ] } }
]
}
app.component.html
<div class="map"
leaflet
[leafletFitBounds]="fitBounds"
[leafletLayers]="layers">
</div>
app.component.ts
import { Component, 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 {
tiles = L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
detectRetina: true
});
layers: L.Layer[];
redGroup = L.featureGroup();
blueGroup = L.featureGroup();
fitBounds = null;
constructor(
private http: HttpClient,
) { }
ngOnInit() {
this.http.get<any>('assets/states.geojson')
.subscribe(data => {
const tmp = L.geoJSON(data, {
style: () => ({
weight: 2,
fillOpacity: 1,
opacity: 1
}),
onEachFeature: this.onEachFeature.bind(this)
});
this.fitBounds = L.geoJSON(data).getBounds();
// this.redGroup.bringToFront();
this.layers = [ this.tiles, this.redGroup, this.blueGroup ];
// this.layers = [ this.tiles, this.redGroup.bringToFront(), this.blueGroup ];
// this.redGroup.bringToFront();
});
}
onEachFeature(feature, layer) {
if (feature.properties.name_len <= 3522) {
layer.addTo(this.redGroup);
// this.redGroup.bringToFront();
} else {
layer.addTo(this.blueGroup);
}
this.blueGroup.setStyle({fillColor: 'lightblue', color: 'blue'});
this.redGroup.setStyle({
fillColor: 'pink', color: 'red'
});
this.redGroup.bringToFront();
layer.on('click', (e) => {
e.target.setStyle({color: 'yellow'}).bringToFront();
});
}
}
我注释掉了所有将 redGroup
推到前面的失败尝试。正如你所看到的,当你点击一个多边形时,黄色笔划被推到前面 bringToFront
。但是在我的初始加载中,我希望 redGroup
中的红色描边显示在 blueGroup
中的蓝色描边之上。我该怎么做?
根据@reblace 的指导,我需要在 onEachFeature
底部超时后调用代码,如下所示:
setTimeout(() => {
this.redGroup.bringToFront();
}, 0);