python:SunMoonTimeCalculator

# encoding: utf-8
# 版权所有 2024 ©涂聚文有限公司
# 许可信息查看:
# 描述: https://github.com/Broham/suncalcPy
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# Datetime  : 2024/5/14 21:59
# User      : geovindu
# Product   : PyCharm
# Project   : EssentialAlgorithms
# File      : sunCalc.py
# explain   : 学习import math
from datetime import datetime, timedelta
import time
import calendarclass SunMoonTimeCalculator(object):"""日出日落,月升月落计算类"""def __init__(self):""""""self.PI = 3.141592653589793  # math.pi"""派"""self.sin = math.sin"""sin 函数"""self.cos = math.cos"""函数"""self.tan = math.tan"""函数"""self.asin = math.asin"""函数"""self.atan = math.atan2"""函数"""self.acos = math.acos"""函数"""self.rad = self.PI / 180.0self.e = self.rad * 23.4397  # obliquity of the Earthself.dayMs = 1000 * 60 * 60 * 24self.J1970 = 2440588self.J2000 = 2451545self.J0 = 0.0009self.times = [[-0.833, 'sunrise', 'sunset'],[-0.3, 'sunriseEnd', 'sunsetStart'],[-6, 'dawn', 'dusk'],[-12, 'nauticalDawn', 'nauticalDusk'],[-18, 'nightEnd', 'night'],[6, 'goldenHourEnd', 'goldenHour']]def rightAscension(self,l, b):""":param l::param b::return:"""return self.atan(self.sin(l) * self.cos(self.e) - self.tan(b) * self.sin(self.e), self.cos(l))def declination(self,l, b):""":param l::param b::return:"""return self.asin(self.sin(b) * self.cos(self.e) + self.cos(b) * self.sin(self.e) * self.sin(l))def azimuth(self,H, phi, dec):""":param H::param phi::param dec::return:"""return self.atan(self.sin(H), self.cos(H) * self.sin(phi) - self.tan(dec) * self.cos(phi))def altitude(self,H, phi, dec):""":param H::param phi::param dec::return:"""return self.asin(self.sin(phi) * self.sin(dec) + self.cos(phi) * self.cos(dec) * self.cos(H))def siderealTime(self,d, lw):""":param d::param lw::return:"""return self.rad * (280.16 + 360.9856235 * d) - lwdef toJulian(self,date):""":param date::return:"""return (time.mktime(date.timetuple()) * 1000) / self.dayMs - 0.5 + self.J1970def fromJulian(self,j):""":param j::return:"""return datetime.fromtimestamp(((j + 0.5 - self.J1970) * self.dayMs) / 1000.0)def toDays(self,date):""":param date::return:"""return self.toJulian(date) - self.J2000def julianCycle(self,d, lw):""":param d::param lw::return:"""return round(d - self.J0 - lw / (2 * self.PI))def approxTransit(self,Ht, lw, n):""":param Ht::param lw::param n::return:"""return self.J0 + (Ht + lw) / (2 * self.PI) + ndef solarTransitJ(self,ds, M, L):""":param ds::param M::param L::return:"""return self.J2000 + ds + 0.0053 * self.sin(M) - 0.0069 * self.sin(2 * L)def hourAngle(self,h, phi, d):""":param h::param phi::param d::return:"""try:ret = self.acos((self.sin(h) - self.sin(phi) * self.sin(d)) / (self.cos(phi) * self.cos(d)))return retexcept ValueError as e:print(h, phi, d, "=>", e)def observerAngle(self,height):""":param height::return:"""return -2.076 * math.sqrt(height) / 60def solarMeanAnomaly(self,d):""":param d::return:"""return self.rad * (357.5291 + 0.98560028 * d)def eclipticLongitude(self,M):""":param M::return:"""C = self.rad * (1.9148 * self.sin(M) + 0.02 * self.sin(2 * M) + 0.0003 * self.sin(3 * M))  # equation of centerP = self.rad * 102.9372  # perihelion of the Earthreturn M + C + P + self.PIdef sunCoords(self,d):""":param d::return:"""M = self.solarMeanAnomaly(d)L = self.eclipticLongitude(M)return dict(dec=self.declination(L, 0),ra=self.rightAscension(L, 0))def getSetJ(self,h, lw, phi, dec, n, M, L):""":param h::param lw::param phi::param dec::param n::param M::param L::return:"""w = self.hourAngle(h, phi, dec)a = self.approxTransit(w, lw, n)return self.solarTransitJ(a, M, L)def moonCoords(self,d):"""geocentric ecliptic coordinates of the moon:param d::return:"""L = self.rad * (218.316 + 13.176396 * d)M = self.rad * (134.963 + 13.064993 * d)F = self.rad * (93.272 + 13.229350 * d)l = L + self.rad * 6.289 * self.sin(M)b = self.rad * 5.128 * self.sin(F)dt = 385001 - 20905 * self.cos(M)return dict(ra=self.rightAscension(l, b),dec=self.declination(l, b),dist=dt)def getMoonIllumination(self,date):"""Gets illumination properties of the moon for the given time.:param date::return:"""d = self.toDays(date)s = self.sunCoords(d)m = self.moonCoords(d)# distance from Earth to Sun in kmsdist = 149598000phi = self.acos(self.sin(s["dec"]) * self.sin(m["dec"]) + self.cos(s["dec"]) * self.cos(m["dec"]) * self.cos(s["ra"] - m["ra"]))inc = self.atan(sdist * self.sin(phi), m["dist"] - sdist * self.cos(phi))angle = self.atan(self.cos(s["dec"]) * self.sin(s["ra"] - m["ra"]),self.sin(s["dec"]) * self.cos(m["dec"]) - self.cos(s["dec"]) * self.sin(m["dec"]) * self.cos(s["ra"] - m["ra"]))return dict(fraction=(1 + self.cos(inc)) / 2,phase=0.5 + 0.5 * inc * (-1 if angle < 0 else 1) / self.PI,angle=angle)def getSunrise(self,date, lat, lng):""":param lat::param lng::return:"""ret = self.getTimes(date, lat, lng)return ret["sunrise"]def getTimes(self,date, lat, lng, height=0):"""Gets sun rise/set properties for the given time, location and height.:param date::param lat::param lng::param height::return:"""lw = self.rad * -lngphi = self.rad * latdh = self.observerAngle(height)d = self.toDays(date)n = self.julianCycle(d, lw)ds = self.approxTransit(0, lw, n)M = self.solarMeanAnomaly(ds)L = self.eclipticLongitude(M)dec = self.declination(L, 0)Jnoon = self.solarTransitJ(ds, M, L)result = dict(solarNoon=self.fromJulian(Jnoon).strftime('%Y-%m-%d %H:%M:%S'),nadir=self.fromJulian(Jnoon - 0.5).strftime('%Y-%m-%d %H:%M:%S'))for i in range(0, len(self.times)):time = self.times[i]h0 = (time[0] + dh) * self.radJset = self.getSetJ(h0, lw, phi, dec, n, M, L)Jrise = Jnoon - (Jset - Jnoon)result[time[1]] = self.fromJulian(Jrise).strftime('%Y-%m-%d %H:%M:%S')result[time[2]] = self.fromJulian(Jset).strftime('%Y-%m-%d %H:%M:%S')return resultdef hoursLater(self,date, h):""":param date::param h::return:"""return date + timedelta(hours=h)def getMoonTimes(self,date, lat, lng):""":param date::param lat::param lng::return:""""""Gets moon rise/set properties for the given time and location."""t = date.replace(hour=0, minute=0, second=0)hc = 0.133 * self.radh0 = self.getMoonPosition(t, lat, lng)["altitude"] - hcrise = 0sett = 0# go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)for i in range(1, 25, 2):h1 = self.getMoonPosition(self.hoursLater(t, i), lat, lng)["altitude"] - hch2 = self.getMoonPosition(self.hoursLater(t, i + 1), lat, lng)["altitude"] - hca = (h0 + h2) / 2 - h1b = (h2 - h0) / 2xe = -b / (2 * a)ye = (a * xe + b) * xe + h1d = b * b - 4 * a * h1roots = 0if d >= 0:dx = math.sqrt(d) / (abs(a) * 2)x1 = xe - dxx2 = xe + dxif abs(x1) <= 1:roots += 1if abs(x2) <= 1:roots += 1if x1 < -1:x1 = x2if roots == 1:if h0 < 0:rise = i + x1else:sett = i + x1elif roots == 2:rise = i + (x2 if ye < 0 else x1)sett = i + (x1 if ye < 0 else x2)if (rise and sett):breakh0 = h2result = dict()if (rise):result["rise"] = self.hoursLater(t, rise)if (sett):result["set"] = self.hoursLater(t, sett)if (not rise and not sett):value = 'alwaysUp' if ye > 0 else 'alwaysDown'result[value] = Truereturn resultdef getMoonPosition(self,date, lat, lng):"""Gets positional attributes of the moon for the given time and location.:param date::param lat::param lng::return:"""lw = self.rad * -lngphi = self.rad * latd = self.toDays(date)c = self.moonCoords(d)H = self.siderealTime(d, lw) - c["ra"]h = self.altitude(H, phi, c["dec"])# altitude correction for refractionh = h + self.rad * 0.017 / self.tan(h + self.rad * 10.26 / (h + self.rad * 5.10))pa = self.atan(self.sin(H), self.tan(phi) * self.cos(c["dec"]) - self.sin(c["dec"]) * self.cos(H))return dict(azimuth=self.azimuth(H, phi, c["dec"]),altitude=h,distance=c["dist"],parallacticAngle=pa)def getPosition(self,date, lat, lng):"""Returns positional attributes of the sun for the given time and location.:param date::param lat::param lng::return:"""lw = self.rad * -lngphi = self.rad * latd = self.toDays(date)c = self.sunCoords(d)H = self.siderealTime(d, lw) - c["ra"]# print("d", d, "c",c,"H",H,"phi", phi)return dict(azimuth=self.azimuth(H, phi, c["dec"]),altitude=self.altitude(H, phi, c["dec"]))

