本文主要是介绍openlayers3+中模拟晨昏线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近在flightware上看到一个好玩的功能,根据季节和一天中的时间,计算太阳的光照线,并模拟出白天黑夜分界线。这里分享一下。
1.结果
夏至日:北半球光照最多,白天最长,黑夜最短,北极圈极昼,南极圈极夜(下图为夏至日北京时间12点)
冬至日:北半球光照最少,白天最短,黑夜最长,北极圈极夜,南极圈极昼(下图为冬至日北京时间12点)
春分秋分:南北半球光照相当,日夜等长(下图为春分秋分日北京时间12点)
春分秋分:(下图为春分秋分日北京时间24点)
2.原理
原理大概就是根据客户端的时区和时间,计算出太阳分界线,并添加到地图上,计算过程太麻烦我看不太懂,如果有谁知道原理麻烦告知一下。
3.代码
先引入Javascript日期处理类库:moment.js,用于函数中的日期处理。
代码是一个函数,直接调用即可,我在原函数计算结果的基础上稍微修改了一下。
function addDayNightTerminator(){var twilightWidth = 667918;var twilightSteps = 13;var points = 288;var maxDimension = ol.proj.get('EPSG:3857').getExtent()[3];var minDimension = ol.proj.get('EPSG:3857').getExtent()[1];this.dayFeatures = [];this.nightFeatures = [];this._terminatorCurveSetCache = {};this._generateTerminatorCurveSet = function(dayOfYear) {offsetX = maxDimension;var declination = 0.40927971 * Math.sin((2 * Math.PI / 365) * (dayOfYear - 81.5));var termFunction = function(lon) {var cosFactor = -Math.cos((lon + offsetX) * (Math.PI / maxDimension));return (2 * maxDimension / Math.PI) * Math.atan(cosFactor / Math.tan(declination));};var lonPrimeFunction = function(t) {return (maxDimension - minDimension) / points;};var latPrimeFunction = function(t) {var aFactor = 2 * maxDimension / Math.PI;var bFactor = offsetX;var cFactor = Math.PI / maxDimension;var dFactor = Math.tan(declination);var cosOperand = ((minDimension + (((maxDimension - minDimension) / points) * t)) + bFactor) * cFactor;return (aFactor / (1 + Math.pow((-Math.cos(cosOperand) / dFactor), 2))) * (Math.sin(cosOperand) / dFactor) * (cFactor * (maxDimension - minDimension)) / points;};var lonParallelFunction = function(dist, t) {return (dist * latPrimeFunction(t)) / Math.sqrt(Math.pow(lonPrimeFunction(t), 2) + Math.pow(latPrimeFunction(t), 2));}var latParallelFunction = function(dist, t) {return (dist * lonPrimeFunction(t)) / Math.sqrt(Math.pow(lonPrimeFunction(t), 2) + Math.pow(latPrimeFunction(t), 2));}var lineCoords = [];for (var i = 0; i < twilightSteps; i++) {lineCoords.push([]);}for (var i = 0; i < points; i++) {var lon = minDimension + ((maxDimension - minDimension) / points * i);var lat = termFunction(lon);lineCoords[0].push([lon, lat]);var latDeg = ol.proj.toLonLat([lon, lat])[1];var latRad = latDeg * Math.PI / 180;var baseDist = (twilightWidth / (twilightSteps - 1)) / Math.cos(latRad);var steps = (twilightSteps - 1) / 2for (var j = 1; j <= steps; j++) {var dist = baseDist * j;lineCoords[j].push([lon + lonParallelFunction(dist, i), Math.max(lat - latParallelFunction(dist, i), minDimension)]);lineCoords[j + steps].push([lon - lonParallelFunction(dist, i), Math.min(lat + latParallelFunction(dist, i), maxDimension)]);}}var dayShimCoord = (declination < 0) ? minDimension : maxDimension;var nightShimCoord = (declination < 0) ? maxDimension : minDimension;return {curves: lineCoords,dayShimCoord: dayShimCoord,nightShimCoord: nightShimCoord};};this.getTerminatorCurveSet = function(dayOfYear) {if (!(dayOfYear in this._terminatorCurveSetCache)) {this._terminatorCurveSetCache[dayOfYear] = this._generateTerminatorCurveSet(dayOfYear);}return $.extend(true, {}, this._terminatorCurveSetCache[dayOfYear]);};this.setClock = function(clock) {var now = moment.unix(clock).utc();var baseCurveData = this.getTerminatorCurveSet(now.dayOfYear());var dayFraction = (now.hour() * 3600 + now.minute() * 60 + now.second()) / 86400;var offsetX = dayFraction * 2 * maxDimension;offsetX = Math.round(offsetX / ((2 * maxDimension) / points)) * ((2 * maxDimension) / points);$.each(baseCurveData.curves, $.proxy(function(k1, curve) {$.each(curve, function(k2, coord) {curve[k2][0] -= offsetX;});var count = 0;while (true) {if (count > curve.length) {break;}if (curve[0][0] < minDimension) {var coord = curve.shift();coord[0] += (maxDimension - minDimension);curve.push(coord);} else {break;}count++;}curve.push([curve[0][0] + (maxDimension - minDimension), curve[0][1]]);var nightCoords = curve.slice(0);nightCoords.push([maxDimension, baseCurveData.nightShimCoord], [minDimension, baseCurveData.nightShimCoord], curve[0]);/*$.each(nightCoords, function(i, coord) { //如果地图是4326坐标系,需要在这里转化nightCoords[i] = ol.proj.transform(nightCoords[i],'EPSG:3857','EPSG:4326')});*/var nightGeometry = new ol.geom.Polygon([nightCoords]);this.nightFeatures[k1].setGeometry(nightGeometry);}, this));};for (var i = 0; i < twilightSteps; i++) {this.nightFeatures.push(new ol.Feature({type: 'night'}));}this.setClock(Math.round(new Date().getTime()/1000));//设置时间,不设置则为当前时间 '2017-03-22 12:00'var twilightLayer = new ol.layer.Vector({source: new ol.source.Vector({features: [].concat(this.nightFeatures)}),opacity:0.1,style:new ol.style.Style({fill: new ol.style.Fill({color: 'rgba(0,0,0,0.4)'})})});map.addLayer(twilightLayer);
};
这篇关于openlayers3+中模拟晨昏线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!