一、切换菜单、地图尺寸刷新
<ngx-map #map [mapUrl]="mapUrl" [showNavigation]="false" [isTransform]="true" [showLOC]="true"
(onMapLoad)="mapload()" (onMapStyleChanged)="onMapStyleChanged()">
</ngx-map>
setMapChange() {
this.onMapload = false;
this.mapUrl = this.area == 'SH' ? `${this.map_url}/styles/shanghai_city_albers/style.json` : `${this.map_url}/styles/csj_province_albers/style.json`;
this.mapbox.changeStyle(this.mapUrl);
}
onMapStyleChanged() {
this.mapload();
}
二、清除图层
clearLayer() {
if (this.mapbox && this.mapbox.getLayer('pngProduct')) {
this.mapbox.removeLayer('pngProduct');
}
if (this.mapbox && this.mapbox.getSource('pngProduct')) {
this.mapbox.removeImage('pngProduct');
}
}
三、 地图添加站点数据
let geojson = {
"type": "FeatureCollection",
"features": []
}
this.mapbox.addSource('point', {
'type': 'geojson',
'data': geojson
});
await this.mapbox.addLayer({
'id': 'point',
'type': 'circle',
'source': 'point',
"paint": {
'circle-radius': 3,
"circle-color": {
"type": "interval",
"property": "data",
"stops": this.stops,
}
}
}, "anno");
四、 拼接geojson数据
createGeoJSONCircle(lngLat: { lat: number, lng: number }, radiusInKm: number, steps = 64) {
let geojson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": []
}
}]
}
let ret = [];
let distanceX = radiusInKm / (111.320 * Math.cos(lngLat.lat * Math.PI / 180));
let distanceY = radiusInKm / 110.574;
let theta, x, y;
for (let i = 0; i < steps; i++) {
theta = (i / steps) * (2 * Math.PI);
x = distanceX * Math.cos(theta);
y = distanceY * Math.sin(theta);
let lng = lngLat.lng + x;
let lat = lngLat.lat + y
ret.push([lng, lat]);
}
ret.push(ret[0]);
geojson.features[0].geometry.coordinates = [ret];
return geojson;
}
五、添加站点信息
点击地图,弹框展示站点信息(实例1)
onClickStation() {
this.mapbox.onLayerClick("station", (e) => {
let props: PestStat = e.features[0].properties;
if (!props) return;
let statData: Station = this.stations.find(stat => stat.v01000 == props.v01000)
this.propsHTML =
`<p style="padding-left:10px">` + statData.cAera + statData.cPrvoName + "省" + statData.cCity + `</p>
<div class="station-tbale">
<div class="col-sm-8 station_title">灾害名称</div>
<div class="col-sm-14">`+ props.disastername + `</div>
</div>
<div class="station-tbale" >
<div class="col-sm-8 station_title">区站号</div>
<div class="col-sm-8">`+ props.v01000 + `</div>
<div class="col-sm-8 station_title">区站名</div>
<div class="col-sm-8">`+ statData.cStatName + `</div>
</div>
<div class="station-tbale">
<div class="col-sm-8 station_title">指数</div>
<div class="col-sm-8">`+ props.disaindex + `</div>
<div class="col-sm-8 station_title">指数等级</div>
<div class="col-sm-8">`+ props.grade + `</div>
</div>
<div class="station-tbale">
<div class="col-sm-8 station_title">年份</div>
<div class="col-sm-8">`+ props.v04001 + "年" + `</div>
<div class="col-sm-8 station_title">连续日数</div>
<div class="col-sm-8">`+ props.condays + `</div>
</div>
<div class="station-tbale">
<div class="col-sm-8 station_title">作物类别</div>
<div class="col-sm-8">`+ props.disastercrop + `</div>
<div class="col-sm-8 station_title">模型版本号</div>
<div class="col-sm-8">`+ props.vVersion + `</div>
</div>
<div class="station-tbale">
<div class="col-sm-8 station_title">起始时间</div>
<div class="col-sm-8">`+ (props.sdate).toString().substring(0, 4) + "年" + Number((props.sdate).toString().substring(4, 6)) + "月" + Number((props.sdate).toString().substring(6, 8)) + "日" + `</div>
<div class="col-sm-8 station_title">终止时间</div>
<div class="col-sm-8">`+ (props.edate).toString().substring(0, 4) + "年" + Number((props.edate).toString().substring(4, 6)) + "月" + Number((props.edate).toString().substring(6, 8)) + "日" + `</div>
</div>`;
this.popup = new Popup()
.setLngLat(e.eventData.lngLat)
.setHTML(this.propsHTML)
.addTo(this.mapbox.map);
})
}
async initStat() {
this.title = `${this.dateArr.sYear}年~${this.dateArr.eYear}年${this.area.cName}${this.task.title}`;
let dayCount = ((new Date(this.dateArr.eYear, this.dateArr.eMonth, 1).getTime() - new Date(this.dateArr.eYear, this.dateArr.eMonth - 1, 1).getTime()) / 24 / 3600 / 1000).toString().padStart(2, "0");
let eDate = this.dateArr.eYear + this.dateArr.eMonth.toString().padStart(2, "0") + dayCount + "000000"
let sDate = this.dateArr.sYear + this.dateArr.sMonth.toString().padStart(2, "0") + "01000000"
let prn = this.productService.makeProductName("BABJ", "WCRMECO", eDate, sDate, this.task.style_name, "1KM", this.area.cCoverage, "geojson")
let geojson
let isGeojson: boolean = false
await this.productService.getContent(prn).toPromise().then(data => {
if (!data.features) {
this.message.error("无" + this.title + "站点数据")
return
}
isGeojson = true;
geojson = data
}).catch(error => {
this.message.error(this.title + "站点数据获取失败")
})
if (!isGeojson) {
return
}
await this.mapbox.addSource('point', {
'type': 'geojson',
'data': geojson
});
await this.mapbox.addLayer({
'id': 'point',
'type': 'circle',
'source': 'point',
"paint": {
'circle-radius': 3,
"circle-color": {
"type": "interval",
"property": "data",
"stops": this.stops,
}
}
}, "anno");
}
if (this.popup) {
this.popup.remove();
var popUps = document.getElementsByClassName("mapboxgl-popup");
if (popUps[0]) {
popUps[0].remove();
console.log('popup.remove');
}
}
点击地图的站点,弹框显示站点信息(实例2)
<ngx-map #map [mapUrl]="mapUrl" [showNavigation]="false" [isTransform]="isAlbers" [showLOC]="true"
[showDraw]="true" (onMapLoad)="mapload()" (onMapStyleChanged)="onMapStyleChanged()">
</ngx-map>
mapload() {
this.mapLoaded = true;
this.mapbox.map.setMinZoom(3.5);
this.mapDefaultService.init(this.mapbox);
this.mapbox.onLayerClick(this.mapDefaultService.LayerId.COUNTY, (event: LayerEventData) => {
this.areaName[2] = event.features[0].properties["NAME"]
});
this.mapbox.onLayerClick(this.mapDefaultService.LayerId.CITY, (event: LayerEventData) => {
this.areaName[1] = event.features[0].properties["NAME"]
});
this.mapbox.onLayerClick(this.mapDefaultService.LayerId.PROVINCE, (event: LayerEventData) => {
this.areaName[0] = event.features[0].properties["NAME"]
});
this.mapbox.onLayerClick("point", (e) => {
this.stations = JSON.parse(localStorage.getItem("stations"))
let props = e.features[0].properties;
if (!props) return;
let statData = this.stations.filter(stat => stat.v01000 == props.id)
let legend = JSON.parse(JSON.stringify(this.stops.find(item => item[0] == props.data)))
this.legend.items.forEach((value, key) => {
if (value == legend[1]) {
legend[0] = key;
}
})
this.propsHTML =
`<p style="padding-left:10px">` + statData[0].cPrvoName + statData[0].cAera + statData[0].cCity + `</p>
<div class="row station-tbale" style="width:250px">
<div class="col-sm-8 station_title">省份</div>
<div class="col-sm-8">`+ statData[0].cPrvoName + `</div>
<div class="col-sm-8 station_title">站名</div>
<div class="col-sm-8">`+ statData[0].cStatName + `</div>
</div>
<div class="row station-tbale" style="width:250px">
<div class="col-sm-8 station_title">站号</div>
<div class="col-sm-8">`+ statData[0].v01000 + `</div>
<div class="col-sm-8 station_title">R值</div>
<div class="col-sm-8">`+ Number(props.R).toFixed(3) + `</div>
</div>
<div class="row station-tbale" style="width:250px">
<div class="col-sm-8 station_title">站点数据</div>
<div class="col-sm-14">`+ legend[0] + `</div>
</div>
<div class="row station-tbale" style="width:250px">
<div class="col-sm-8 station_title">相关类型</div>
<div class="col-sm-14">`+ this.task.title + `</div>
</div>`;
this.popup = new Popup()
.setLngLat(e.eventData.lngLat)
.setHTML(this.propsHTML)
.addTo(this.mapbox.map);
})
}
六、 stop的四种类型
map.addLayer({
"paint": {
"circle-color": {
"type": "exponential",
"property": "val",
"stops": [
[0, "red"],
[500, "green"],
[1000, "blue"]
],
"base": 0.9
}
}
});
map.addLayer({
"paint": {
"circle-opacity": {
"type": "interval",
"property": "val",
"stops": [
[0, "red"],
[500, "green"],
[1000, "blue"],
]
}
}
});
map.addLayer({
"paint": {
"fill-color": {
"type": "categorical",
"property": "num",
"stops": [
[5, "red"],
[10, "green"],
]
}
}
});
map.addLayer({
"paint": {
"line-color": {
"type": "identity",
"property": "color"
}
}
});
按数据的最小最大值范围渲染颜色,生成图例(实例)
private loadYield(id: string, item: any) {
let yieldSource = this.map.getSource(id);
let showLayer = this.map.getLayer(id);
if (!yieldSource || !showLayer) return;
this._todoService.getProvYieldPolygon(this.selYear, item.text).then(areaData => {
if (!areaData) {
yieldSource.setData({
"type": "FeatureCollection",
"features": []
});
if (this.activeLayer == id)
this.yzNgxToastyService.warning("提示", "【" + this.selectedItem.text + "】作物" + this.selYear + "年无产量信息", 2000);
return;
}
yieldSource.setData(areaData);
let filterPro = "产量(吨)";
areaData.features.sort((val1, val2) => {
let proVal1 = val1['properties'][filterPro];
let proVal2 = val2['properties'][filterPro];
if (proVal1 < proVal2) {
return -1;
} else if (proVal1 > proVal2) {
return 1;
} else {
return 0;
}
});
let minValue = Math.floor(areaData.features[0]['properties'][filterPro]);
let maxValue = minValue;
for (let i = areaData.features.length - 1; i >= 0; i--) {
let t = Math.ceil(areaData.features[i]['properties'][filterPro]);
if (t && t > 0) {
maxValue = t;
break;
}
}
let midValue =Number(((maxValue + minValue) / 2).toFixed(1));
let stops = [
[minValue, "#51bbd6"],
[midValue, "#f1f075"],
[maxValue, "#f28cb1"]
];
let items = new Map<string, string>();
for (let i = 0; i < stops.length; i++) {
if (stops[i] == stops[stops.length - 1]) {
items.set("大于" + String(stops[i][0]), String(stops[i][1]));
} else {
items.set(String(stops[i][0] + "~" + stops[i + 1][0]), String(stops[i][1]));
}
}
this.legend = new Legend();
this.legend.unit = '产量(吨)'
this.legend.items = items;
this.map.addLegendControl(this.legend, "bottom-left");
if (this.legendShow) {
document.getElementsByClassName("legend")[0].className = "show legend";
} else {
document.getElementsByClassName("legend")[0].className = "hidden legend";
}
this.map.setFilter(id, ["has", filterPro]);
this.map.setPaintProperty(id, "fill-color", {
"property": filterPro,
"stops": stops,
"type": "interval",
});
this.map.setPaintProperty(id, "fill-opacity", 0.8);
if (this.activeLayer == id) {
this.map.setVisibility(id, true);
}
else {
this.map.setVisibility(id, false);
}
});
}