调用:

#日出日落 深圳
sun=Common.sunCalc.SunMoonTimeCalculator()
lat= 22.5445741
lng= 114.0545429
print(sun.getTimes(datetime.now(),  lat, lng))
print(sun.getMoonIllumination(datetime.now()))
#月升月落
print(sun.getMoonTimes(datetime.now(), lat, lng))

输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/704171.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百面算法工程师 | YOLOv6面试考点原理全解析

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv6面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习目标检测面试问题&#xff0c;并提供参考的回答…

【练习】分治--快排思想

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;算法(Java)&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 颜色分类 题目描述 题解 代码实现 排序数组 题目描述 题解 代码…

Shell之常用命令

目录 1.排序工具--sort命令 1.1 快读查找一个目录中最大文件 2.去重工具--uniq命令 2.1 分析判断远程登录错误次数&#xff0c;禁止该用户远程登录 3.修改工具--tr命令 4.列截取工具--cut命令 5.分割文件工具--split命令 6.合并文件列--paste命令 7.扫描工具--eval命令…

YOLOv8改进教程|加入可改变核卷积AKConv模块,效果远超DSConv!

⭐⭐ YOLOv8改进专栏|包含主干、模块、注意力机制、检测头等前沿创新 ​ ⭐⭐ 一、 论文介绍 论文链接&#xff1a;https://arxiv.org/abs/2311.11587 代码链接&#xff1a;GitHub - CV-ZhangXin/AKConv 论文速览&#xff1a;&#xff1a;AKConv是2023年11月发表的一种可变卷积…

