Skip to content

Commit

Permalink
Re-structured the observation data, and integrated parsing system to …
Browse files Browse the repository at this point in the history
…populate them automatically from the raw METAR data.

git-svn-id: http://django-weathertracking.googlecode.com/svn/trunk@4 696a86c2-f982-11dd-8259-6defae454439
  • Loading branch information
adamfast committed Feb 17, 2009
1 parent 1de1b0d commit 77328c5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
2 changes: 1 addition & 1 deletion weathertracking/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class WeatherStationAdmin(admin.ModelAdmin):

class WeatherReportAdmin(admin.ModelAdmin):
list_display = ('station', 'observation_time', 'temperature_celsius',
'wind_speed_kts', 'wind_direction', 'visibility_mi', 'cycle', 'sky_conditions')
'wind_speed_kts', 'wind_direction', 'visibility_mi', 'observation_cycle', 'sky_conditions')
list_filter = ('station',)
date_hierarchy = 'observation_time'

Expand Down
1 change: 1 addition & 0 deletions weathertracking/documentation/INSTALL.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Dependencies:
GeoDjango and its dependencies (http://geodjango.org/docs/install.html)
A suitable spatial database that supports distance lookup (http://geodjango.org/docs/db-api.html#id38) - right now that means only PostgreSQL / PostGIS and Oracle
Metar - from http://homepage.mac.com/wtpollard/Software/FileSharing4.html

Notes:
You can without too much pain an suffering comment out the bits that require GeoDjango, but I personally will always be using those bits so my "official" distribution will include them.
Expand Down
61 changes: 46 additions & 15 deletions weathertracking/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.gis.db import models
from metar.Metar import Metar # available from http://homepage.mac.com/wtpollard/Software/FileSharing4.html

class WeatherStationManager(models.GeoManager):
def auto_poll(self):
Expand Down Expand Up @@ -38,26 +39,56 @@ def all(self, limit=None):
class WeatherReport(models.Model):
station = models.ForeignKey(WeatherStation)
raw = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
timestamp = models.DateTimeField(auto_now_add=True) # keep track of when it was retrieved - necessary because METARs don't include any month/year info

# denormalized data - obtainable by parsing the raw info, but stored for convenience of lookup
observation_type = models.CharField(max_length=5, null=True, blank=True) # METAR or SPECI
observation_mode = models.CharField(max_length=4, null=True, blank=True) # AUTO or COR (corrected)
observation_cycle = models.IntegerField(null=True, blank=True) # a number between 0 and 23
observation_time = models.DateTimeField(null=True, blank=True)
temperature_celsius = models.DecimalField(max_digits=5, decimal_places=2)
temperature_fahrenheit = models.DecimalField(max_digits=5, decimal_places=2)
dewpoint_celsius = models.DecimalField(max_digits=5, decimal_places=2)
dewpoint_fahrenheit = models.DecimalField(max_digits=5, decimal_places=2)
wind_speed_kts = models.IntegerField()
wind_speed_meters_per_second = models.DecimalField(max_digits=10, decimal_places=7)
wind_speed_miles_per_hour = models.DecimalField(max_digits=10, decimal_places=7)
wind_direction = models.IntegerField(null=True, blank=True)
wind_compass = models.CharField(max_length=4, null=True, blank=True)
visibility_km = models.DecimalField(max_digits=10, decimal_places=7)
visibility_mi = models.DecimalField(max_digits=10, decimal_places=7)
humidity_percent = models.IntegerField()
barometric_pressure_mb = models.DecimalField(max_digits=14, decimal_places=10)
altimeter = models.DecimalField(max_digits=4, decimal_places=2)
cycle = models.IntegerField(null=True, blank=True)
sky_conditions = models.CharField(max_length=256)
wind_direction_from = models.IntegerField(null=True, blank=True) # used when the wind direction is variable and specified
wind_direction_to = models.IntegerField(null=True, blank=True) # ^^^
wind_speed_kts = models.IntegerField(null=True, blank=True)
wind_speed_gust_kts = models.IntegerField(null=True, blank=True)
visibility_mi = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True)
temperature_celsius = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
temperature_fahrenheit = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
dewpoint_celsius = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
dewpoint_fahrenheit = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
sky_conditions = models.TextField(null=True, blank=True)

objects = WeatherReportManager()

def get_metar_object(self):
return Metar(self.raw)

def save(self, **kwargs):
"Populate all the denormalized data fields by using the metar class before saving."
metar = self.get_metar_object()

self.observation_time = metar.time
self.observation_cycle = metar.cycle
self.observation_type = metar.type
self.observation_mode = metar.mod
self.temperature_celsius = '%s' % metar.temp.value(units='c')
self.temperature_fahrenheit = '%s' % metar.temp.value(units='f')
self.dewpoint_celsius = '%s' % metar.dewpt.value(units='c')
self.dewpoint_fahrenheit = '%s' % metar.dewpt.value(units='f')
self.visibility_mi = '%s' % metar.vis.value(units='MI')
self.wind_direction = '%s' % int(metar.wind_dir.value())
self.wind_compass = metar.wind_dir.compass()
if metar.wind_dir_from:
self.wind_direction_from = '%s' % int(metar.wind_dir_from.value())
if metar.wind_dir_to:
self.wind_direction_to = '%s' % int(metar.wind_dir_to.value())
self.wind_speed_kts = '%s' % int(metar.wind_speed.value()) # metars will only return integers when using kts
if metar.wind_gust:
self.wind_speed_gust_kts = '%s' % int(metar.wind_gust.value())
self.sky_conditions = '%s' % metar.sky_conditions()

super(WeatherReport, self).save(**kwargs)

def __unicode__(self):
return u'%s' % self.raw

0 comments on commit 77328c5

Please sign in to comment.