from django.contrib.gis.db import models


# EPSG Codes database below
# Imported via psql from http://www.epsg.org/databases/Discv6_17sql-PosgreSql.html

class EpsgSupersession(models.Model):
    supersession_id = models.IntegerField(primary_key=True)
    object_table_name = models.CharField(max_length=80)
    object_code = models.IntegerField()
    superseded_by = models.IntegerField()
    supersession_type = models.CharField(max_length=50)
    supersession_year = models.SmallIntegerField()
    remarks = models.CharField(max_length=254)
    class Meta:
        db_table = 'epsg_supersession'
    def __unicode__(self):
        return "EPSG Supersession:  %s" % (self.supersession_id)

class EpsgVersionhistory(models.Model):
    version_history_code = models.IntegerField(primary_key=True)
    version_date = models.DateField()
    version_number = models.CharField(unique=True, max_length=10)
    version_remarks = models.CharField(max_length=254)
    superceded_by = models.CharField(max_length=10)
    supercedes = models.CharField(max_length=10)
    class Meta:
        db_table = 'epsg_versionhistory'
    def __unicode__(self):
        return "EPSG Version History:  %s" % (self.version_history_code)

class EpsgCoordinateaxisname(models.Model):
    coord_axis_name_code = models.IntegerField(primary_key=True)
    coord_axis_name = models.CharField(max_length=80)
    description = models.CharField(max_length=254)
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordinateaxisname'

    def __unicode__(self):
        return "EPSG Coordinate Axis: %s - %s" % (self.coord_axis_name_code, self.coord_axis_name)

class EpsgAlias(models.Model):
    alias_code = models.IntegerField(primary_key=True)
    object_table_name = models.CharField(max_length=80)
    object_code = models.IntegerField()
    naming_system_code = models.ForeignKey('EpsgNamingsystem', db_column='naming_system_code')
    alias = models.CharField(max_length=80)
    remarks = models.CharField(max_length=254)
    class Meta:
        db_table = 'epsg_alias'

class EpsgNamingsystem(models.Model):
    naming_system_code = models.IntegerField(primary_key=True)
    naming_system_name = models.CharField(max_length=80)
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_namingsystem'

class EpsgDeprecation(models.Model):
    deprecation_id = models.IntegerField(primary_key=True)
    deprecation_date = models.DateField()
    change = models.ForeignKey('EpsgChange')
    object_table_name = models.CharField(max_length=80)
    object_code = models.IntegerField()
    replaced_by = models.IntegerField()
    deprecation_reason = models.CharField(max_length=254)
    class Meta:
        db_table = 'epsg_deprecation'

class EpsgChange(models.Model):
    change_id = models.TextField(unique=True) # This field type is a guess.
    report_date = models.DateField()
    date_closed = models.DateField()
    reporter = models.CharField(max_length=254)
    request = models.CharField(max_length=254)
    tables_affected = models.CharField(max_length=254)
    codes_affected = models.CharField(max_length=254)
    change_comment = models.CharField(max_length=254)
    action = models.TextField()
    class Meta:
        db_table = 'epsg_change'

class EpsgCoordoperationparamvalue(models.Model):
    coord_op_code = models.ForeignKey('EpsgCoordoperation', db_column='coord_op_code', primary_key=True)
    coord_op_method_code = models.IntegerField()
    parameter_code = models.ForeignKey('EpsgCoordoperationparamusage', db_column='parameter_code')
    parameter_code = models.IntegerField()
    parameter_value = models.TextField() # This field type is a guess.
    param_value_file_ref = models.CharField(max_length=254)
    uom_code = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code')
    class Meta:
        db_table = 'epsg_coordoperationparamvalue'
    def __unicode__(self):
        return "EPSG Coordinate Operation Parameters:  %s - %s:'%s'" % (self.coord_op_code, self.parameter_code, self.parameter_value)
        