mobarxtem应用与华为设备端口绑定技术

交换机端口绑定 华为交换机的基础配置与MOBAXTERM终端连接 实验步骤&#xff1a; 一、给每个交换机划分vlan并添加端口 1.单个vlan的划分 2.批量划分vlan 在高端交换机CE6800上批量划分连续编号的VLAN&#xff0c;本例中连续的vlan20到vlan25 [~CE6800]vlan b 20 to 25 3…

Django视图Views

Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求&#xff0c;并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…

鸿蒙应用布局ArkUI【基础运用案例】

布局基础运用案例 平级导航的复合网格视图 平级导航的复合网格视图常出现在同时展示多种不同内容的界面。 例如&#xff0c;市场类应用作为典型的平级导航&#xff0c;其首页不同板块采用了不同布局能力。 标题栏与搜索栏&#xff1a;因元素单一、位置固定在顶部&#xff0c…

【easyX】动手轻松掌握easyX 1

01 简单绘图 在这个程序中&#xff0c;我们先初始化绘图窗口。其次&#xff0c;简单绘制两条线。 #include <graphics.h>//绘图库头文件 #include <stdio.h> int main() {initgraph(640, 480);//初始化640✖480绘图屏幕line(200, 240, 440, 240);//画线(200,240)…

win11快速安装mysql数据库系统

win11快速安装mysql数据库系统 1、下载 1.1 打开官网 1.2 向下滚动页面 1.3 进入下载选项 1.4 下载8.0.4 LTS 1.5 开始下载 1.6 下载中 2、解压 大家注意&#xff0c;此时解压后目录是没有data目录的。 3、数据库初始化 3.1 管理员身份打开CMD 开始菜单上&#xff0c;输入…

【记录】docker笔记(五):Docker网络-Network Namespace

Docker 网络理论基础 要了解docker网络&#xff0c;先了解如下基础概念。 Network Namespace Docker 网络的底层原理是 Linux 的 Network Namespace &#xff0c;所以对于 Linux Network Namespace 的理解对 Docker 网络底层原理的理解非常重要。 简介 Network Name…

【Qt】widget圆角,styleSheet

仅配置widget&#xff0c;不设置其子组件。 #widget{background-color: rgba(255, 255, 255, 100); border-top-left-radius: 20; border-top-right-radius: 20; border-bottom-left-radius: 20; border-bottom-right-radius: 20;}