Merge branch 'master' into map

This commit is contained in:
0x5c 2021-01-17 23:19:14 -05:00 committed by GitHub
commit 5a43495a00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 117 deletions

View File

@ -7,8 +7,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
### Added ### Added
- MUF and foF2 maps from [prop.kc2g.com](https://prop.kc2g.com/). - MUF and foF2 maps from [prop.kc2g.com](https://prop.kc2g.com/).
### Changed
- New colour theme for `?greyline`.
- Moved great circle distance and bearing calculation from `?ungrid` to `?griddistance`.
- `?ungrid` to `?latlong`.
### Deprecated
- `?ungrid`.
## [2.5.1] - 2020-12-10
### Fixed ### Fixed
- The result of `?greyline` was cached by discord and would get out of date. - The result of `?greyline` was cached by discord and would get out of date.
- Broken reaction functionality in `?hamstudy`.
## [2.5.0] - 2020-10-31 ## [2.5.0] - 2020-10-31
@ -142,7 +152,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 1.0.0 - 2019-07-31 [YANKED] ## 1.0.0 - 2019-07-31 [YANKED]
[Unreleased]: https://github.com/miaowware/qrm2/compare/v2.5.0...HEAD [Unreleased]: https://github.com/miaowware/qrm2/compare/v2.5.1...HEAD
[2.5.1]: https://github.com/miaowware/qrm2/releases/tag/v2.5.1
[2.5.0]: https://github.com/miaowware/qrm2/releases/tag/v2.5.0 [2.5.0]: https://github.com/miaowware/qrm2/releases/tag/v2.5.0
[2.4.1]: https://github.com/miaowware/qrm2/releases/tag/v2.4.1 [2.4.1]: https://github.com/miaowware/qrm2/releases/tag/v2.4.1
[2.4.0]: https://github.com/miaowware/qrm2/releases/tag/v2.4.0 [2.4.0]: https://github.com/miaowware/qrm2/releases/tag/v2.4.0

View File

@ -8,7 +8,7 @@ the GNU General Public License, version 2.
""" """
import math import gridtools
import discord.ext.commands as commands import discord.ext.commands as commands
@ -20,124 +20,49 @@ class GridCog(commands.Cog):
self.bot = bot self.bot = bot
@commands.command(name="grid", category=cmn.cat.maps) @commands.command(name="grid", category=cmn.cat.maps)
async def _grid_sq_lookup(self, ctx: commands.Context, lat: str, lon: str): async def _grid_sq_lookup(self, ctx: commands.Context, lat: float, lon: float):
("""Calculates the grid square for latitude and longitude coordinates, """ ("""Calculates the grid square for latitude and longitude coordinates."""
"""with negative being latitude South and longitude West.""") """\n\nCoordinates should be in decimal format, with negative being latitude South and longitude West."""
grid = "**" """\n\nTo calculate the latitude and longitude from a grid locator, use `latlong`""")
latf = float(lat) + 90 latlong = gridtools.LatLong(lat, lon)
lonf = float(lon) + 180 grid = gridtools.Grid(latlong)
if 0 <= latf <= 180 and 0 <= lonf <= 360:
grid += chr(ord("A") + int(lonf / 20)) embed = cmn.embed_factory(ctx)
grid += chr(ord("A") + int(latf / 10)) embed.title = f"Maidenhead Grid Locator for {latlong.lat:.5f}, {latlong.long:.5f}"
grid += chr(ord("0") + int((lonf % 20)/2)) embed.description = f"**{grid}**"
grid += chr(ord("0") + int((latf % 10)/1)) embed.colour = cmn.colours.good
grid += chr(ord("a") + int((lonf - (int(lonf/2)*2)) / (5/60)))
grid += chr(ord("a") + int((latf - (int(latf/1)*1)) / (2.5/60)))
grid += "**"
embed = cmn.embed_factory(ctx)
embed.title = f"Maidenhead Grid Locator for {float(lat):.6f}, {float(lon):.6f}"
embed.description = grid
embed.colour = cmn.colours.good
else:
embed = cmn.embed_factory(ctx)
embed.title = f"Error generating grid square for {lat}, {lon}."
embed.description = """Coordinates out of range.
The valid ranges are:
- Latitude: `-90` to `+90`
- Longitude: `-180` to `+180`"""
embed.colour = cmn.colours.bad
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="ungrid", aliases=["loc"], category=cmn.cat.maps) @commands.command(name="latlong", aliases=["latlon", "loc", "ungrid"], category=cmn.cat.maps)
async def _location_lookup(self, ctx: commands.Context, grid: str, grid2: str = None): async def _location_lookup(self, ctx: commands.Context, grid: str):
"""Calculates the latitude and longitude for the center of a grid square. ("""Calculates the latitude and longitude for the center of a grid locator."""
If two grid squares are given, the distance and azimuth between them is calculated.""" """\n\nTo calculate the grid locator from a latitude and longitude, use `grid`"""
if grid2 is None or grid2 == "": """\n\n*Warning: `ungrid` will be removed soon. Use one of the other names for this command.*""")
try: grid_obj = gridtools.Grid(grid)
grid = grid.upper()
loc = get_coords(grid)
embed = cmn.embed_factory(ctx) embed = cmn.embed_factory(ctx)
embed.title = f"Latitude and Longitude for {grid}" embed.title = f"Latitude and Longitude for {grid_obj}"
embed.colour = cmn.colours.good embed.colour = cmn.colours.good
embed.description = f"**{grid_obj.lat:.5f}, {grid_obj.long:.5f}**"
if len(grid) >= 6: if ctx.invoked_with == "ungrid":
embed.description = f"**{loc[0]:.5f}, {loc[1]:.5f}**" embed.add_field(name="Warning", value=(f"*`{ctx.prefix}ungrid` will be removed soon, use `{ctx.prefix}help "
embed.url = f"https://www.openstreetmap.org/#map=13/{loc[0]:.5f}/{loc[1]:.5f}" "latlong` to see other names for this command.*"))
else:
embed.description = f"**{loc[0]:.1f}, {loc[1]:.1f}**"
embed.url = f"https://www.openstreetmap.org/#map=10/{loc[0]:.1f}/{loc[1]:.1f}"
except Exception as e:
embed = cmn.embed_factory(ctx)
embed.title = f"Error generating latitude and longitude for grid {grid}."
embed.description = str(e)
embed.colour = cmn.colours.bad
else:
radius = 6371
try:
grid = grid.upper()
grid2 = grid2.upper()
loc = get_coords(grid)
loc2 = get_coords(grid2)
# Haversine formula
d_lat = math.radians(loc2[0] - loc[0])
d_lon = math.radians(loc2[1] - loc[1])
a = (math.sin(d_lat/2) ** 2
+ math.cos(math.radians(loc[0]))
* math.cos(math.radians(loc2[0]))
* math.sin(d_lon/2) ** 2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
d_mi = 0.6213712 * d
# Bearing
y_dist = math.sin(math.radians(loc2[1]-loc[1])) * math.cos(math.radians(loc2[0]))
x_dist = (math.cos(math.radians(loc[0]))
* math.sin(math.radians(loc2[0]))
- math.sin(math.radians(loc[0]))
* math.cos(math.radians(loc2[0]))
* math.cos(math.radians(loc2[1] - loc[1])))
bearing = (math.degrees(math.atan2(y_dist, x_dist)) + 360) % 360
embed = cmn.embed_factory(ctx)
embed.title = f"Great Circle Distance and Bearing from {grid} to {grid2}"
embed.description = f"**Distance:** {d:.1f} km ({d_mi:.1f} mi)\n**Bearing:** {bearing:.1f}°"
embed.colour = cmn.colours.good
except Exception as e:
embed = cmn.embed_factory(ctx)
embed.title = f"Error generating great circle distance and bearing from {grid} and {grid2}."
embed.description = str(e)
embed.colour = cmn.colours.bad
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="griddistance", aliases=["griddist", "distance", "dist"], category=cmn.cat.maps)
async def _dist_lookup(self, ctx: commands.Context, grid1: str, grid2: str):
"""Calculates the great circle distance and azimuthal bearing between two grid locators."""
g1 = gridtools.Grid(grid1)
g2 = gridtools.Grid(grid2)
def get_coords(grid: str): dist, bearing = gridtools.grid_distance(g1, g2)
if len(grid) < 3: dist_mi = 0.6214 * dist
raise ValueError("The grid locator must be at least 4 characters long.")
if not grid[0:2].isalpha() or not grid[2:4].isdigit(): embed = cmn.embed_factory(ctx)
if len(grid) <= 4: embed.title = f"Great Circle Distance and Bearing from {g1} to {g2}"
raise ValueError("The grid locator must be of the form AA##.") embed.description = f"**Distance:** {dist:.1f} km ({dist_mi:.1f} mi)\n**Bearing:** {bearing:.1f}°"
if len(grid) >= 6 and not grid[5:7].isalpha(): embed.colour = cmn.colours.good
raise ValueError("The grid locator must be of the form AA##AA.") await ctx.send(embed=embed)
lon = ((ord(grid[0]) - ord("A")) * 20) - 180
lat = ((ord(grid[1]) - ord("A")) * 10) - 90
lon += ((ord(grid[2]) - ord("0")) * 2)
lat += ((ord(grid[3]) - ord("0")) * 1)
if len(grid) >= 6:
# have subsquares
lon += ((ord(grid[4])) - ord("A")) * (5/60)
lat += ((ord(grid[5])) - ord("A")) * (2.5/60)
# move to center of subsquare
lon += (2.5/60)
lat += (1.25/60)
return (lat, lon)
# move to center of square
lon += 1
lat += 0.5
return (lat, lon)
def setup(bot: commands.Bot): def setup(bot: commands.Bot):

