@@ -1,180 +0,0 @@ | |||
# encoding: utf-8 | |||
import logging | |||
import os | |||
import subprocess | |||
from logging.handlers import RotatingFileHandler | |||
from flask import Flask, g, jsonify | |||
from flask_migrate import Migrate | |||
from flask_socketio import SocketIO | |||
from models import db | |||
import eventlet | |||
import texttable | |||
from flask_debugtoolbar import DebugToolbarExtension | |||
from utils import InvalidUsage, utils_download_and_ingest_faa | |||
from update_db import update_all as update_all_db | |||
from update_db import update_aircrafts, update_registrations | |||
from controllers.main import bp_main | |||
from pprint import pprint as pp | |||
from version import VERSION | |||
from config import LISTEN_HOST, LISTEN_PORT, SOCKETIO_CORS_ALLOWED_ORIGINS | |||
__VERSION__ = VERSION | |||
try: | |||
from raven.contrib.flask import Sentry | |||
import raven | |||
print(" * Sentry support loaded") | |||
HAS_SENTRY = True | |||
except ImportError: | |||
print(" * No Sentry support") | |||
HAS_SENTRY = False | |||
eventlet.monkey_patch() | |||
socketio = SocketIO(cors_allowed_origins=SOCKETIO_CORS_ALLOWED_ORIGINS) | |||
def create_app(config_filename="config.py"): | |||
# App configuration | |||
app = Flask(__name__) | |||
app.config.from_pyfile(config_filename) | |||
socketio.init_app( | |||
app, | |||
message_queue=app.config["SOCKETIO_MESSAGE_QUEUE"], | |||
cors_allowed_origins=app.config["SOCKETIO_CORS_ALLOWED_ORIGINS"], | |||
) | |||
app.jinja_env.add_extension("jinja2.ext.with_") | |||
app.jinja_env.add_extension("jinja2.ext.do") | |||
if HAS_SENTRY: | |||
app.config["SENTRY_RELEASE"] = raven.fetch_git_sha(os.path.dirname(__file__)) | |||
sentry = Sentry(app, dsn=app.config["SENTRY_DSN"]) # noqa: F841 | |||
print("Sentry support activated") | |||
print("Sentry DSN: %s" % app.config["SENTRY_DSN"]) | |||
if app.config["DEBUG"] is True: | |||
app.jinja_env.auto_reload = True | |||
app.logger.setLevel(logging.DEBUG) | |||
# Logging | |||
if not app.debug: | |||
formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s " "[in %(pathname)s:%(lineno)d]") | |||
file_handler = RotatingFileHandler("%s/errors_app.log" % os.getcwd(), "a", 1000000, 1) | |||
file_handler.setLevel(logging.DEBUG) | |||
file_handler.setFormatter(formatter) | |||
app.logger.addHandler(file_handler) | |||
migrate = Migrate(app, db) # noqa: F841 | |||
toolbar = DebugToolbarExtension(app) # noqa: F841 | |||
db.init_app(app) | |||
git_version = "" | |||
gitpath = os.path.join(os.getcwd(), ".git") | |||
if os.path.isdir(gitpath): | |||
git_version = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) | |||
if git_version: | |||
git_version = git_version.strip().decode("UTF-8") | |||
@app.before_request | |||
def before_request(): | |||
cfg = { | |||
"PYAIRWAVES_VERSION_VER": VERSION, | |||
"PYAIRWAVES_VERSION_GIT": git_version, | |||
"PYAIRWAVES_VERSION": "{0} ({1})".format(VERSION, git_version), | |||
} | |||
g.cfg = cfg | |||
@app.errorhandler(InvalidUsage) | |||
def handle_invalid_usage(error): | |||
response = jsonify(error.to_dict()) | |||
response.status_code = error.status_code | |||
return response | |||
app.register_blueprint(bp_main) | |||
@app.errorhandler(404) | |||
def page_not_found(msg): | |||
return jsonify({"error": "Not Found"}), 404 | |||
@app.errorhandler(403) | |||
def err_forbidden(msg): | |||
return jsonify({"error": "Access forbidden"}), 404 | |||
@app.errorhandler(410) | |||
def err_gone(msg): | |||
return jsonify({"error": "Gone"}), 404 | |||
if not app.debug: | |||
@app.errorhandler(500) | |||
def err_failed(msg): | |||
return jsonify({"error": "Something is broken"}), 404 | |||
@app.after_request | |||
def set_x_powered_by(response): | |||
response.headers["X-Powered-By"] = "pyAirwaves" | |||
return response | |||
# Other commands | |||
@app.cli.command() | |||
def routes(): | |||
"""Dump all routes of defined app""" | |||
table = texttable.Texttable() | |||
table.set_deco(texttable.Texttable().HEADER) | |||
table.set_cols_dtype(["t", "t", "t"]) | |||
table.set_cols_align(["l", "l", "l"]) | |||
table.set_cols_width([50, 30, 80]) | |||
table.add_rows([["Prefix", "Verb", "URI Pattern"]]) | |||
for rule in sorted(app.url_map.iter_rules(), key=lambda x: str(x)): | |||
methods = ",".join(rule.methods) | |||
table.add_row([rule.endpoint, methods, rule]) | |||
print(table.draw()) | |||
@app.cli.command() | |||
def config(): | |||
"""Dump config""" | |||
pp(app.config) | |||
@app.cli.command() | |||
def seed(): | |||
"""Seed database with default content""" | |||
# make_db_seed(db) | |||
pass | |||
@app.cli.command() | |||
def download_and_ingest_faa(): | |||
"""Downloads and ingest FAA datas""" | |||
utils_download_and_ingest_faa() | |||
@app.cli.command() | |||
def update_aircrafts_db(): | |||
"""Downloads and ingest various datas""" | |||
update_all_db() | |||
@app.cli.command() | |||
def import_aircrafts(): | |||
"""Ingest aircrafts""" | |||
update_aircrafts() | |||
@app.cli.command() | |||
def import_registrations(): | |||
"""Ingest registrations""" | |||
update_registrations() | |||
return app | |||
if __name__ == "__main__": | |||
app = create_app() | |||
socketio.run(app, host=LISTEN_HOST, port=LISTEN_PORT, debug=app.config["DEBUG"]) |
@@ -1,52 +1,9 @@ | |||
# Website translations | |||
BABEL_DEFAULT_LOCALE = "en" | |||
LISTEN_HOST = '127.0.0.1' | |||
LISTEN_PORT = '5000' | |||
# If using sentry, set a DSN | |||
SENTRY_USER_ATTRS = ['name', 'email'] | |||
SENTRY_DSN = "" | |||
SQLALCHEMY_DATABASE_URI = \ | |||
'postgresql+psycopg2://postgres@database/pyairwaves' | |||
# Redis configuration for socket.io | |||
SOCKETIO_MESSAGE_QUEUE = "redis://127.0.0.1:6379/3" | |||
# Redis configuration for the ingesters<>backend pubsub | |||
REDIS_URL = "redis://127.0.0.1:6379/3" | |||
SOCKETIO_CORS_ALLOWED_ORIGINS = ["https://pyairwaves.some.where/"] | |||
# or to entirely disable CORS | |||
# SOCKETIO_CORS_ALLOWED_ORIGINS = "*" | |||
# URL to FAA Archive | |||
FAA_ARCHIVE_URL = "https://registry.faa.gov/database/ReleasableAircraft.zip" | |||
FAA_DL_TEMP_PATH = "/tmp/faaingest/" | |||
UPDATE_DB_TEMP_PATH = "/tmp/updatedb_pyairwaves/" | |||
# Hostname on where this server is running | |||
PYAW_HOSTNAME = 'potato' | |||
# Sources for ADS-B and AIS, PLEASE NOTE that currently only one source is handled for each ! | |||
# Port for ADSB (dump1090) needs to be 30003 (SBS BaseStation) | |||
# Port for AIS (rtl-ais) needs to be 10110 | |||
ADSB_SOURCE = {"host": "patate", "port": 30003, "name": "patate", "reconnect_delay": 5, "thread_timeout": 30} | |||
AIS_SOURCE = {'host': 'patate', 'port': 10110, "name": "patate", "reconnect_delay": 5, "thread_timeout": 30} | |||
SECRET_KEY = "pls fill me" | |||
# Development only options | |||
DEBUG = False | |||
TESTING = False | |||
SQLALCHEMY_ECHO = False | |||
DEBUG_TB_PROFILER_ENABLED = False | |||
DEBUG_TB_INTERCEPT_REDIRECTS = False | |||
# Do not touch that | |||
SQLALCHEMY_TRACK_MODIFICATIONS = False | |||
SQLALCHEMY_RECORD_QUERIES = True | |||
# Users can change password | |||
# Do not disable, will breaks things | |||
SECURITY_CHANGEABLE = True | |||
# Password hash algorithm | |||
SECURITY_PASSWORD_HASH = 'bcrypt' |
@@ -34,21 +34,23 @@ Please makes sure your postgresql is in UTF8 ! In doubt uses `-E UTF8` when doin | |||
cd ~/backend/ | |||
mix ecto.create | |||
mix ecto.migrate | |||
# Import datas in database | |||
# expected around 10191 items | |||
mix pyairwaves.update_aircrafts | |||
# expected around 234 items | |||
mix pyairwaves.update_aircrafts_registrations | |||
# Import more datas | |||
# expected: | |||
# mode_s aco ~94924 | |||
# mode_s acm ~176708 | |||
# mode_s ogn ~16240 | |||
flask update-aircrafts-db | |||
mix pyairwaves.update_translations | |||
mix pyairwaves.update_aircrafts_mode_s | |||
mix pyairwaves.update_aircrafts_mode_sogn | |||
# Python part for the ingesters | |||
cd ~/ | |||
python3 -m venv venv | |||
cd pyAirwaves | |||
$EDITOR config.py | |||
# don't forget to always enable the virtualenv | |||
source ~/venv/bin/activate | |||
pip install -r requirements.txt | |||
# Automatic run | |||
@@ -1 +0,0 @@ | |||
Generic single-database configuration. |
@@ -1,45 +0,0 @@ | |||
# A generic, single database configuration. | |||
[alembic] | |||
# template used to generate migration files | |||
# file_template = %%(rev)s_%%(slug)s | |||
# set to 'true' to run the environment during | |||
# the 'revision' command, regardless of autogenerate | |||
# revision_environment = false | |||
# Logging configuration | |||
[loggers] | |||
keys = root,sqlalchemy,alembic | |||
[handlers] | |||
keys = console | |||
[formatters] | |||
keys = generic | |||
[logger_root] | |||
level = WARN | |||
handlers = console | |||
qualname = | |||
[logger_sqlalchemy] | |||
level = WARN | |||
handlers = | |||
qualname = sqlalchemy.engine | |||
[logger_alembic] | |||
level = INFO | |||
handlers = | |||
qualname = alembic | |||
[handler_console] | |||
class = StreamHandler | |||
args = (sys.stderr,) | |||
level = NOTSET | |||
formatter = generic | |||
[formatter_generic] | |||
format = %(levelname)-5.5s [%(name)s] %(message)s | |||
datefmt = %H:%M:%S |
@@ -1,95 +0,0 @@ | |||
from __future__ import with_statement | |||
import logging | |||
from logging.config import fileConfig | |||
from alembic import context | |||
from sqlalchemy import engine_from_config, pool | |||
from flask import current_app | |||
# this is the Alembic Config object, which provides | |||
# access to the values within the .ini file in use. | |||
config = context.config | |||
# Interpret the config file for Python logging. | |||
# This line sets up loggers basically. | |||
fileConfig(config.config_file_name) | |||
logger = logging.getLogger("alembic.env") | |||
# add your model's MetaData object here | |||
# for 'autogenerate' support | |||
# from myapp import mymodel | |||
# target_metadata = mymodel.Base.metadata | |||
config.set_main_option("sqlalchemy.url", current_app.config.get("SQLALCHEMY_DATABASE_URI")) | |||
target_metadata = current_app.extensions["migrate"].db.metadata | |||
# other values from the config, defined by the needs of env.py, | |||
# can be acquired: | |||
# my_important_option = config.get_main_option("my_important_option") | |||
# ... etc. | |||
def run_migrations_offline(): | |||
"""Run migrations in 'offline' mode. | |||
This configures the context with just a URL | |||
and not an Engine, though an Engine is acceptable | |||
here as well. By skipping the Engine creation | |||
we don't even need a DBAPI to be available. | |||
Calls to context.execute() here emit the given string to the | |||
script output. | |||
""" | |||
url = config.get_main_option("sqlalchemy.url") | |||
context.configure(url=url) | |||
with context.begin_transaction(): | |||
context.run_migrations() | |||
def run_migrations_online(): | |||
"""Run migrations in 'online' mode. | |||
In this scenario we need to create an Engine | |||
and associate a connection with the context. | |||
""" | |||
# this callback is used to prevent an auto-migration from being generated | |||
# when there are no changes to the schema | |||
# reference: http://alembic.readthedocs.org/en/latest/cookbook.html | |||
def process_revision_directives(context, revision, directives): | |||
if getattr(config.cmd_opts, "autogenerate", False): | |||
script = directives[0] | |||
if script.upgrade_ops.is_empty(): | |||
directives[:] = [] | |||
logger.info("No changes in schema detected.") | |||
engine = engine_from_config( | |||
config.get_section(config.config_ini_section), prefix="sqlalchemy.", poolclass=pool.NullPool | |||
) | |||
connection = engine.connect() | |||
context.configure( | |||
connection=connection, | |||
target_metadata=target_metadata, | |||
process_revision_directives=process_revision_directives, | |||
transaction_per_migration=True, | |||
**current_app.extensions["migrate"].configure_args, | |||
) | |||
try: | |||
with context.begin_transaction(): | |||
context.run_migrations() | |||
finally: | |||
connection.close() | |||
if context.is_offline_mode(): | |||
run_migrations_offline() | |||
else: | |||
run_migrations_online() |
@@ -1,22 +0,0 @@ | |||
"""${message} | |||
Revision ID: ${up_revision} | |||
Revises: ${down_revision} | |||
Create Date: ${create_date} | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = ${repr(up_revision)} | |||
down_revision = ${repr(down_revision)} | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
${imports if imports else ""} | |||
def upgrade(): | |||
${upgrades if upgrades else "pass"} | |||
def downgrade(): | |||
${downgrades if downgrades else "pass"} |
@@ -1,33 +0,0 @@ | |||
"""Create ACARS translation table | |||
Revision ID: 7f5c2634ef59 | |||
Revises: None | |||
Create Date: 2019-02-24 09:58:19.032683 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "7f5c2634ef59" | |||
down_revision = None | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.create_table( | |||
"translation", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("reg", sa.String(length=20), nullable=True), | |||
sa.Column("reg_correct", sa.String(length=20), nullable=True), | |||
sa.Column("operator", sa.String(length=20), nullable=True), | |||
sa.Column("operator_correct", sa.String(length=20), nullable=True), | |||
sa.Column("source", sa.String(length=255), nullable=True), | |||
sa.Column("date_added", sa.DateTime(), nullable=True), | |||
sa.Column("date_modified", sa.DateTime(), nullable=True), | |||
sa.PrimaryKeyConstraint("id"), | |||
) | |||
def downgrade(): | |||
op.drop_table("translation") |
@@ -1,46 +0,0 @@ | |||
"""Add AircraftModeS and AircraftOwner | |||
Revision ID: 4a351f950cdd | |||
Revises: 7f5c2634ef59 | |||
Create Date: 2019-02-24 10:50:44.337330 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "4a351f950cdd" | |||
down_revision = "7f5c2634ef59" | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.create_table( | |||
"aircraft_modes", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("first_created", sa.DateTime(), nullable=True), | |||
sa.Column("last_modified", sa.DateTime(), nullable=True), | |||
sa.Column("mode_s", sa.String(length=6), nullable=False), | |||
sa.Column("mode_s_country", sa.String(length=40), nullable=True), | |||
sa.Column("registration", sa.String(length=20), nullable=True), | |||
sa.Column("icao_type_code", sa.String(length=4), nullable=True), | |||
sa.Column("type_flight", sa.String(length=50), nullable=True), | |||
sa.Column("source", sa.String(length=255), nullable=True), | |||
sa.Column("source_type", sa.String(length=255), nullable=True), | |||
sa.PrimaryKeyConstraint("id"), | |||
) | |||
op.create_table( | |||
"aircraft_owner", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("registration", sa.String(length=255), nullable=False), | |||
sa.Column("base", sa.String(length=255), nullable=True), | |||
sa.Column("owner", sa.String(length=255), nullable=True), | |||
sa.Column("date_first_reg", sa.DateTime(), nullable=True), | |||
sa.Column("source", sa.String(length=255), nullable=False), | |||
sa.PrimaryKeyConstraint("id"), | |||
) | |||
def downgrade(): | |||
op.drop_table("aircraft_owner") | |||
op.drop_table("aircraft_modes") |
@@ -1,22 +0,0 @@ | |||
"""Add is_private aircraft owner info | |||
Revision ID: 7dddb7d187c9 | |||
Revises: 4a351f950cdd | |||
Create Date: 2019-02-24 11:38:07.778807 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "7dddb7d187c9" | |||
down_revision = "4a351f950cdd" | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.add_column("aircraft_owner", sa.Column("is_private", sa.Boolean(), nullable=True)) | |||
def downgrade(): | |||
op.drop_column("aircraft_owner", "is_private") |
@@ -1,37 +0,0 @@ | |||
"""Add Aircrafts table | |||
Revision ID: bcc5cc4c389a | |||
Revises: 7dddb7d187c9 | |||
Create Date: 2019-02-24 14:10:14.608927 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "bcc5cc4c389a" | |||
down_revision = "7dddb7d187c9" | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.create_table( | |||
"aircraft", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("icao", sa.String(length=10), nullable=False), | |||
sa.Column("type", sa.String(length=255), nullable=False), | |||
sa.Column("manufacturer", sa.String(length=255), nullable=False), | |||
sa.Column("official_page", sa.String(length=255), nullable=False), | |||
sa.Column("aircraft_shadow", sa.String(length=255), nullable=True), | |||
sa.Column("aircraft_description", sa.String(length=255), nullable=True), | |||
sa.Column("engine_type", sa.String(length=255), nullable=True), | |||
sa.Column("engine_count", sa.Integer(), nullable=True), | |||
sa.Column("wake_category", sa.String(length=10), nullable=True), | |||
sa.Column("mfr", sa.String(length=255), nullable=True), | |||
sa.PrimaryKeyConstraint("id"), | |||
sa.UniqueConstraint("icao"), | |||
) | |||
def downgrade(): | |||
op.drop_table("aircraft") |
@@ -1,28 +0,0 @@ | |||
"""Add Aircraft Registrations | |||
Revision ID: cb6b54abcdb3 | |||
Revises: bcc5cc4c389a | |||
Create Date: 2019-02-26 09:47:25.263327 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "cb6b54abcdb3" | |||
down_revision = "bcc5cc4c389a" | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.create_table( | |||
"aircraft_registration", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("country", sa.String(length=255), nullable=False), | |||
sa.Column("prefix", sa.String(length=10), nullable=False), | |||
sa.PrimaryKeyConstraint("id"), | |||
) | |||
def downgrade(): | |||
op.drop_table("aircraft_registration") |
@@ -1,31 +0,0 @@ | |||
"""Add missing performance index | |||
Revision ID: 23e0cd74b0aa | |||
Revises: cb6b54abcdb3 | |||
Create Date: 2020-02-12 22:29:07.056507 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "23e0cd74b0aa" | |||
down_revision = "cb6b54abcdb3" | |||
from alembic import op # noqa: E402 | |||
def upgrade(): | |||
op.create_index(op.f("ix_aircraft_modes_icao_type_code"), "aircraft_modes", ["icao_type_code"], unique=False) | |||
op.create_index(op.f("ix_aircraft_modes_mode_s"), "aircraft_modes", ["mode_s"], unique=False) | |||
op.create_index(op.f("ix_aircraft_modes_mode_s_country"), "aircraft_modes", ["mode_s_country"], unique=False) | |||
op.create_index(op.f("ix_aircraft_modes_registration"), "aircraft_modes", ["registration"], unique=False) | |||
op.create_index(op.f("ix_aircraft_owner_registration"), "aircraft_owner", ["registration"], unique=False) | |||
op.create_index(op.f("ix_aircraft_registration_country"), "aircraft_registration", ["country"], unique=False) | |||
def downgrade(): | |||
op.drop_index(op.f("ix_aircraft_registration_country"), table_name="aircraft_registration") | |||
op.drop_index(op.f("ix_aircraft_owner_registration"), table_name="aircraft_owner") | |||
op.drop_index(op.f("ix_aircraft_modes_registration"), table_name="aircraft_modes") | |||
op.drop_index(op.f("ix_aircraft_modes_mode_s_country"), table_name="aircraft_modes") | |||
op.drop_index(op.f("ix_aircraft_modes_mode_s"), table_name="aircraft_modes") | |||
op.drop_index(op.f("ix_aircraft_modes_icao_type_code"), table_name="aircraft_modes") |
@@ -1,54 +0,0 @@ | |||
"""Add future table for ADSB history | |||
Revision ID: 8df93fae7d26 | |||
Revises: 23e0cd74b0aa | |||
Create Date: 2020-02-12 22:30:19.539620 | |||
""" | |||
# revision identifiers, used by Alembic. | |||
revision = "8df93fae7d26" | |||
down_revision = "23e0cd74b0aa" | |||
from alembic import op # noqa: E402 | |||
import sqlalchemy as sa # noqa: E402 | |||
def upgrade(): | |||
op.create_table( | |||
"archive_adsb_message", | |||
sa.Column("id", sa.Integer(), nullable=False), | |||
sa.Column("message_type", sa.String(length=5), nullable=False), | |||
sa.Column("transmission_type", sa.Integer(), nullable=False), | |||
sa.Column("session_id", sa.String(length=20), nullable=True), | |||
sa.Column("aircraft_id", sa.String(length=20), nullable=True), | |||
sa.Column("hex_ident", sa.String(length=20), nullable=True), | |||
sa.Column("flight_id", sa.String(length=20), nullable=True), | |||
sa.Column("date_msg_gen", sa.String(length=20), nullable=True), | |||
sa.Column("time_msg_gen", sa.String(length=20), nullable=True), | |||
sa.Column("msg_gen", sa.DateTime(), nullable=True), | |||
sa.Column("date_msg_log", sa.String(length=20), nullable=True), | |||
sa.Column("time_msg_log", sa.String(length=20), nullable=True), | |||
sa.Column("msg_log", sa.DateTime(), nullable=True), | |||
sa.Column("callsign", sa.String(length=20), nullable=True), | |||
sa.Column("altitude", sa.Integer(), nullable=True), | |||
sa.Column("ground_speed", sa.Integer(), nullable=True), | |||
sa.Column("track", sa.String(length=20), nullable=True), | |||
sa.Column("latitude", sa.Float(), nullable=True), | |||
sa.Column("longitude", sa.Float(), nullable=True), | |||
sa.Column("vertical_rate", sa.Integer(), nullable=True), | |||
sa.Column("squawk", sa.Integer(), nullable=True), | |||
sa.Column("alert", sa.String(length=20), nullable=True), | |||
sa.Column("emergency", sa.String(length=20), nullable=True), | |||
sa.Column("spi_ident", sa.String(length=20), nullable=True), | |||
sa.Column("is_on_ground", sa.Boolean(), nullable=True), | |||
sa.Column("src", sa.String(length=255), nullable=True), | |||
sa.Column("client_name", sa.String(length=255), nullable=True), | |||
sa.Column("data_origin", sa.String(length=255), nullable=True), | |||
sa.Column("entry_point", sa.String(length=255), nullable=True), | |||
sa.PrimaryKeyConstraint("id"), | |||
) | |||
def downgrade(): | |||
op.drop_table("archive_adsb_message") |
@@ -8,6 +8,7 @@ exclude = ''' | |||
| \__pycache__ | |||
| venv | |||
| front | |||
| backend | |||
)/ | |||
''' | |||
skip-numeric-underscore-normalization = true |
@@ -2,15 +2,9 @@ psycopg2-binary==2.8.4 | |||
texttable==1.6.2 | |||
Unidecode==1.1.1 | |||
python-magic==0.4.15 | |||
flask==1.1.1 | |||
python-slugify==4.0.0 | |||
sqlalchemy==1.3.13 | |||
bcrypt==3.1.7 | |||
flask_migrate==2.5.2 | |||
sqlalchemy_searchable==1.1.0 | |||
flask_debugtoolbar==0.11.0 | |||
redis==3.4.1 | |||
pyais==1.0.0 | |||
Flask-SocketIO==4.2.1 | |||
eventlet==0.25.1 | |||
gunicorn==20.0.4 |
@@ -8,7 +8,7 @@ python_files = tests/*.py | |||
[flake8] | |||
max-line-length = 120 | |||
ignore = F405,E501,W504,W503,E231,E203,F601 | |||
exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,venv,.eggs | |||
exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,venv,.eggs,backend | |||
[coverage:run] | |||
omit = | |||
@@ -19,6 +19,7 @@ omit = | |||
**/*__init__.py | |||
venv/* | |||
front/* | |||
backend/* | |||
[isort] | |||
line_length=120 |
@@ -10,20 +10,14 @@ setup( | |||
author="Dashie", | |||
author_email="dashie@sigpipe.me", | |||
install_requires=[ | |||
"Flask", | |||
"SQLAlchemy", | |||
"SQLAlchemy-Searchable", | |||
"SQLAlchemy-Utils", | |||
"Flask-DebugToolbar", | |||
"Flask-Migrate", | |||
"Flask-SQLAlchemy", | |||
"bcrypt", | |||
"psycopg2-binary", | |||
"unidecode", | |||
"texttable", | |||
"redis", | |||
"flask-socketio", | |||
"eventlet", | |||
"pyais", | |||
], | |||
setup_requires=["pytest-runner"], | |||
@@ -1,2 +0,0 @@ | |||
.leaflet-control-locate a{font-size:1.4em;color:#444;cursor:pointer}.leaflet-control-locate.active a{color:#2074b6}.leaflet-control-locate.active.following a{color:#fc8428}.leaflet-control-locate-location circle{animation:leaflet-control-locate-throb 4s ease infinite}@keyframes leaflet-control-locate-throb{0%{stroke-width:1}50%{stroke-width:3;transform:scale(0.8, 0.8)}100%{stroke-width:1}} | |||
/*# sourceMappingURL=L.Control.Locate.min.css.map */ |
@@ -1,7 +0,0 @@ | |||
{ | |||
"version": 3, | |||
"mappings": "AAEE,yBAAE,CACA,SAAS,CAAE,KAAK,CAChB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,OAAO,CAGf,gCAAE,CACA,KAAK,CAAE,OAAO,CAEhB,0CAAc,CACZ,KAAK,CAAE,OAAO,CAKpB,uCAAwC,CACtC,SAAS,CAAE,6CAA6C,CAG1D,uCAWC,CAVC,EAAG,CACD,YAAY,CAAE,CAAC,CAEjB,GAAI,CACF,YAAY,CAAE,CAAC,CACf,SAAS,CAAE,eAAe,CAE5B,IAAK,CACH,YAAY,CAAE,CAAC", | |||
"sources": ["../src/L.Control.Locate.scss"], | |||
"names": [], | |||
"file": "L.Control.Locate.min.css" | |||
} |
@@ -1,35 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<title>Inkscape Output</title> | |||
</head> | |||
<body> | |||
<canvas id='canvas' width='26' height='26'></canvas> | |||
<script> | |||
var ctx = document.getElementById("canvas").getContext("2d"); | |||
// #path3763 | |||
ctx.beginPath(); | |||
ctx.lineWidth = 0.083333; | |||
ctx.moveTo(8.958330, 25.864580); | |||
ctx.lineTo(8.958330, 23.531250); | |||
ctx.lineTo(11.458330, 21.531250); | |||
ctx.lineTo(11.458330, 15.531250); | |||
ctx.lineTo(0.375000, 19.197920); | |||
ctx.lineTo(0.375000, 16.281250); | |||
ctx.lineTo(11.375000, 9.614580); | |||
ctx.lineTo(11.375000, 1.447920); | |||
ctx.bezierCurveTo(11.375000, -0.302080, 14.208330, -0.302080, 14.208330, 1.447920); | |||
ctx.lineTo(14.208330, 9.614580); | |||
ctx.lineTo(25.375000, 16.281250); | |||
ctx.lineTo(25.375000, 19.197920); | |||
ctx.lineTo(14.291670, 15.614580); | |||
ctx.lineTo(14.291670, 21.531250); | |||
ctx.lineTo(16.791670, 23.531250); | |||
ctx.lineTo(16.791670, 25.864580); | |||
ctx.lineTo(12.875000, 24.614580); | |||
</script> | |||
</body> | |||
</html> |
@@ -1,55 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="26" | |||
height="26" | |||
version="1.1" | |||
id="svg3765" | |||
sodipodi:docname="plane.svg" | |||
inkscape:version="0.92.1 r"> | |||
<metadata | |||
id="metadata3771"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<defs | |||
id="defs3769" /> | |||
<sodipodi:namedview | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1" | |||
objecttolerance="10" | |||
gridtolerance="10" | |||
guidetolerance="10" | |||
inkscape:pageopacity="0" | |||
inkscape:pageshadow="2" | |||
inkscape:window-width="1233" | |||
inkscape:window-height="794" | |||
id="namedview3767" | |||
showgrid="false" | |||
inkscape:zoom="4" | |||
inkscape:cx="98.625" | |||
inkscape:cy="52.5" | |||
inkscape:window-x="0" | |||
inkscape:window-y="23" | |||
inkscape:window-maximized="0" | |||
inkscape:current-layer="svg3765" /> | |||
<path | |||
d="m 8.95833,25.86458 v -2.33333 l 2.5,-2 v -6 L 0.375,19.19792 v -2.91667 l 11,-6.66667 V 1.44792 c 0,-1.75 2.83333,-1.75 2.83333,0 V 9.61458 L 25.375,16.28125 v 2.91667 L 14.29167,15.61458 v 5.91667 l 2.5,2 v 2.33333 l -3.91667,-1.25" | |||
id="path3763" | |||
inkscape:connector-curvature="0" | |||
style="stroke-width:0.08333334" /> | |||
</svg> |
@@ -1,2 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg enable-background="new 0 0 100 100" fill="#000000" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g transform="translate(.42394 -.056559)"><path d="m42.101 80.682h14.576c0.631-3.473 1.151-5.774 1.583-8.932h-17.351c0.466 4.799 0.963 7.384 1.192 8.932z"/><path d="m39.986 46.168h19.865c-0.148-5.253-0.632-9.784-1.326-13.681h-17.254c-0.724 4.398-1.119 9.051-1.285 13.681z"/><path d="m49.986 11.936c-3.882 3.222-5.494 7.411-7.202 13.56h14.113c-2.721-9.209-5.51-12.302-6.911-13.56z"/><path d="m40.406 65.757h18.576c0.48-4.54 0.76-8.737 0.864-12.597h-19.953c0.036 4.45 0.24 8.736 0.513 12.597z"/><path d="m70.242 35.35c-0.554-4.357-1.006-7.047-2.542-10.924-2.033-5.134-4.822-10.355-8.959-14.06-2.913-2.608-7.357-7.199-11.634-4.559-2.593 1.6-4.977 3.471-7.12 5.651-4.487 4.563-9.305 11.416-10.22 23.842-0.036 0.48-0.154 1.096 0.324 1.132 0.465 0.038 0.648-0.327 0.683-0.808 0.839-11.393 5.715-18.026 10.389-22.819-0.2 0.267-0.401 0.537-0.602 0.82-3.705 5.217-7.552 14.159-7.552 27.324 0 0.491 0.088 0.93 0.571 0.93 0.484 0 0.401-0.475 0.401-0.966 0-14.059 5.249-23.247 9.679-28.505-16.017 23.822-5.175 79.132-5.175 79.132h5.95c0.253 0.781 0.528 1.349 0.739 1.455 0.354 0.177 0.667 0.491 0.695 0.698s0.381 0.608 0.784 0.891c0.404 0.283 1.621 0.514 2.704 0.514s2.3-0.231 2.704-0.514 0.757-0.683 0.784-0.891c0.028-0.207 0.34-0.521 0.695-0.698 0.211-0.105 0.487-0.674 0.739-1.455h5.857c9.283-46.114 2.638-68.299-3.402-78.328 4.275 5.369 9.021 14.333 9.021 27.701 0 0.491-0.083 0.966 0.4 0.966 0.484 0 0.571-0.439 0.571-0.93 0-13.165-3.847-22.107-7.552-27.324-0.366-0.515-0.73-0.995-1.093-1.459 0.193 0.188 0.386 0.378 0.58 0.576 4.258 4.348 9.696 10.891 10.569 22.751 0.034 0.459 0.093 0.944 0.542 0.944 0.021 0 0.043-1e-3 0.065-3e-3 0.48-0.037 0.465-0.606 0.405-1.084zm-11.734 47.329h-18.263s-9.588-58.484 9.75-73.021c-1e-3 0 19.602 13.133 8.513 73.021z"/></g></svg> |
@@ -1,200 +0,0 @@ | |||
.sidebar { | |||
position: absolute; | |||
top: 0; | |||
bottom: 0; | |||
width: 100%; | |||
overflow: hidden; | |||
z-index: 2000; } | |||
.sidebar.collapsed { | |||
width: 40px; } | |||
@media (min-width: 768px) { | |||
.sidebar { | |||
top: 10px; | |||
bottom: 10px; | |||
transition: width 500ms; } } | |||
@media (min-width: 768px) and (max-width: 991px) { | |||
.sidebar { | |||
width: 305px; } } | |||
@media (min-width: 992px) and (max-width: 1199px) { | |||
.sidebar { | |||
width: 390px; } } | |||
@media (min-width: 1200px) { | |||
.sidebar { | |||
width: 460px; } } | |||
.sidebar-left { | |||
left: 0; } | |||
@media (min-width: 768px) { | |||
.sidebar-left { | |||
left: 10px; } } | |||
.sidebar-right { | |||
right: 0; } | |||
@media (min-width: 768px) { | |||
.sidebar-right { | |||
right: 10px; } } | |||
.sidebar-tabs { | |||
top: 0; | |||
bottom: 0; | |||
height: 100%; | |||
background-color: #fff; } | |||
.sidebar-left .sidebar-tabs { | |||
left: 0; } | |||
.sidebar-right .sidebar-tabs { | |||
right: 0; } | |||
.sidebar-tabs, .sidebar-tabs > ul { | |||
position: absolute; | |||
width: 40px; | |||
margin: 0; | |||
padding: 0; | |||
list-style-type: none; } | |||
.sidebar-tabs > li, .sidebar-tabs > ul > li { | |||
width: 100%; | |||
height: 40px; | |||
color: #333; | |||
font-size: 12pt; | |||
overflow: hidden; | |||
transition: all 80ms; } | |||
.sidebar-tabs > li:hover, .sidebar-tabs > ul > li:hover { | |||
color: #000; | |||
background-color: #eee; } | |||
.sidebar-tabs > li.active, .sidebar-tabs > ul > li.active { | |||
color: #fff; | |||
background-color: #0074d9; } | |||
.sidebar-tabs > li.disabled, .sidebar-tabs > ul > li.disabled { | |||
color: rgba(51, 51, 51, 0.4); } | |||
.sidebar-tabs > li.disabled:hover, .sidebar-tabs > ul > li.disabled:hover { | |||
background: transparent; } | |||
.sidebar-tabs > li.disabled > a, .sidebar-tabs > ul > li.disabled > a { | |||
cursor: default; } | |||
.sidebar-tabs > li > a, .sidebar-tabs > ul > li > a { | |||
display: block; | |||
width: 100%; | |||
height: 100%; | |||
line-height: 40px; | |||
color: inherit; | |||
text-decoration: none; | |||
text-align: center; } | |||
.sidebar-tabs > ul + ul { | |||
bottom: 0; } | |||
.sidebar-content { | |||
position: absolute; | |||
top: 0; | |||
bottom: 0; | |||
background-color: rgba(255, 255, 255, 0.95); | |||
overflow-x: hidden; | |||
overflow-y: auto; } | |||
.sidebar-left .sidebar-content { | |||
left: 40px; | |||
right: 0; } | |||
.sidebar-right .sidebar-content { | |||
left: 0; | |||
right: 40px; } | |||
.sidebar.collapsed > .sidebar-content { | |||
overflow-y: hidden; } | |||
.sidebar-pane { | |||
display: none; | |||
left: 0; | |||
right: 0; | |||
box-sizing: border-box; | |||
padding: 10px 20px; } | |||
.sidebar-pane.active { | |||
display: block; } | |||
@media (min-width: 768px) and (max-width: 991px) { | |||
.sidebar-pane { | |||
min-width: 265px; } } | |||
@media (min-width: 992px) and (max-width: 1199px) { | |||
.sidebar-pane { | |||
min-width: 350px; } } | |||
@media (min-width: 1200px) { | |||
.sidebar-pane { | |||
min-width: 420px; } } | |||
.sidebar-header { | |||
margin: -10px -20px 0; | |||
height: 40px; | |||
padding: 0 20px; | |||
line-height: 40px; | |||
font-size: 14.4pt; | |||
color: #fff; | |||
background-color: #0074d9; } | |||
.sidebar-right .sidebar-header { | |||
padding-left: 40px; } | |||
.sidebar-close { | |||
position: absolute; | |||
top: 0; | |||
width: 40px; | |||
height: 40px; | |||
text-align: center; | |||
cursor: pointer; } | |||
.sidebar-left .sidebar-close { | |||
right: 0; } | |||
.sidebar-right .sidebar-close { | |||
left: 0; } | |||
.sidebar-left ~ .sidebar-map { | |||
margin-left: 40px; } | |||
@media (min-width: 768px) { | |||
.sidebar-left ~ .sidebar-map { | |||
margin-left: 0; } } | |||
.sidebar-right ~ .sidebar-map { | |||
margin-right: 40px; } | |||
@media (min-width: 768px) { | |||
.sidebar-right ~ .sidebar-map { | |||
margin-right: 0; } } | |||
.sidebar { | |||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65); } | |||
.sidebar.leaflet-touch { | |||
box-shadow: none; | |||
border-right: 2px solid rgba(0, 0, 0, 0.2); } | |||
@media (min-width: 768px) { | |||
.sidebar { | |||
border-radius: 4px; } | |||
.sidebar.leaflet-touch { | |||
border: 2px solid rgba(0, 0, 0, 0.2); } } | |||
@media (min-width: 768px) { | |||
.sidebar-left ~ .sidebar-map .leaflet-left { | |||
transition: left 500ms; } } | |||
@media (min-width: 768px) and (max-width: 991px) { | |||
.sidebar-left ~ .sidebar-map .leaflet-left { | |||
left: 315px; } } | |||
@media (min-width: 992px) and (max-width: 1199px) { | |||
.sidebar-left ~ .sidebar-map .leaflet-left { | |||
left: 400px; } } | |||
@media (min-width: 1200px) { | |||
.sidebar-left ~ .sidebar-map .leaflet-left { | |||
left: 470px; } } | |||
@media (min-width: 768px) { | |||
.sidebar-left.collapsed ~ .sidebar-map .leaflet-left { | |||
left: 50px; } } | |||
@media (min-width: 768px) { | |||
.sidebar-right ~ .sidebar-map .leaflet-right { | |||
transition: right 500ms; } } | |||
@media (min-width: 768px) and (max-width: 991px) { | |||
.sidebar-right ~ .sidebar-map .leaflet-right { | |||
right: 315px; } } | |||
@media (min-width: 992px) and (max-width: 1199px) { | |||
.sidebar-right ~ .sidebar-map .leaflet-right { | |||
right: 400px; } } | |||
@media (min-width: 1200px) { | |||
.sidebar-right ~ .sidebar-map .leaflet-right { | |||
right: 470px; } } | |||
@media (min-width: 768px) { | |||
.sidebar-right.collapsed ~ .sidebar-map .leaflet-right { | |||
right: 50px; } } |
@@ -1 +0,0 @@ | |||
.sidebar{position:absolute;top:0;bottom:0;width:100%;overflow:hidden;z-index:2000;box-shadow:0 1px 5px rgba(0,0,0,.65)}.sidebar.collapsed{width:40px}@media (min-width:768px) and (max-width:991px){.sidebar{width:305px}.sidebar-pane{min-width:265px}}@media (min-width:992px) and (max-width:1199px){.sidebar{width:390px}}@media (min-width:1200px){.sidebar{width:460px}}.sidebar-left{left:0}.sidebar-right{right:0}@media (min-width:768px){.sidebar{top:10px;bottom:10px;transition:width .5s}.sidebar-left{left:10px}.sidebar-right{right:10px}}.sidebar-tabs{top:0;bottom:0;height:100%;background-color:#fff}.sidebar-left .sidebar-tabs{left:0}.sidebar-right .sidebar-tabs{right:0}.sidebar-tabs,.sidebar-tabs>ul{position:absolute;width:40px;margin:0;padding:0;list-style-type:none}.sidebar-tabs>li,.sidebar-tabs>ul>li{width:100%;height:40px;color:#333;font-size:12pt;overflow:hidden;transition:all 80ms}.sidebar-tabs>li:hover,.sidebar-tabs>ul>li:hover{color:#000;background-color:#eee}.sidebar-tabs>li.active,.sidebar-tabs>ul>li.active{color:#fff;background-color:#0074d9}.sidebar-tabs>li.disabled,.sidebar-tabs>ul>li.disabled{color:rgba(51,51,51,.4)}.sidebar-tabs>li.disabled:hover,.sidebar-tabs>ul>li.disabled:hover{background:0 0}.sidebar-tabs>li.disabled>a,.sidebar-tabs>ul>li.disabled>a{cursor:default}.sidebar-tabs>li>a,.sidebar-tabs>ul>li>a{display:block;width:100%;height:100%;line-height:40px;color:inherit;text-decoration:none;text-align:center}.sidebar-tabs>ul+ul{bottom:0}.sidebar-content{position:absolute;top:0;bottom:0;background-color:rgba(255,255,255,.95);overflow-x:hidden;overflow-y:auto}.sidebar-left .sidebar-content{left:40px;right:0}.sidebar-right .sidebar-content{left:0;right:40px}.sidebar.collapsed>.sidebar-content{overflow-y:hidden}.sidebar-pane{display:none;left:0;right:0;box-sizing:border-box;padding:10px 20px}.sidebar-pane.active{display:block}.sidebar-header{margin:-10px -20px 0;height:40px;padding:0 20px;line-height:40px;font-size:14.4pt;color:#fff;background-color:#0074d9}.sidebar-right .sidebar-header{padding-left:40px}.sidebar-close{position:absolute;top:0;width:40px;height:40px;text-align:center;cursor:pointer}.sidebar-left .sidebar-close{right:0}.sidebar-right .sidebar-close{left:0}.sidebar-left~.sidebar-map{margin-left:40px}.sidebar-right~.sidebar-map{margin-right:40px}.sidebar.leaflet-touch{box-shadow:none;border-right:2px solid rgba(0,0,0,.2)}@media (min-width:768px) and (max-width:991px){.sidebar-left~.sidebar-map .leaflet-left{left:315px}.sidebar-right~.sidebar-map .leaflet-right{right:315px}}@media (min-width:992px) and (max-width:1199px){.sidebar-pane{min-width:350px}.sidebar-left~.sidebar-map .leaflet-left{left:400px}.sidebar-right~.sidebar-map .leaflet-right{right:400px}}@media (min-width:1200px){.sidebar-pane{min-width:420px}.sidebar-left~.sidebar-map .leaflet-left{left:470px}.sidebar-right~.sidebar-map .leaflet-right{right:470px}}@media (min-width:768px){.sidebar-left~.sidebar-map{margin-left:0}.sidebar-right~.sidebar-map{margin-right:0}.sidebar{border-radius:4px}.sidebar.leaflet-touch{border:2px solid rgba(0,0,0,.2)}.sidebar-left~.sidebar-map .leaflet-left{transition:left .5s}.sidebar-left.collapsed~.sidebar-map .leaflet-left{left:50px}.sidebar-right~.sidebar-map .leaflet-right{transition:right .5s}.sidebar-right.collapsed~.sidebar-map .leaflet-right{right:50px}} |
@@ -1,640 +0,0 @@ | |||
/* required styles */ | |||
.leaflet-pane, | |||
.leaflet-tile, | |||
.leaflet-marker-icon, | |||
.leaflet-marker-shadow, | |||
.leaflet-tile-container, | |||
.leaflet-pane > svg, | |||
.leaflet-pane > canvas, | |||
.leaflet-zoom-box, | |||
.leaflet-image-layer, | |||
.leaflet-layer { | |||
position: absolute; | |||
left: 0; | |||
top: 0; | |||
} | |||
.leaflet-container { | |||
overflow: hidden; | |||
} | |||
.leaflet-tile, | |||
.leaflet-marker-icon, | |||
.leaflet-marker-shadow { | |||
-webkit-user-select: none; | |||
-moz-user-select: none; | |||
user-select: none; | |||
-webkit-user-drag: none; | |||
} | |||
/* Prevents IE11 from highlighting tiles in blue */ | |||
.leaflet-tile::selection { | |||
background: transparent; | |||
} | |||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ | |||
.leaflet-safari .leaflet-tile { | |||
image-rendering: -webkit-optimize-contrast; | |||
} | |||
/* hack that prevents hw layers "stretching" when loading new tiles */ | |||
.leaflet-safari .leaflet-tile-container { | |||
width: 1600px; | |||
height: 1600px; | |||
-webkit-transform-origin: 0 0; | |||
} | |||
.leaflet-marker-icon, | |||
.leaflet-marker-shadow { | |||
display: block; | |||
} | |||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ | |||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ | |||
.leaflet-container .leaflet-overlay-pane svg, | |||
.leaflet-container .leaflet-marker-pane img, | |||
.leaflet-container .leaflet-shadow-pane img, | |||
.leaflet-container .leaflet-tile-pane img, | |||
.leaflet-container img.leaflet-image-layer, | |||
.leaflet-container .leaflet-tile { | |||
max-width: none !important; | |||
max-height: none !important; | |||
} | |||
.leaflet-container.leaflet-touch-zoom { | |||
-ms-touch-action: pan-x pan-y; | |||
touch-action: pan-x pan-y; | |||
} | |||
.leaflet-container.leaflet-touch-drag { | |||
-ms-touch-action: pinch-zoom; | |||
/* Fallback for FF which doesn't support pinch-zoom */ | |||
touch-action: none; | |||
touch-action: pinch-zoom; | |||
} | |||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { | |||
-ms-touch-action: none; | |||
touch-action: none; | |||
} | |||
.leaflet-container { | |||
-webkit-tap-highlight-color: transparent; | |||
} | |||
.leaflet-container a { | |||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); | |||
} | |||
.leaflet-tile { | |||
filter: inherit; | |||
visibility: hidden; | |||
} | |||
.leaflet-tile-loaded { | |||
visibility: inherit; | |||
} | |||
.leaflet-zoom-box { | |||
width: 0; | |||
height: 0; | |||
-moz-box-sizing: border-box; | |||
box-sizing: border-box; | |||
z-index: 800; | |||
} | |||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ | |||
.leaflet-overlay-pane svg { | |||
-moz-user-select: none; | |||
} | |||
.leaflet-pane { z-index: 400; } | |||
.leaflet-tile-pane { z-index: 200; } | |||
.leaflet-overlay-pane { z-index: 400; } | |||
.leaflet-shadow-pane { z-index: 500; } | |||
.leaflet-marker-pane { z-index: 600; } | |||
.leaflet-tooltip-pane { z-index: 650; } | |||
.leaflet-popup-pane { z-index: 700; } | |||
.leaflet-map-pane canvas { z-index: 100; } | |||
.leaflet-map-pane svg { z-index: 200; } | |||
.leaflet-vml-shape { | |||
width: 1px; | |||
height: 1px; | |||
} | |||
.lvml { | |||
behavior: url(#default#VML); | |||
display: inline-block; | |||
position: absolute; | |||
} | |||
/* control positioning */ | |||
.leaflet-control { | |||
position: relative; | |||
z-index: 800; | |||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ | |||
pointer-events: auto; | |||
} | |||
.leaflet-top, | |||
.leaflet-bottom { | |||
position: absolute; | |||
z-index: 1000; | |||
pointer-events: none; | |||
} | |||
.leaflet-top { | |||
top: 0; | |||
} | |||
.leaflet-right { | |||
right: 0; | |||
} | |||
.leaflet-bottom { | |||
bottom: 0; | |||
} | |||
.leaflet-left { | |||
left: 0; | |||
} | |||
.leaflet-control { | |||
float: left; | |||
clear: both; | |||
} | |||
.leaflet-right .leaflet-control { | |||
float: right; | |||
} | |||
.leaflet-top .leaflet-control { | |||
margin-top: 10px; | |||
} | |||
.leaflet-bottom .leaflet-control { | |||
margin-bottom: 10px; | |||
} | |||
.leaflet-left .leaflet-control { | |||
margin-left: 10px; | |||
} | |||
.leaflet-right .leaflet-control { | |||
margin-right: 10px; | |||
} | |||
/* zoom and fade animations */ | |||
.leaflet-fade-anim .leaflet-tile { | |||
will-change: opacity; | |||
} | |||
.leaflet-fade-anim .leaflet-popup { | |||
opacity: 0; | |||
-webkit-transition: opacity 0.2s linear; | |||
-moz-transition: opacity 0.2s linear; | |||
transition: opacity 0.2s linear; | |||
} | |||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { | |||
opacity: 1; | |||
} | |||
.leaflet-zoom-animated { | |||
-webkit-transform-origin: 0 0; | |||
-ms-transform-origin: 0 0; | |||
transform-origin: 0 0; | |||
} | |||
.leaflet-zoom-anim .leaflet-zoom-animated { | |||
will-change: transform; | |||
} | |||
.leaflet-zoom-anim .leaflet-zoom-animated { | |||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); | |||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); | |||
transition: transform 0.25s cubic-bezier(0,0,0.25,1); | |||
} | |||
.leaflet-zoom-anim .leaflet-tile, | |||
.leaflet-pan-anim .leaflet-tile { | |||
-webkit-transition: none; | |||
-moz-transition: none; | |||
transition: none; | |||
} | |||
.leaflet-zoom-anim .leaflet-zoom-hide { | |||
visibility: hidden; | |||
} | |||
/* cursors */ | |||
.leaflet-interactive { | |||
cursor: pointer; | |||
} | |||
.leaflet-grab { | |||
cursor: -webkit-grab; | |||
cursor: -moz-grab; | |||
cursor: grab; | |||
} | |||
.leaflet-crosshair, | |||
.leaflet-crosshair .leaflet-interactive { | |||
cursor: crosshair; | |||
} | |||
.leaflet-popup-pane, | |||
.leaflet-control { | |||
cursor: auto; | |||
} | |||
.leaflet-dragging .leaflet-grab, | |||
.leaflet-dragging .leaflet-grab .leaflet-interactive, | |||
.leaflet-dragging .leaflet-marker-draggable { | |||
cursor: move; | |||
cursor: -webkit-grabbing; | |||
cursor: -moz-grabbing; | |||
cursor: grabbing; | |||
} | |||
/* marker & overlays interactivity */ | |||
.leaflet-marker-icon, | |||
.leaflet-marker-shadow, | |||
.leaflet-image-layer, | |||
.leaflet-pane > svg path, | |||
.leaflet-tile-container { | |||
pointer-events: none; | |||
} | |||
.leaflet-marker-icon.leaflet-interactive, | |||
.leaflet-image-layer.leaflet-interactive, | |||
.leaflet-pane > svg path.leaflet-interactive, | |||
svg.leaflet-image-layer.leaflet-interactive path { | |||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ | |||
pointer-events: auto; | |||
} | |||
/* visual tweaks */ | |||
.leaflet-container { | |||
background: #ddd; | |||
outline: 0; | |||
} | |||
.leaflet-container a { | |||
color: #0078A8; | |||
} | |||
.leaflet-container a.leaflet-active { | |||
outline: 2px solid orange; | |||
} | |||
.leaflet-zoom-box { | |||
border: 2px dotted #38f; | |||
background: rgba(255,255,255,0.5); | |||
} | |||
/* general typography */ | |||
.leaflet-container { | |||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; | |||
} | |||
/* general toolbar styles */ | |||
.leaflet-bar { | |||
box-shadow: 0 1px 5px rgba(0,0,0,0.65); | |||
border-radius: 4px; | |||
} | |||
.leaflet-bar a, | |||
.leaflet-bar a:hover { | |||
background-color: #fff; | |||
border-bottom: 1px solid #ccc; | |||
width: 26px; | |||
height: 26px; | |||
line-height: 26px; | |||
display: block; | |||
text-align: center; | |||
text-decoration: none; | |||
color: black; | |||
} | |||
.leaflet-bar a, | |||
.leaflet-control-layers-toggle { | |||
background-position: 50% 50%; | |||
background-repeat: no-repeat; | |||
display: block; | |||
} | |||
.leaflet-bar a:hover { | |||
background-color: #f4f4f4; | |||
} | |||
.leaflet-bar a:first-child { | |||
border-top-left-radius: 4px; | |||
border-top-right-radius: 4px; | |||
} | |||
.leaflet-bar a:last-child { | |||
border-bottom-left-radius: 4px; | |||
border-bottom-right-radius: 4px; | |||
border-bottom: none; | |||
} | |||
.leaflet-bar a.leaflet-disabled { | |||
cursor: default; | |||
background-color: #f4f4f4; | |||
color: #bbb; | |||
} | |||
.leaflet-touch .leaflet-bar a { | |||
width: 30px; | |||
height: 30px; | |||
line-height: 30px; | |||
} | |||
.leaflet-touch .leaflet-bar a:first-child { | |||
border-top-left-radius: 2px; | |||
border-top-right-radius: 2px; | |||
} | |||
.leaflet-touch .leaflet-bar a:last-child { | |||
border-bottom-left-radius: 2px; | |||
border-bottom-right-radius: 2px; | |||
} | |||
/* zoom control */ | |||
.leaflet-control-zoom-in, | |||
.leaflet-control-zoom-out { | |||
font: bold 18px 'Lucida Console', Monaco, monospace; | |||
text-indent: 1px; | |||
} | |||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { | |||
font-size: 22px; | |||
} | |||
/* layers control */ | |||
.leaflet-control-layers { | |||
box-shadow: 0 1px 5px rgba(0,0,0,0.4); | |||
background: #fff; | |||
border-radius: 5px; | |||
} | |||
.leaflet-control-layers-toggle { | |||
background-image: url(images/layers.png); | |||
width: 36px; | |||
height: 36px; | |||
} | |||
.leaflet-retina .leaflet-control-layers-toggle { | |||
background-image: url(images/layers-2x.png); | |||
background-size: 26px 26px; | |||
} | |||
.leaflet-touch .leaflet-control-layers-toggle { | |||
width: 44px; | |||
height: 44px; | |||
} | |||
.leaflet-control-layers .leaflet-control-layers-list, | |||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle { | |||
display: none; | |||
} | |||
.leaflet-control-layers-expanded .leaflet-control-layers-list { | |||
display: block; | |||
position: relative; | |||
} | |||
.leaflet-control-layers-expanded { | |||
padding: 6px 10px 6px 6px; | |||
color: #333; | |||
background: #fff; | |||
} | |||
.leaflet-control-layers-scrollbar { | |||
overflow-y: scroll; | |||
overflow-x: hidden; | |||
padding-right: 5px; | |||
} | |||
.leaflet-control-layers-selector { | |||
margin-top: 2px; | |||
position: relative; | |||
top: 1px; | |||
} | |||
.leaflet-control-layers label { | |||
display: block; | |||
} | |||
.leaflet-control-layers-separator { | |||
height: 0; | |||
border-top: 1px solid #ddd; | |||
margin: 5px -10px 5px -6px; | |||
} | |||
/* Default icon URLs */ | |||
.leaflet-default-icon-path { | |||
background-image: url(images/marker-icon.png); | |||
} | |||
/* attribution and scale controls */ | |||
.leaflet-container .leaflet-control-attribution { | |||
background: #fff; | |||
background: rgba(255, 255, 255, 0.7); | |||
margin: 0; | |||
} | |||
.leaflet-control-attribution, | |||
.leaflet-control-scale-line { | |||
padding: 0 5px; | |||
color: #333; | |||
} | |||
.leaflet-control-attribution a { | |||
text-decoration: none; | |||
} | |||
.leaflet-control-attribution a:hover { | |||
text-decoration: underline; | |||
} | |||
.leaflet-container .leaflet-control-attribution, | |||
.leaflet-container .leaflet-control-scale { | |||
font-size: 11px; | |||
} | |||
.leaflet-left .leaflet-control-scale { | |||
margin-left: 5px; | |||
} | |||
.leaflet-bottom .leaflet-control-scale { | |||
margin-bottom: 5px; | |||
} | |||
.leaflet-control-scale-line { | |||
border: 2px solid #777; | |||
border-top: none; | |||
line-height: 1.1; | |||
padding: 2px 5px 1px; | |||
font-size: 11px; | |||
white-space: nowrap; | |||
overflow: hidden; | |||
-moz-box-sizing: border-box; | |||
box-sizing: border-box; | |||
background: #fff; | |||
background: rgba(255, 255, 255, 0.5); | |||
} | |||
.leaflet-control-scale-line:not(:first-child) { | |||
border-top: 2px solid #777; | |||
border-bottom: none; | |||
margin-top: -2px; | |||
} | |||
.leaflet-control-scale-line:not(:first-child):not(:last-child) { | |||
border-bottom: 2px solid #777; | |||
} | |||
.leaflet-touch .leaflet-control-attribution, | |||
.leaflet-touch .leaflet-control-layers, | |||
.leaflet-touch .leaflet-bar { | |||
box-shadow: none; | |||
} | |||
.leaflet-touch .leaflet-control-layers, | |||
.leaflet-touch .leaflet-bar { | |||
border: 2px solid rgba(0,0,0,0.2); | |||
background-clip: padding-box; | |||
} | |||
/* popup */ | |||
.leaflet-popup { | |||
position: absolute; | |||
text-align: center; | |||
margin-bottom: 20px; | |||
} | |||
.leaflet-popup-content-wrapper { | |||
padding: 1px; | |||
text-align: left; | |||
border-radius: 12px; | |||
} | |||
.leaflet-popup-content { | |||
margin: 13px 19px; | |||
line-height: 1.4; | |||
} | |||
.leaflet-popup-content p { | |||
margin: 18px 0; | |||
} | |||
.leaflet-popup-tip-container { | |||
width: 40px; | |||
height: 20px; | |||
position: absolute; | |||
left: 50%; | |||
margin-left: -20px; | |||
overflow: hidden; | |||
pointer-events: none; | |||
} | |||
.leaflet-popup-tip { | |||
width: 17px; | |||
height: 17px; | |||
padding: 1px; | |||
margin: -10px auto 0; | |||
-webkit-transform: rotate(45deg); | |||
-moz-transform: rotate(45deg); | |||
-ms-transform: rotate(45deg); | |||
transform: rotate(45deg); | |||
} | |||
.leaflet-popup-content-wrapper, | |||
.leaflet-popup-tip { | |||
background: white; | |||
color: #333; | |||
box-shadow: 0 3px 14px rgba(0,0,0,0.4); | |||
} | |||
.leaflet-container a.leaflet-popup-close-button { | |||
position: absolute; | |||
top: 0; | |||
right: 0; | |||
padding: 4px 4px 0 0; | |||
border: none; | |||
text-align: center; | |||
width: 18px; | |||
height: 14px; | |||
font: 16px/14px Tahoma, Verdana, sans-serif; | |||
color: #c3c3c3; | |||
text-decoration: none; | |||
font-weight: bold; | |||
background: transparent; | |||
} | |||
.leaflet-container a.leaflet-popup-close-button:hover { | |||
color: #999; | |||
} | |||
.leaflet-popup-scrolled { | |||
overflow: auto; | |||
border-bottom: 1px solid #ddd; | |||
border-top: 1px solid #ddd; | |||
} | |||
.leaflet-oldie .leaflet-popup-content-wrapper { | |||
zoom: 1; | |||
} | |||
.leaflet-oldie .leaflet-popup-tip { | |||
width: 24px; | |||
margin: 0 auto; | |||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; | |||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); | |||
} | |||
.leaflet-oldie .leaflet-popup-tip-container { | |||
margin-top: -1px; | |||
} | |||
.leaflet-oldie .leaflet-control-zoom, | |||
.leaflet-oldie .leaflet-control-layers, | |||
.leaflet-oldie .leaflet-popup-content-wrapper, | |||
.leaflet-oldie .leaflet-popup-tip { | |||
border: 1px solid #999; | |||
} | |||
/* div icon */ | |||
.leaflet-div-icon { | |||
background: #fff; | |||
border: 1px solid #666; | |||
} | |||
/* Tooltip */ | |||
/* Base styles for the element that has a tooltip */ | |||
.leaflet-tooltip { | |||
position: absolute; | |||
padding: 6px; | |||
background-color: #fff; | |||
border: 1px solid #fff; | |||
border-radius: 3px; | |||
color: #222; | |||
white-space: nowrap; | |||
-webkit-user-select: none; | |||
-moz-user-select: none; | |||
-ms-user-select: none; | |||
user-select: none; | |||
pointer-events: none; | |||
box-shadow: 0 1px 3px rgba(0,0,0,0.4); | |||
} | |||
.leaflet-tooltip.leaflet-clickable { | |||
cursor: pointer; | |||
pointer-events: auto; | |||
} | |||
.leaflet-tooltip-top:before, | |||
.leaflet-tooltip-bottom:before, | |||
.leaflet-tooltip-left:before, | |||
.leaflet-tooltip-right:before { | |||
position: absolute; | |||
pointer-events: none; | |||
border: 6px solid transparent; | |||
background: transparent; | |||
content: ""; | |||
} | |||
/* Directions */ | |||
.leaflet-tooltip-bottom { | |||
margin-top: 6px; | |||
} | |||
.leaflet-tooltip-top { | |||
margin-top: -6px; | |||
} | |||
.leaflet-tooltip-bottom:before, | |||
.leaflet-tooltip-top:before { | |||
left: 50%; | |||
margin-left: -6px; | |||
} | |||
.leaflet-tooltip-top:before { | |||
bottom: 0; | |||
margin-bottom: -12px; | |||
border-top-color: #fff; | |||
} | |||
.leaflet-tooltip-bottom:before { | |||
top: 0; | |||
margin-top: -12px; | |||
margin-left: -6px; | |||
border-bottom-color: #fff; | |||
} | |||
.leaflet-tooltip-left { | |||
margin-left: -6px; | |||
} | |||
.leaflet-tooltip-right { | |||
margin-left: 6px; | |||
} | |||
.leaflet-tooltip-left:before, | |||
.leaflet-tooltip-right:before { | |||
top: 50%; | |||
margin-top: -6px; | |||
} | |||
.leaflet-tooltip-left:before { | |||
right: 0; | |||
margin-right: -12px; | |||
border-left-color: #fff; | |||
} | |||
.leaflet-tooltip-right:before { | |||
left: 0; | |||
margin-left: -12px; | |||
border-right-color: #fff; | |||
} |
@@ -1,66 +0,0 @@ | |||
* { | |||
/*font-size: 0.9rem; | |||
font-family: Helvetica, | |||
Arial, | |||
"Lucida Grande", | |||
sans-serif;*/ | |||
} | |||
.msgBx { | |||
font-size: 0.5rem; | |||
font-family: monospace; | |||
width: 100%; | |||
border: 1px solid #000000; | |||
background-color: #cccccc; | |||
position: absolute; | |||
bottom: 0; | |||
left: 0; | |||
right: 0; | |||
opacity: 0.85; | |||
} | |||
.dbgInactive { | |||
display: none; | |||
} | |||
.dbgActive { | |||
z-index: 9999; | |||
} | |||
div.content { | |||
padding-top: 3rem; | |||
height: 100%; | |||
} | |||
div.content .noMap { | |||
padding-top: 1rem; | |||
} | |||
html, body { | |||
height: 100%; | |||
} | |||
#map { | |||
height: 100%; | |||
} | |||
#mapStyleBox { | |||
text-align: left; | |||
font-family: Roboto, Arial, sans-serif; | |||
position: absolute; | |||
top: 5px !important; | |||
left: 35px !important; | |||
} | |||
.mapStyleSelector { | |||
font-size: 12px; | |||
z-index: 9999; | |||
} | |||
span.icon-socket-ok { | |||
color: green; | |||
} | |||
span.icon-socket-nok { | |||
color: red; | |||
} |
@@ -1,98 +0,0 @@ | |||
/*********************************************************** | |||
* Airsuck User Interface Sidebar CSS | |||
* v. 0.1 | |||
* | |||
* Sidebar styling for airsuck UI-Sidebar | |||
* | |||
* Licensed under GPL V3 | |||
* https://github.com/ThreeSixes/airSuck | |||
* | |||
**********************************************************/ | |||
.sidebar { | |||
top: 3.7rem !important; | |||
bottom: 1.8rem !important; | |||
} | |||
.sidebar-header { | |||
margin-bottom: 10px !important; | |||
} | |||
#sidebar #aircrafts, #sidebar #ships { | |||
font-size: 9px !important; | |||
font-family: Helvetica, Arial, "Lucida Grande", sans-serif; | |||
} | |||
#aircrafts.sidebar-pane .sidebar-header, #ships.sidebar-pane .sidebar-header { | |||
margin-bottom: 0 !important; | |||
} | |||
.sidebar-tabs .locateMe { | |||
margin-top: 3em; | |||
padding-left: 3px; | |||
} | |||
#LocateMe .leaflet-control-locate { | |||
left: 10.5px; | |||
} | |||
/* Vehicle List Container */ | |||
.vehicle-table { | |||
width: 100%; | |||
max-height: 300px; | |||
overflow: auto; | |||
border-collapse: collapse; | |||
} | |||
.vehicle-table tbody { | |||
} | |||
.vehicle-table th { | |||
height: 30px; | |||
} | |||
.vehicle-table td { | |||
padding: 5px; | |||
} | |||
.vehicle-table-entry { | |||
border-top: 1px solid #e6e6e6; | |||
} | |||
tr.vehicle-table-entry:hover { | |||
background-color: #f2f2f2 | |||
} | |||
tr.vehicle-table-entry { | |||
cursor: pointer; | |||
} | |||
tr.vehicle-table-entry td { | |||
text-overflow: ellipsis; | |||
} | |||
.vehicle-table-detail { | |||
display: none; | |||
} | |||
.infoTable { | |||
border: 0; | |||
} | |||
.tblHeader { | |||
font-weight: bold; | |||
border: 0; | |||
} | |||
.tblCell { | |||
border: 0; | |||
} | |||
.tblEmerg { | |||
font-weight: bold; | |||
border: 0; | |||
background-color: #ffff00; | |||
color: #ff0000; | |||
} |
@@ -1,148 +0,0 @@ | |||
(function (global, factory) { | |||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('leaflet')) : | |||
typeof define === 'function' && define.amd ? define(['leaflet'], factory) : | |||
(global.L = global.L || {}, global.L.terminator = factory(global.L)); | |||
}(this, (function (L) { 'use strict'; | |||
L = L && L.hasOwnProperty('default') ? L['default'] : L; | |||
/* Terminator.js -- Overlay day/night region on a Leaflet map */ | |||
function julian(date) { | |||
/* Calculate the present UTC Julian Date. Function is valid after | |||
* the beginning of the UNIX epoch 1970-01-01 and ignores leap | |||
* seconds. */ | |||
return (date / 86400000) + 2440587.5; | |||
} | |||
function GMST(julianDay) { | |||
/* Calculate Greenwich Mean Sidereal Time according to | |||
http://aa.usno.navy.mil/faq/docs/GAST.php */ | |||
var d = julianDay - 2451545.0; | |||
// Low precision equation is good enough for our purposes. | |||
return (18.697374558 + 24.06570982441908 * d) % 24; | |||
} | |||
var Terminator = L.Polygon.extend({ | |||
options: { | |||
color: '#00', | |||
opacity: 0.5, | |||
fillColor: '#00', | |||
fillOpacity: 0.5, | |||
resolution: 2 | |||
}, | |||
initialize: function (options) { | |||
this.version = '0.1.0'; | |||
this._R2D = 180 / Math.PI; | |||
this._D2R = Math.PI / 180; | |||
L.Util.setOptions(this, options); | |||
var latLng = this._compute(this.options.time); | |||
this.setLatLngs(latLng); | |||
}, | |||
setTime: function (date) { | |||
this.options.time = date; | |||
var latLng = this._compute(date); | |||
this.setLatLngs(latLng); | |||
}, | |||
_sunEclipticPosition: function (julianDay) { | |||
/* Compute the position of the Sun in ecliptic coordinates at | |||
julianDay. Following | |||
http://en.wikipedia.org/wiki/Position_of_the_Sun */ | |||
// Days since start of J2000.0 | |||
var n = julianDay - 2451545.0; | |||
// mean longitude of the Sun | |||
var L$$1 = 280.460 + 0.9856474 * n; | |||
L$$1 %= 360; | |||
// mean anomaly of the Sun | |||
var g = 357.528 + 0.9856003 * n; | |||
g %= 360; | |||
// ecliptic longitude of Sun | |||
var lambda = L$$1 + 1.915 * Math.sin(g * this._D2R) + | |||
0.02 * Math.sin(2 * g * this._D2R); | |||
// distance from Sun in AU | |||
var R = 1.00014 - 0.01671 * Math.cos(g * this._D2R) - | |||
0.0014 * Math.cos(2 * g * this._D2R); | |||
return {lambda: lambda, R: R}; | |||
}, | |||
_eclipticObliquity: function (julianDay) { | |||
// Following the short term expression in | |||
// http://en.wikipedia.org/wiki/Axial_tilt#Obliquity_of_the_ecliptic_.28Earth.27s_axial_tilt.29 | |||
var n = julianDay - 2451545.0; | |||
// Julian centuries since J2000.0 | |||
var T = n / 36525; | |||
var epsilon = 23.43929111 - | |||
T * (46.836769 / 3600 | |||
- T * (0.0001831 / 3600 | |||
+ T * (0.00200340 / 3600 | |||
- T * (0.576e-6 / 3600 | |||