openlayers入门开发系列之台风轨迹篇
2019-02-27 本文已影响6人
gis之家
本篇的重点内容是利用openlayers实现台风轨迹功能,效果图如下:
image
台风轨迹效果图:
image image image实现思路
- 界面设计
//台风
"<div style='height:25px;background:#30A4D5;margin-top:10px;width: 98%;margin-left: 3px;float: left;'>" +
"<span style='margin-left:5px;font-size: 13px;color:white;'>台风</span>" +
"</div>" +
'<div id="typhoonLayer" style="padding:5px;float: left;">' +
'<input type="checkbox" name="typhoonlayer" style="width: 15px;height: 15px;vertical-align: middle;margin: auto;"/>' +
'<label style="font-weight: normal;vertical-align: middle;margin: auto;">台风</label>' +
'</div>'
- 点击事件
//台风
$("#typhoonLayer input").bind("click", function () {
if (this.checked) {
listDialog = new bxmap.TyphoonListDialog();
listDialog.setTyphoonMap(bmap);
listDialog.show();
var map = bmap.getMap();
map.getView().setCenter([13286590.004642466, 2562780.6843453925]);
map.getView().setZoom(6);
//图例面板显示
$("#map_tl").css("display","block");
$("#map_tl>img").attr('src', GLOBAL.domainResource+"/Content/img/typhoonLegend.png");
$("#map_tl>img").css("width","auto");
$("#map_tl>img").css("height","350px");
}
else {
if(listDialog){
listDialog.close();
}
//图例面板隐藏
$("#map_tl").hide();
}
})
- 台风轨迹初始化
/**
* @description 初始化图层
* @param bmap
* @private
*/
bxmap.Typhoon.prototype._initializeLayers = function () {
//24小时48小时警戒线
this.picketLineLayer = new bxmap.layer.Vector({
source: new ol.source.Vector()
});
//台风实际路线节点
this.realNodesLayer = new bxmap.layer.Vector({
source: new ol.source.Vector(),
property: "symbol",
style: null,
context: function (feature) {
return feature["symbol"];
}
});
var symbolizer = new bxmap.symbol.UniqueValueSymbolizer();
var styles = this.styles;
symbolizer.addRule({ruleName: "default", styles: styles["TyphoonNodes_Unselected"]});
symbolizer.addRule({ruleName: "selected", styles: styles["TyphoonNodes_Selected"]});
symbolizer.addRule({ruleName: "unselected", styles: styles["TyphoonNodes_Unselected"]});
this.realNodesLayer.setSymbolizer(symbolizer);
//台风预测路线节点
this.forecastNodesLayer = new bxmap.layer.Vector({
source: new ol.source.Vector(),
property: "symbol",
style: null,
context: function (feature) {
return feature["symbol"];
}
});
symbolizer = new bxmap.symbol.UniqueValueSymbolizer();
symbolizer.addRule({ruleName: "default", styles: styles["TyphoonNodes_Unselected"]});
symbolizer.addRule({ruleName: "selected", styles: styles["TyphoonNodes_Selected"]});
symbolizer.addRule({ruleName: "unselected", styles: styles["TyphoonNodes_Unselected"]});
this.forecastNodesLayer.setSymbolizer(symbolizer);
//其他数据
this.resourceLayer = new bxmap.layer.Vector({
source: new ol.source.Vector()
});
}
- 台风轨迹样式设置代码
/**
* @description 创建样式
* @return {JSON}
*/
bxmap.Typhoon.prototype.createStyles = function () {
var output = {};
//台风节点
output["TyphoonNodes_Unselected"] = {
"热带低压": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngRddy})
})
,"热带风暴": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngRdfb})
})
,"强热带风暴": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngQrdfb})
})
,"台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngTf})
})
,"强台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngQtf})
})
,"超强台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 0.8, scale: 0.8, src: bxmap.Resource.TyphoonPngCqtf})
})
};
output["TyphoonNodes_Selected"] = {
"热带低压": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngRddy})
})
,"热带风暴": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngRdfb})
})
,"强热带风暴": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngQrdfb})
})
,"台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngTf})
})
,"强台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngQtf})
})
,"超强台风": new ol.style.Style({
image: new ol.style.Icon({opacity: 1, scale: 1, src: bxmap.Resource.TyphoonPngCqtf})
})
};
return output;
}
- 绘制默认警戒线
/**
* @description 绘制默认警戒线
*/
bxmap.Typhoon.prototype.drawDefaultPicketLine = function () {
//警戒线数据
var picketLine24 = '';
var picketLine48 = '';
if(this.isProjected){
picketLine24 = 'LINESTRING(14137575.3307 4028802.0261, 14137575.3307 2391878.5879, 12245143.9873 1689200.1396)';
picketLine48 = 'LINESTRING(14694172.7847 4028802.0261, 14694172.7847 1689200.1396, 11688546.5333 0)';
}else {
picketLine24 = 'LINESTRING(127 34, 127 21, 110 15)';
picketLine48 = 'LINESTRING(132 34, 132 15, 105 0)';
}
var WKTReader = new ol.format.WKT();
var feature24 = WKTReader.readFeature(picketLine24);
var feature48 = WKTReader.readFeature(picketLine48);
feature24.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ff0000',
width: 1
})
}));
feature48.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ffff99',
width: 1
})
}));
this.picketLineLayer.getSource().addFeatures([feature24, feature48]);
}
- 设置风圈
/**
* @description 设置风圈
* @param node - {JSON} 格式{"WD":"20.9","JD":"116.2","EN7Radii":"220","ES7Radii":"220","WS7Radii":"260","WN7Radii":"240","EN10Radii":"50","ES10Radii":"80","WS10Radii":"80","WN10Radii":"50"}
*/
bxmap.Typhoon.prototype.setWindCircle = function (node) {
if(node == null) return;
var n = node;
var center = [n.X,n.Y];
//台风位置
this._typhoonFeature.setGeometry(new ol.geom.Point([Number(center[0]),Number(center[1])]));
//7级风圈
if(n.EN7Radii){
var path = this.getSectorPoints(center, n.EN7Radii,0,90,30);
this._windEN7.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windEN7.setGeometry(null);
}
if(n.ES7Radii){
var path = this.getSectorPoints(center, n.ES7Radii,90,180,30);
this._windES7.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windES7.setGeometry(null);
}
if(n.WS7Radii){
var path = this.getSectorPoints(center, n.WS7Radii,180,270,30);
this._windWS7.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windWS7.setGeometry(null);
}
if(n.WN7Radii){
var path = this.getSectorPoints(center, n.WN7Radii,270,360,30);
this._windWN7.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windWN7.setGeometry(null);
}
//10级风圈
if(n.EN10Radii){
var path = this.getSectorPoints(center, n.EN10Radii,0,90,30);
this._windEN10.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windEN10.setGeometry(null);
}
if(n.ES10Radii){
var path = this.getSectorPoints(center, n.ES10Radii,90,180,30);
this._windES10.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windES10.setGeometry(null);
}
if(n.WS10Radii){
var path = this.getSectorPoints(center, n.WS10Radii,180,270,30);
this._windWS10.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windWS10.setGeometry(null);
}
if(n.WN10Radii){
var path = this.getSectorPoints(center, n.WN10Radii,270,360,30);
this._windWN10.setGeometry(new ol.geom.Polygon([path]));
}else{
this._windWN10.setGeometry(null);
}
}
/**
* @description 逆时针计算扇形风圈的点集合
* @param center - {Array<String|Number>}中心点,例如[117.23,23.123]
* @param radius - {String|Number} 半径km
* @param startAngle - {String|Number} 起始角度(单位°)
* @param endAngle - {String|Number} 结束角度(单位°)
* @param pointNum - {String|Number} 返回构成的弧点个数,默认30
* @return {Array}
*/
bxmap.Typhoon.prototype.getSectorPoints = function(center,radius,startAngle,endAngle,pointNum) {
radius = Number(radius) * 1000;
if(!this.isProjected){
var MetersPerUnit = 111319.49079327358; //1度多少米
radius = radius/MetersPerUnit;//转化为度
}
center = [Number(center[0]),Number(center[1])];
startAngle = Number(startAngle);
endAngle = Number(endAngle);
pointNum = Number(pointNum || 30);
var sin;
var cos;
var x;
var y;
var angle;
var points = new Array();
var pointsLL = new Array();
var lonlat = center;
points.push([center[0], center[1]]);
for (var i = 0; i <= pointNum; i++) {
angle = startAngle + (endAngle - startAngle) * i / pointNum;
sin = Math.sin(angle * Math.PI / 180);
cos = Math.cos(angle * Math.PI / 180);
x = center[0] + radius * sin;
y = center[1] + radius * cos;
points[i + 1] = [x, y];
}
points.push([center[0], center[1]]);
for (var j = 0; j < points.length; j++) {
pointsLL[j] = points[j];
}
return pointsLL;
}
GIS之家作品:GIS之家
GIS之家源码咨询:GIS之家webgis入门开发系列demo源代码咨询