|
|
{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "from collections import namedtuple\n", "from math import degrees\n", "\n", "import cartopy.crs as ccrs\n", "import cartopy.feature as cfeature\n", "import ephem\n", "import matplotlib.pyplot as plt\n", "\n", "\n", "philly = ephem.Observer()\n", "philly.lon, philly.lat = '-75.16961', '39.92435'\n", "\n", "portland = ephem.Observer()\n", "portland.lon, portland.lat = '-122.68092', '45.50901'\n", "\n", "fo_29 = ephem.readtle(\n", " \"JAS-2 (FO-29)\",\n", " \"1 24278U 96046B 19132.42991715 .00000011 00000-0 48833-4 0 9994\",\n", " \"2 24278 98.5319 290.9039 0349934 336.8182 21.7496 13.53090691122769\",\n", ")\n", "\n", "lakes = cfeature.NaturalEarthFeature('physical', 'lakes', '50m', facecolor=\"none\")\n", "countries = cfeature.NaturalEarthFeature('cultural', 'admin_0_countries', '50m', facecolor=\"none\")\n", "states = cfeature.NaturalEarthFeature('cultural', 'admin_1_states_provinces_lines', '50m', facecolor=\"none\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "philly.date = '2019/5/12'\n", "portland.date = '2019/5/12'\n", "\n", "def next_n_passses(location, sat, n):\n", " passes = []\n", " for i in range(n):\n", " info = location.next_pass(sat)\n", " passes.append((info[0], info[4], info[3]))\n", " location.date = info[4] + 0.01\n", " return passes\n", "\n", "philly_passes = next_n_passses(philly, fo_29, 20)\n", "portland_passes = next_n_passses(portland, fo_29, 20)\n", "\n", "best_overlap = {\"score\": 10000}\n", "for o_rise, o_set, o_max in philly_passes:\n", " for t_rise, t_set, t_max in portland_passes:\n", " if t_rise < o_set and t_set > o_rise:\n", " score = abs(o_max - t_max)\n", " if best_overlap[\"score\"] > score:\n", " best_overlap = {\n", " \"score\": score,\n", " \"rise\": o_rise\n", " }" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "Point = namedtuple('Point', 'lat lon t')\n", "ground_track = Point([], [], 0)\n", "for i in range(300):\n", " t = best_overlap['rise'] - 0.01 + i/10000.0\n", " fo_29.compute(t)\n", " ground_track.lat.append(degrees(fo_29.sublat))\n", " ground_track.lon.append(degrees(fo_29.sublong))\n", "\n", "def dt(t):\n", " return t.datetime().strftime(\" %H:%M:%S\")\n", "\n", "begin = best_overlap['rise'] - 0.01\n", "philly.date = begin\n", "philly_pass = philly.next_pass(fo_29)\n", "fo_29.compute(philly_pass[0])\n", "philly_aos = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(philly_pass[0]))\n", "\n", "fo_29.compute(philly_pass[2])\n", "philly_max = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(philly_pass[2]))\n", "\n", "fo_29.compute(philly_pass[4])\n", "philly_los = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(philly_pass[4]))\n", "\n", "\n", "portland.date = begin\n", "portland_pass = portland.next_pass(fo_29)\n", "fo_29.compute(portland_pass[0])\n", "portland_aos = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(portland_pass[0]))\n", "\n", "fo_29.compute(portland_pass[2])\n", "portland_max = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(portland_pass[2]))\n", "\n", "fo_29.compute(portland_pass[4])\n", "portland_los = Point(degrees(fo_29.sublat), degrees(fo_29.sublong), dt(portland_pass[4]))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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 "text/plain": [ "<Figure size 792x612 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "proj = ccrs.NearsidePerspective(\n", " central_longitude=-95,\n", " central_latitude=35,\n", ")\n", "geodetic = ccrs.Geodetic()\n", "\n", "fig = plt.figure(figsize=(11, 8.5))\n", "ax = fig.add_axes([0.1, 0.1, 0.9, 0.9], projection=proj)\n", "ax.set_extent([-140, -50, 5, 85], ccrs.Geodetic())\n", "\n", "plt.title(\"FO-29 Pass {d}\".format(d=best_overlap['rise'].datetime().strftime(\"%b %d %Y %H:%M UTC\")), loc='left')\n", "ax.coastlines(resolution='50m', color=\"grey\", linewidth=0.4, alpha=0.3)\n", "ax.add_feature(lakes, edgecolor=\"grey\", linewidth=0.4, alpha=0.3)\n", "ax.add_feature(states, edgecolor=\"grey\", linewidth=0.4, alpha=0.2, dashes='--')\n", "ax.add_feature(countries, edgecolor=\"grey\", linewidth=0.4, alpha=0.3, dashes='--')\n", "\n", "\n", "ax.plot(ground_track.lon, ground_track.lat, 'k', lw=1, alpha=1, transform=geodetic)\n", "ax.plot([degrees(philly.lon), philly_aos.lon], [degrees(philly.lat), philly_aos.lat], 'k--', lw=0.5, transform=geodetic)\n", "ax.plot([degrees(philly.lon), philly_max.lon], [degrees(philly.lat), philly_max.lat], transform=geodetic)\n", "ax.plot([degrees(philly.lon), philly_los.lon], [degrees(philly.lat), philly_los.lat], 'k--', lw=0.5, transform=geodetic)\n", "\n", "ax.plot([degrees(portland.lon), portland_aos.lon], [degrees(portland.lat), portland_aos.lat], 'k--', lw=0.5, transform=geodetic)\n", "ax.plot([degrees(portland.lon), portland_max.lon], [degrees(portland.lat), portland_max.lat], transform=geodetic)\n", "ax.plot([degrees(portland.lon), portland_los.lon], [degrees(portland.lat), portland_los.lat], 'k--', lw=0.5, transform=geodetic)\n", "\n", "geodetic_transform = ccrs.Geodetic()._as_mpl_transform(ax)\n", "ax.text(philly_aos.lon, philly_aos.lat, philly_aos.t + \" Philly AOS\", fontsize=8, horizontalalignment='left', transform=geodetic_transform)\n", "ax.text(philly_max.lon, philly_max.lat, philly_max.t + \" Philly Max Alt\", fontsize=8, horizontalalignment='left', transform=geodetic_transform)\n", "ax.text(philly_los.lon, philly_los.lat, philly_los.t + \" Philly LOS\", fontsize=8, horizontalalignment='left', transform=geodetic_transform)\n", "\n", "ax.text(portland_aos.lon, portland_aos.lat, \"Portland AOS\" + portland_aos.t, fontsize=8, horizontalalignment='right', transform=geodetic_transform)\n", "ax.text(portland_max.lon, portland_max.lat, \"Portland Max Alt\" + portland_max.t, fontsize=8, horizontalalignment='right', transform=geodetic_transform)\n", "ax.text(portland_los.lon, portland_los.lat, \"Portland LOS\" + portland_los.t, fontsize=8, horizontalalignment='right', transform=geodetic_transform)\n", "\n", "\n", "plt.savefig(\"map.png\", dpi=190)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 2 }
|