mirror of
				https://github.com/miaowware/qrm2.git
				synced 2025-10-31 11:20:19 -04:00 
			
		
		
		
	Merge branch 'master' into map
This commit is contained in:
		
						commit
						5a43495a00
					
				
							
								
								
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -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 | ||||||
|  | |||||||
							
								
								
									
										149
									
								
								exts/grid.py
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								exts/grid.py
									
									
									
									
									
								
							| @ -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): | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								info.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								info.py
									
									
									
									
									
								
							| @ -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" | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.py
									
									
									
									
									
								
							| @ -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) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user