class EpsgCoordoperation(models.Model):
    coord_op_code = models.IntegerField(primary_key=True)
    coord_op_name = models.CharField(max_length=80)
    coord_op_type = models.CharField(max_length=24)
    source_crs_code = models.ForeignKey('EpsgCoordinatereferencesystem', db_column='source_crs_code', related_name='source_crs')
    target_crs_code = models.ForeignKey('EpsgCoordinatereferencesystem', db_column='target_crs_code', related_name='target_crs')
    coord_tfm_version = models.CharField(max_length=24)
    coord_op_variant = models.SmallIntegerField()
    area_of_use_code = models.ForeignKey('EpsgArea', db_column='area_of_use_code')
    coord_op_scope = models.CharField(max_length=254)
    coord_op_accuracy = models.TextField() # This field type is a guess.
    coord_op_method = models.ForeignKey('EpsgCoordoperationmethod', db_column='coord_op_method_code')
    uom_code_source_coord_diff = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code_source_coord_diff', related_name='measure_code_source_coord_diff')
    uom_code_target_coord_diff = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code_target_coord_diff', related_name='measure_code_target_coord_diff')
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    show_operation = models.SmallIntegerField()
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordoperation'
    
    def __unicode__(self):
        return "EPSG Coordinate Operation:  %s" % (self.coord_op_code)

class EpsgCoordoperationmethod(models.Model):
    coord_op_method_code = models.IntegerField(primary_key=True)
    coord_op_method_name = models.CharField(max_length=50)
    reverse_op = models.SmallIntegerField()
    formula = models.TextField()
    example = models.TextField()
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordoperationmethod'
        
class EpsgCoordoperationparam(models.Model):
    parameter_code = models.IntegerField(primary_key=True)
    parameter_name = models.CharField(max_length=80)
    description = models.TextField()
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordoperationparam'

class EpsgCoordoperationpath(models.Model):
    concat_operation_code = models.ForeignKey('EpsgCoordoperation', db_column='concat_operation_code', related_name='concat_code')
    single_operation_code = models.ForeignKey('EpsgCoordoperation', db_column='single_operation_code', related_name='single_code')
    op_path_step = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordoperationpath'
    def __unicode__(self):
        return "EPSG Coordinate Operation Path:  %s" % (self.concat_operation_code)

class EpsgCoordoperationparamusage(models.Model):
    coord_op_method = models.ForeignKey('EpsgCoordoperationmethod', db_column='coord_op_method_code')
    parameter_code = models.ForeignKey('EpsgCoordoperationparam', db_column='parameter_code', primary_key=True)
    sort_order = models.SmallIntegerField()
    param_sign_reversal = models.CharField(max_length=3)
    class Meta:
        db_table = 'epsg_coordoperationparamusage'
        
class EpsgPrimemeridian(models.Model):
    prime_meridian_code = models.IntegerField(primary_key=True)
    prime_meridian_name = models.CharField(max_length=80)
    greenwich_longitude = models.TextField() # This field type is a guess.
    uom_code = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code')
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_primemeridian'

class EpsgEllipsoid(models.Model):
    ellipsoid_code = models.IntegerField(primary_key=True)
    ellipsoid_name = models.CharField(max_length=80)
    semi_major_axis = models.TextField() # This field type is a guess.
    uom_code = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code')
    inv_flattening = models.TextField() # This field type is a guess.
    semi_minor_axis = models.TextField() # This field type is a guess.
    ellipsoid_shape = models.SmallIntegerField()
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_ellipsoid'
    def __unicode__(self):
        return "EPSG Ellipsoid: %s - %s" % (self.ellipsoid_code, self.ellipsoid_name)

class EpsgUnitofmeasure(models.Model):
    uom_code = models.IntegerField(primary_key=True)
    unit_of_meas_name = models.CharField(max_length=80)
    unit_of_meas_type = models.CharField(max_length=50)
    target_uom_code = models.ForeignKey('self', db_column='target_uom_code')
    factor_b = models.TextField() # This field type is a guess.
    factor_c = models.TextField() # This field type is a guess.
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_unitofmeasure'

    def __unicode__(self):
        return "Unit of Measure %s: %s, %s" % ( self.uom_code, self.unit_of_meas_name, self.unit_of_meas_type)

class EpsgCoordinateaxis(models.Model):
    coord_axis_code = models.IntegerField(unique=True)
    coord_sys_code = models.ForeignKey('EpsgCoordinatesystem', db_column='coord_sys_code')
    coord_axis_name_code = models.ForeignKey('EpsgCoordinateaxisname', db_column='coord_axis_name_code')
    coord_axis_orientation = models.CharField(max_length=24)
    coord_axis_abbreviation = models.CharField(max_length=24)
    uom_code = models.ForeignKey('EpsgUnitofmeasure', db_column='uom_code')
    coord_axis_order = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordinateaxis'

