首页
网络资源
技术分享
云资源
分享你我
行动起来,活在当下
累计撰写
118
篇文章
累计创建
13
个标签
累计收到
0
条评论
栏目
首页
网络资源
技术分享
云资源
目 录
CONTENT
最新文章
VUE3 使用 openlayers v6.6.1 绘制台风路径、台风圈
<p>ts代码:</p><pre class="brush:js;toolbar:false">import { Feature, Overlay } from 'ol'; import { Point, Polygon, LineString, Circle as GeomCircle } from 'ol/geom'; import { Vector as LayerVector } from 'ol/layer'; import { Style, Stroke, Circle, Fill } from 'ol/style'; import { Vector } from 'ol/source'; import { WKT } from 'ol/format'; import { fromLonLat } from 'ol/proj'; import d from '../assets/201929'; export default class Typhoon { _map: any; _speed: Number = 200; _forcColorDict: any = { 中国: '#ec5d72', 中国香港: '#ec7cfe', 中国台湾: '#ecaa65', 日本: '#56f66e', 美国: '#53dbfe', 韩国: '#72a4ac', 欧洲: '#4c54a6', }; _typhoonList: any = []; _typhoonData: any = {}; _nameOverlays: any = {}; _typhoonPlayFlag: any = {}; _typhoonPlayIndex: any = {}; _warnLines: any = null; _typhoonLayers: any = {}; _forecastFeatures: any = {}; _typhoonCircle: any = []; wktformat:any = new WKT(); constructor(map: any) { this._map = map; } init = () => { // 添加警戒线 this.addWarnLine(); // 添加地图事件 this.addMapEvent(); this.showTyphoon(d.data[0]); // 获取台风数据 // $.get('../../data/201929.json', (res) => { // _typhoonList = res; // showTyphoon(_typhoonList[0]); // }); }; addWarnLine = () => { const warnLineData = [ { color: 'blue', weight: 1, opacity: 0.8, dashArray: [0, 0], points: [ [105, 0], [113, 4.5], [119, 11], [119, 18], [127, 22], [127, 34], ], }, { color: 'green', weight: 1, opacity: 0.8, dashArray: [10, 5], points: [ [105, 0], [120, 0], [132, 15], [132, 34], ], }, ]; const features = []; for (var i = 0; i < warnLineData.length; i++) { const d = warnLineData[i]; const geometry = new LineString(d.points); geometry.transform('EPSG:4326', this._map.getView().getProjection()); const feature = new Feature({ geometry: geometry, attr: d, }); features.push(feature); } const source = new Vector({ features: features, }); this._warnLines = new LayerVector({ source: source, style: this.warnLineStyle, opacity: 0.8, }); this._map.addLayer(this._warnLines); }; // 警戒线样式设置 warnLineStyle = (feat: any) => { const attr = feat.get('attr'); return new Style({ stroke: new Stroke({ color: attr.color, width: attr.weight, lineDash: attr.dashArray, }), }); }; // 添加地图事件 addMapEvent = () => { // 鼠标移动事件 this._map.on('pointermove', (evt: any) => { const pixel = evt.pixel; const dom = this._map.getTargetElement(); if (this._map.hasFeatureAtPixel(pixel)) { dom.style.cursor = 'pointer'; const features = this._map.getFeaturesAtPixel(pixel); const feature = features[0]; // console.log(feature.get('attr')); } else { dom.style.cursor = 'default'; } }); this._map.on('click', (evt: any) => { const pixel = evt.pixel; if (this._map.hasFeatureAtPixel(pixel)) { const features = this._map.getFeaturesAtPixel(pixel); const feature = features[0]; const attr = feature.get('attr'); this._typhoonPlayIndex[attr.tfbh] = attr.index; this.showForecast(attr.tfbh, attr); } }); }; // 展示台风 showTyphoon = (typhoonData: any) => { const tfbh = typhoonData.tfbh; this._typhoonData[tfbh] = typhoonData; // 1. 添加台风名称 this.addNameOverlay(typhoonData); // 2. 创建展示图层 this.addTyphoonLayer(tfbh); // 3.开始播放 this.playTyphoon(tfbh); }; // 移除台风 removeTyphoon = (tfbh: any) => { // 删除台风名称 this._map.removeOverlay(this._nameOverlays[tfbh]); // 删除展示图层 this._map.removeLayer(this._typhoonLayers[tfbh].layer); // 消除定时器 clearInterval(this._typhoonPlayFlag[tfbh]); }; // 添加台风名称 addNameOverlay = (typhoonData: any) => { const nameDom = document.createElement('div'); nameDom.setAttribute('class', 'typhoon-name'); nameDom.innerHTML = typhoonData.name; const pointStart = typhoonData.points[0]; // const position = fromLonLat([ // pointStart.longitude, // pointStart.latitude, // ]); const nameOverlay = new Overlay({ element: nameDom, position: [pointStart.longitude, pointStart.latitude], positioning: 'center-left', offset: [15, 0], }); this._map.addOverlay(nameOverlay); this._nameOverlays[typhoonData.tfbh] = nameOverlay; this._typhoonCircle[typhoonData.tfbh]=this.drawTyphoonCircle(pointStart.longitude, pointStart.latitude);//台风圈 }; /** * 绘制台风圈 */ drawTyphoonCircle = (x: any, y: any) => { /** 台风配置 */ var Configs = { // CIRCLE_CENTER_X:104.21390114106414, // CIRCLE_CENTER_Y:35.847595169932646, CIRCLE_CENTER_X: x, CIRCLE_CENTER_Y: y, CIRCLE_R: { "SE": 0.5, "NE": 0.3, "NW": 0.2, "SW": 0.5 } }; /** 台风算法 */ var wkt = "POLYGON(("; var wkt0 = "", _interval = 6; for (var i = 0; i < 360 / _interval; i++) { var _r = 0; var _ang = i * _interval; if (_ang > 0 && _ang <= 90) { _r = Configs.CIRCLE_R.NE; } else if (_ang > 90 && _ang <= 180) { _r = Configs.CIRCLE_R.NW; } else if (_ang > 180 && _ang <= 270) { _r = Configs.CIRCLE_R.SW; } else { _r = Configs.CIRCLE_R.SE; } var x = Configs.CIRCLE_CENTER_X + _r * Math.cos(_ang * 3.14 / 180); var y = Configs.CIRCLE_CENTER_Y + _r * Math.sin(_ang * 3.14 / 180); wkt = wkt + "" + x + " " + y + ", "; if (i === 0) { wkt0 = "" + x + " " + y + ""; } } wkt = wkt + wkt0 + "))"; var features = new Array(); features.push(this.wktformat.readFeature(wkt)); features.push(this.wktformat.readFeature("POINT(" + Configs.CIRCLE_CENTER_X + " " + Configs.CIRCLE_CENTER_Y + ")")); var styleFunc = (feature: any, resolution: any) => { return new Style({ fill: new Fill({ color: 'rgba(255, 0, 0, 0.2)' }), stroke: new Stroke({ color: '#ffcc33', width: 2 }), image: new Circle({ radius: 4, fill: new Fill({ color: '#ff0000' }) }) }); }; var layerVector = new LayerVector({ source: new Vector({ features: features, }), style: styleFunc }); this._map.addLayer(layerVector); return layerVector; }; /** * 删除台风圈 * @param tfbh 分组名称 */ removeTyphoonCircle = (tfbh: any)=>{ // const source = this._typhoonCircle[tfbh].getSource(); // source.removeFeature(this._typhoonCircle[tfbh]); this._typhoonCircle[tfbh].getSource().clear(); this._map.removeLayer(this._typhoonCircle[tfbh]); } // 根据编号添加台风图层 addTyphoonLayer = (tfbh: any) => { const source = new Vector({ features: [], }); const layer = new LayerVector({ source: source, style: this.typhoonStyle, }); this._map.addLayer(layer); this._typhoonLayers[tfbh] = { source: source, layer: layer, }; this._forecastFeatures[tfbh] = []; }; // 播放台风 playTyphoon = (tfbh: any) => { let index = 0; const typhoonData = this._typhoonData[tfbh]; this.play(index, tfbh); this._typhoonPlayFlag[tfbh] = setInterval(() => { index++; if (index === typhoonData.points.length) { clearInterval(this._typhoonPlayFlag[tfbh]); } else { this.play(index, tfbh); } }, 200); }; // 播放单个点 play = (index: any, tfbh: any) => { // 删除预报 this.removeForecast(tfbh); this.removeTyphoonCircle(tfbh); this._map.removeLayer(this._typhoonCircle[tfbh]); this._typhoonPlayIndex[tfbh] = index; const points = this._typhoonData[tfbh].points; const point = points[index]; point.type = 'live'; point.index = index; point.tfbh = tfbh; if (index > 0) { const prePoint = points[index - 1]; point.start = [prePoint.longitude, prePoint.latitude]; } point.end = [point.longitude, point.latitude]; //const position = fromLonLat(point.end); const position = point.end; //点的数据设置 const feature = new Feature({ geometry: new Point(position), attr: point, }); this._typhoonLayers[tfbh].source.addFeature(feature); this._typhoonCircle[tfbh]=this.drawTyphoonCircle(point.longitude, point.latitude);//台风圈 // console.log("输出数据", this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry()); // this._typhoonCircle[tfbh].getSource().getFeatures()[0].getGeometry().setCoordinates(feature); // debugger; console.log("分类保存的台风圈"); // 最后一个实况点,展示预报路径 if (index === this._typhoonData[tfbh].points.length - 1) { this.showForecast(tfbh, point); } }; // 删除预报数据 removeForecast = (tfbh: any) => { const source = this._typhoonLayers[tfbh].source; for (var i = 0; i < this._forecastFeatures[tfbh].length; i++) { const f = this._forecastFeatures[tfbh][i]; source.removeFeature(f); } this._forecastFeatures[tfbh] = []; }; // 展示预报数据 showForecast = (tfbh: any, livePoint: any) => { const source = this._typhoonLayers[tfbh].source; // 1. 删除预报数据 this.removeForecast(tfbh); // 2. 添加预报 const forecast = livePoint.forecast; const features = []; for (var i = 0; i < forecast.length; i++) { const f = forecast[i]; for (var j = 0; j < f.points.length; j++) { const point = f.points[j]; const prePoint = f.points[j - 1]; point.sets = f.sets; point.type = 'forc'; point.index = j; point.start = j === 0 ? [livePoint.longitude, livePoint.latitude] : [prePoint.longitude, prePoint.latitude]; point.end = [point.longitude, point.latitude]; //const coords = fromLonLat(point.end); const coords = point.end; const feature = new Feature({ geometry: new Point(coords), attr: point, }); features.push(feature); } } source.addFeatures(features); this._forecastFeatures[tfbh] = features; }; // 根据风速获取点的颜色 getPointColor = (speed: any) => { let _color = ''; if (speed >= 10.8 && speed < 17.2) { _color = 'rgba(153, 255, 153, .9)'; } else if (speed >= 17.2 && speed < 24.5) { _color = 'rgba(102, 204, 255, .9)'; } else if (speed >= 24.5 && speed < 32.7) { _color = 'rgba(255, 255, 102, .9)'; } else if (speed >= 32.7 && speed < 41.5) { _color = 'rgba(253, 139, 0, .9)'; } else if (speed >= 41.5 && speed < 50.1) { _color = 'rgba(255, 51, 0, .9)'; } else { _color = 'rgba(255, 0, 255, .9)'; } return _color; }; // 台风展示样式 typhoonStyle = (feat: any) => { const attr = feat.get('attr'); const speed = 12; //attr.speed; const type = attr.type; const index = attr.index; const color = this.getPointColor(speed); let styles = []; // 点的样式 const radius = type === 'live' ? 4 : 3; const pointStyle = new Style({ image: new Circle({ radius: radius, fill: new Fill({ color: color, }), stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.6)', width: 1, }), }), }); styles.push(pointStyle); if (type === 'live' && index === this._typhoonPlayIndex[attr.tfbh]) { const center = feat.get('geometry').getCoordinates(); const fillStyle = new Fill({ color: 'rgba(0, 0, 0, 0.2)', }); // 7级风圈的样式 if (attr.radius7 > 0) { const geometry: any = this.getCircleGeometry(center, attr.radius7_quad); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#00bab2', width: 1, }), fill: fillStyle, }); styles.push(style); } // 10级风圈的样式 if (attr.radius10 > 0) { const geometry: any = this.getCircleGeometry( center, attr.radius10_quad ); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#ffff00', width: 1, }), fill: fillStyle, }); styles.push(style); } // 12级风圈的样式 if (attr.radius12 > 0) { const geometry: any = this.getCircleGeometry( center, attr.radius12_quad ); const style = new Style({ geometry: geometry, stroke: new Stroke({ color: '#da7341', width: 1, }), fill: fillStyle, }); styles.push(style); } } // 线的样式 const start = attr.start; const end = attr.end; const lineColor = this.getLineColor(type, attr.sets); const lineDash = type === 'live' ? [0] : [8]; const lineWidth = type === 'live' ? 2 : 1; if (start && start.length > 0) { const coords = [start, end]; const geometry = new LineString(coords); geometry.transform('EPSG:4326', this._map.getView().getProjection()); const lineStyle = new Style({ geometry: geometry, stroke: new Stroke({ color: lineColor, width: lineWidth, lineDash: lineDash, }), }); styles.push(lineStyle); } return styles; }; // 获取线的颜色 getLineColor = (type: any, sets: any) => { if (type === 'live') { return 'rgba(0, 0, 0, .6)'; } else { let color = this._forcColorDict[sets]; if (!color) color = 'rgba(0, 0, 0, .3)'; return color; } }; getCircleGeometry = (center: any, radiusData: any) => { if (typeof radiusData === 'number') { return new GeomCircle(center, radiusData * 1000); } else { if (radiusData['ne']) { let _coords = []; let _angInterval = 6; let _pointNums = 360 / (_angInterval * 4); let quadrant: any = { // 逆时针算角度 '0': 'ne', '1': 'nw', '2': 'sw', '3': 'se', }; for (let i = 0; i < 4; i++) { let _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是km if (!_r) _r = 0; for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) { let _ang = _angInterval * j; let x = center[0] + _r * Math.cos((_ang * Math.PI) / 180); let y = center[1] + _r * Math.sin((_ang * Math.PI) / 180); _coords.push([x, y]); } } return new Polygon([_coords]); } else { return null; } } }; }</pre><!--autointro--><!--75-->
2021-08-30
35
0
0
技术分享
WPF Expander自定义样式
<p><span style="color: #4D4D4D; font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; background-color: #FFFFFF;"></span></p><!--autointro--><!--74-->
2021-08-27
42
0
0
技术分享
c# 调用Everything-SDK 实现文件快速搜索
<p>Everything 下载地址:<a href="https://www.voidtools.com/zh-cn/downloads/" target="_blank" title="Everything" rel="noopener">点击访问</a></p><p>Everything-SDK 接口API和注意事项:<a href="https://www.voidtools.com/zh-cn/support/everything/sdk/" target="_blank" title="Everything-SDK" rel="noopener"></a></p><!--autointro--><!--73-->
2021-08-23
24
0
0
技术分享
华为光猫HS8145X6 补齐shell EPON与GPON双切换(最简单)
<p><span style="overflow-wrap: break-word; color: #444444; font-family: Tahoma, "Microsoft Yahei", Simsun; font-size: 14px; background-color: #FFFFFF;"></span></p><p>链接:https://pan.baidu.com/s/15aGgLiBgYPe9u0H03KG4bQ 提取码:5555 </p><!--autointro--><!--72-->
2021-08-06
237
0
0
技术分享
vite+electron+vue3 (ts) 搭建开发框架
<h1 class="_1RuRku" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5em; color: rgb(64, 64, 64); text-rendering: optimizelegibility; font-size: 30px; word-break: break-word; font-family: -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif; white-space: normal;"><!--autointro--><!--71-->
2021-07-22
39
0
0
技术分享
WPF MVVM(数据驱动模式) 简易代码生成工具
<p style="line-height: 16px;">因为使用winform已经做过一次了 <a href="https://github.com/Child-Cheng/GenerateCode" _src="https://github.com/Child-Cheng/GenerateCode">https://github.com/Child-Cheng/GenerateCode</a> </p><p style="line-height: 16px;">本次使用WPF MVVM 模式开发只是让部分人参考一下。大神可以忽略</p><!--autointro--><!--70-->
2021-07-19
37
0
0
技术分享
proxmark3(pm3) + 二代变色龙使用
<p><span style="color: #FF0000;"><strong>本文仅做记录。请不要参考本文做任何凌驾于法律之上的事。如果你在本文学习后做了任何违法事情与本文无关</strong></span></p><p><span style="color: #FF0000;"><strong><strong style="white-space: normal;">本文仅做记录。请不要参考本文做任何凌驾于法律之上的事。如果你在本文学习后做了任何违法事情与本文无关</strong></strong></span></p><!--autointro--><!--69-->
2021-07-12
38
0
0
技术分享
.net 多线程下载(文件分块下载)
public interface IDownloadProgressListener { void OnDownloadSize(long size); } /// <summary><!--autointro--><!--68-->
2021-06-30
35
0
0
技术分享
.net 多线程下载(已经测试通过)
public class MultiDownload { #region 初始化参数 private int bufferSize = 512;//缓冲池大小 &nb<!--autointro--><!--67-->
2021-06-26
23
0
0
技术分享
windows下编译cef最新版本并支持mp3/mp4
<p>官方:<a href="https://bitbucket.org/chromiumembedded/cef/src/master/" target="_blank" title="参考地址" rel="noopener">参考地址</a></p><p>编译分三大步:</p><p> 一、配置必须的环境<br/></p><p> 二、下载</p><p> 三、编译</p><p>一、准备工作</p><p> 1.Win10系统,必须64位,至少8GB的RAM,我采用win10 64位,16GRAM</p><!--autointro--><!--66-->
2021-06-10
26
0
0
技术分享
1
...
5
6
7
...
12