View File

@ -17,8 +17,7 @@ import common as cmn
class ImageCog(commands.Cog): class ImageCog(commands.Cog):
gl_url = ("http://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=NOAAtopo.evif" gl_url = "https://www.fourmilab.ch/cgi-bin/uncgi/Earth?img=ETOPO1_day-m.evif&dynimg=y&opt=-p"
"&imgsize=320&dynimg=y&opt=-p&lat=&lon=&alt=&tle=&date=0&utc=&jd=")
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot

View File

@ -12,5 +12,5 @@ authors = ("@ClassAbbyAmplifier#2229", "@0x5c#0639")
description = """A bot with various useful ham radio-related functions, written in Python.""" description = """A bot with various useful ham radio-related functions, written in Python."""
license = "Released under the GNU General Public License v2" license = "Released under the GNU General Public License v2"
contributing = "Check out the source on GitHub, contributions welcome: https://github.com/miaowware/qrm2" contributing = "Check out the source on GitHub, contributions welcome: https://github.com/miaowware/qrm2"
release = "2.5.0" release = "2.5.1"
bot_server = "https://discord.gg/Ntbg3J4" bot_server = "https://discord.gg/Ntbg3J4"

View File

@ -57,7 +57,7 @@ bot = commands.Bot(command_prefix=opt.prefix,
case_insensitive=True, case_insensitive=True,
description=info.description, help_command=commands.MinimalHelpCommand(), description=info.description, help_command=commands.MinimalHelpCommand(),
intents=intents, intents=intents,
member_cache=member_cache, member_cache_flags=member_cache,
loop=loop, loop=loop,
connector=connector) connector=connector)

View File

@ -1,5 +1,6 @@
discord.py~=1.5.0 discord.py~=1.5.0
ctyparser~=2.0 ctyparser~=2.0
gridtools~=1.0
beautifulsoup4 beautifulsoup4
lxml lxml
pytz pytz