class EpsgCoordinatesystem(models.Model):
    coord_sys_code = models.IntegerField(primary_key=True)
    coord_sys_name = models.CharField(max_length=254)
    coord_sys_type = models.CharField(max_length=24)
    dimension = models.SmallIntegerField()
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=50)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_coordinatesystem'
    def __unicode__(self):
        return "EPSG Coordinate System: %s - %s" % (self.coord_sys_code, self.coord_sys_name)

class EpsgCoordinatereferencesystem(models.Model):
    coord_ref_sys_code = models.IntegerField(primary_key=True)
    coord_ref_sys_name = models.CharField(max_length=80)
    area_of_use_code = models.ForeignKey('EpsgArea', db_column='area_of_use_code')
    coord_ref_sys_kind = models.CharField(max_length=24)
    coord_sys_code = models.ForeignKey('EpsgCoordinatesystem', db_column='coord_sys_code')
    datum_code = models.ForeignKey('EpsgDatum', db_column='datum_code', null=True)
    source_geogcrs_code = models.ForeignKey('self', db_column='source_geogcrs_code', related_name='src_geogcrs_code')
    projection_conv_code = models.IntegerField()
    cmpd_horizcrs_code = models.ForeignKey('self', db_column='cmpd_horizcrs_code', related_name = 'cmpd_horizcrs_code_1')
    cmpd_vertcrs_code = models.ForeignKey('self', db_column='cmpd_vertcrs_code', related_name = 'cmpd_vertcrs_code_1')
    crs_scope = models.CharField(max_length=254)
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    show_crs = models.SmallIntegerField()
    deprecated = models.SmallIntegerField()
    
    def uom_obj(self):
        crs = self
        if crs.coord_ref_sys_kind == "projected":
            crs = self.source_geogcrs_code
        datum = crs.datum_code
        ell = datum.ellipsoid_code
        return ell.uom_code 
    
    class Meta:
        db_table = 'epsg_coordinatereferencesystem'

    def __unicode__(self):
        return "EPSG Coordinate Reference System: %s - %s" % (self.coord_ref_sys_code, self.coord_ref_sys_name)

class EpsgDatum(models.Model):
    datum_code = models.IntegerField(primary_key=True)
    datum_name = models.CharField(max_length=80)
    datum_type = models.CharField(max_length=24)
    origin_description = models.CharField(max_length=254)
    realization_epoch = models.CharField(max_length=4)
    ellipsoid_code = models.ForeignKey('EpsgEllipsoid', db_column='ellipsoid_code')
    prime_meridian_code = models.ForeignKey('EpsgPrimemeridian', db_column='prime_meridian_code')
    area_of_use_code = models.ForeignKey('EpsgArea', db_column='area_of_use_code')
    datum_scope = models.CharField(max_length=254)
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_datum'
    def __unicode__(self):
        return "EPSG Datum: %s, %s" % (self.datum_code, self.datum_name)
 
class EpsgArea(models.Model):
    class Admin: pass
    area_code = models.IntegerField(primary_key=True)
    area_name = models.CharField(max_length=80)
    area_of_use = models.TextField()
    area_south_bound_lat = models.TextField(null=True) # This field type is a guess.
    area_north_bound_lat = models.TextField(null=True) # This field type is a guess.
    area_west_bound_lon = models.TextField(null=True) # This field type is a guess.
    area_east_bound_lon = models.TextField(null=True) # This field type is a guess.
    area_polygon_file_ref = models.CharField(max_length=254)
    iso_a2_code = models.CharField(max_length=2)
    iso_a3_code = models.CharField(max_length=3)
    iso_n_code = models.IntegerField(null=True)
    remarks = models.CharField(max_length=254)
    information_source = models.CharField(max_length=254)
    data_source = models.CharField(max_length=40)
    revision_date = models.DateField()
    change_id = models.CharField(max_length=50)
    deprecated = models.SmallIntegerField()
    class Meta:
        db_table = 'epsg_area'
    def __unicode__(self):
        return "EPSG Area: %s - %s" % (self.area_code, self.area_name)
