Beispiel #1
0
    def _get_radius_query(self, queryset, radius):
        if not self._is_filter_enabled('near'):
            raise rest_serializers.ValidationError(
                'near parameter must be set to use radius filter')

        near = self._get_filter_string('near')
        try:
            srid = self._get_srid_parameter()
            point = self._coordinates_from_string('near', near, 2)
        except ValueError as e:
            rest_serializers.ValidationError(str(e))

        postgis_point = Func(Value(point[0]),
                             Value(point[1]),
                             function='ST_MakePoint',
                             output_field=GeometryField())
        srid_point = Func(postgis_point,
                          srid,
                          function='ST_SetSRID',
                          output_field=GeometryField())
        transformed_point = Func(srid_point,
                                 28992,
                                 function='ST_Transform',
                                 output_field=GeometryField())

        queryset = queryset.filter(
            _geolocation_2d_rd__dwithin=(transformed_point, D(m=radius)))

        # Sort by indexed KNN distance, see https://postgis.net/docs/geometry_distance_knn.html
        order_by_distance = CombinedExpression(F('_geolocation_2d_rd'), '<->',
                                               transformed_point)
        return queryset.order_by(order_by_distance)
Beispiel #2
0
class Feature(TaggedModel, LinkableModel, AttachableModel, RecursiveModel):
    name = models.CharField(max_length=255)
    type = models.CharField(
        choices=[
            ('feature', 'Feature'),
            ('water_body', 'Water Body'),
            ('glacier', 'Glacier'),
            ('bog', 'Bog'),
            ('geopolitical_unit', 'Geopolitical Unit'),
            ('region', 'Region')
        ],
        default='feature',
        max_length=55
    )
    description = models.TextField(blank=True)
    source = models.TextField(blank=True)

    geometry = GeometryField(blank=True, null=True)
    geo_elev = models.FloatField(default=0)
    geo_error = models.FloatField(default=0)

    modified = models.DateTimeField('modified', auto_now=True)
    created = models.DateTimeField('created', auto_now_add=True)

    class Meta:
        ordering = ['-modified']

    def save(self, *args, **kwargs):
        self.cache_recursive_depth()
        super().save(*args, **kwargs)

    def __str__(self):
        return '%s <%s %s>' % (self.name, self.type, self.pk)
Beispiel #3
0
class Circonscription(models.Model):
    departement = models.CharField(verbose_name="Code du département",
                                   max_length=3)

    numero = models.PositiveSmallIntegerField(
        verbose_name="Numéro de la circonscription")

    contour = GeometryField(verbose_name="Contour", geography=True, null=True)
    centroid = PointField(verbose_name="Centre approximatif",
                          geography=True,
                          null=True)

    @property
    def nom(self):
        if self.numero == 1:
            ordinal_suffix = "ère"
        else:
            ordinal_suffix = "ème"

        return format_html(
            "{numero}<sup>{ordinal}</sup> circonscription {departement}",
            numero=self.numero,
            ordinal=ordinal_suffix,
            departement=departements[self.departement].avec_charniere,
        )

    def __str__(self):
        return f"{self.departement}-{self.numero}"

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["departement", "numero"],
                                    name="code_circonscription")
        ]
        verbose_name = "Circonscription"
Beispiel #4
0
class Branch(Timestamped, AppModel):
    location = GeometryField(
        geography=True,
        blank=True,
        null=True,
    )
    name = models.CharField(
        max_length=255,
        db_index=True,
    )
    facade = models.ImageField(
        blank=True,
        upload_to=RandomPath('branches/facades'),
    )

    objects = BranchQueryset.as_manager()

    class Meta:
        ordering = ['-id']
        indexes = [
            GistIndex(name='branch_name_gist_trgm_index',
                      fields=['name'],
                      opclasses=['gist_trgm_ops']),
        ]

    @property
    def employees_count(self) -> int:
        if hasattr(self, '_employees_count'):
            return self._employees_count  # type: ignore
        return self.employees.count()
Beispiel #5
0
 def get_kwargs_relation_by_type(self, qs, relation):
     kwargs = {}
     if relation.relation_type == 'intersects':
         kwargs.update({
             'geom__intersects': self.geom,
         })
     elif relation.relation_type == 'distance':
         if django_version < (3, 2):
             qs = qs.annotate(geography=Cast('geom', output_field=GeometryField(geography=True)))
         else:
             qs = qs.alias(geography=Cast('geom', output_field=GeometryField(geography=True)))
         kwargs.update({
             'geography__dwithin': (self.geom,
                                    relation.settings.get('distance')),
         })
     return qs, kwargs
Beispiel #6
0
    def get_bbox_layer(cls, layer):
        """
        Method giving the bbox of a layer,
        under the form of a Polygon (if > 0)
        OUTPUT query # Polygon (bbox) with 'extent' attribute
        """
        features = layer.features.all()

        query = features.annotate(
            geom3857=Cast(ST_Transform('geom', EPSG_3857),
                          GeometryField(srid=EPSG_3857))
            ).aggregate(
            extent=Cast(ST_Extent('geom3857'), GeometryField(srid=0))
            )

        return query
Beispiel #7
0
class HighwayAuthority(ReferenceModel):
    id = models.CharField(max_length=20, primary_key=True)
    mapit_id = models.CharField(max_length=20, blank=True)
    geometry = GeometryField(null=True, blank=True, db_index=True)

    class Meta:
        ordering = ('label', )
Beispiel #8
0
 def test_geometry_value_annotation_different_srid(self):
     p = Point(1, 1, srid=32140)
     point = City.objects.annotate(p=Value(p, GeometryField(
         srid=4326))).first().p
     self.assertTrue(
         point.equals_exact(p.transform(4326, clone=True), 10**-5))
     self.assertEqual(point.srid, 4326)
Beispiel #9
0
class ZipCode(models.Model):
    zipcode = USZipCodeField(
        _('zip code'),
        validators=[validate_zip],
    )
    geometry = GeometryField(
        _('geometry'),
        null=True,
    )
    state = models.ForeignKey(
        State,
        related_name='state_zipcodes',
        on_delete=models.CASCADE,
    )
    counties = models.ManyToManyField(
        County,
        related_name='county_zipcodes',
    )
    population = models.PositiveIntegerField(
        _('population'),
        null=True,
    )

    class Meta:
        verbose_name = _('zip code')
        verbose_name_plural = _('zip codes')
        indexes = [
            models.Index(fields=['zipcode']),
            models.Index(fields=['state_id']),
        ]

    def __str__(self):
        return '{} - {}'.format(self.zipcode, self.state)
Beispiel #10
0
def run():
    """ Runs the script """
    # First do it for the cities which have tiles
    countries = Country.objects.all()
    country_count = countries.count()
    for idx1, country in enumerate(countries):
        nr_of_country_cities = City.objects.filter(country=country).count()
        # TODO: REMOVE canton__name='Vaud'
        cities = City.objects.filter(country=country).filter(Q(canton__name='Vaud') | Q(canton__name='Genève'))
        city_count = cities.count()
        for idx2, city in enumerate(cities):
            metrics = Tile.objects.annotate(geom=Cast('mpoly', GeometryField())) \
                .filter(geom__within=city.mpoly) \
                .annotate(count=Count('*')) \
                .filter(count__gt=0) \
                .aggregate(Avg('tree_density'), Avg('tree_sparsity'))
            if metrics['tree_density__avg'] is not None: # Check if result returned, a.k.a has tiles
                tree_density = metrics['tree_density__avg']
                tree_sparsity = metrics['tree_sparsity__avg']
                cars_pp = city.cars / city.population
                rel_population = city.population / country.population * nr_of_country_cities
                rel_area = city.area / country.area * nr_of_country_cities
                city.tree_density = tree_density
                city.tree_sparsity = tree_sparsity
                city.score = np.dot(weights, [
                    tree_density,
                    functions.sparsity_to_representable(tree_sparsity),
                    (1 - cars_pp),
                    rel_population,
                    rel_area
                ])
                city.has_mapping = True
                city.save()
            print('Fetched city {}/{} ({})'.format(idx2 + 1, city_count, city.name))
        print('Fetched country {}/{} ({})'.format(idx1 + 1, country_count, country.name))
Beispiel #11
0
def cantonPolygon(request, id):
    item = models.Canton.objects.filter(id=id).first()
    if item is None:
        raise Http404
    cached_url = os.path.join(settings.BASE_DIR, 'ui', 'static', 'pxs',
                              'cantons', '{}.png'.format(item.pk))
    if os.path.isfile(cached_url):
        response = HttpResponse(content_type='image/png')
        functions.read_image(cached_url).save(response, 'PNG')
        return response
    tiles = models.Tile.objects \
        .annotate(geom=Cast('mpoly', GeometryField())) \
        .filter(geom__within=item.mpoly)
    densities = []
    for tile in tiles:
        centroid = tile.mpoly.centroid
        densities.append({
            'x': centroid.x,
            'y': centroid.y,
            'value': tile.tree_density
        })
    polygon = functions.get_polygon(json.loads(item.mpoly.json),
                                    densities=densities)
    response = HttpResponse(content_type='image/png')
    polygon.save(cached_url, 'png')
    polygon.save(response, 'PNG')
    return response
Beispiel #12
0
class AbstractTrackingData(models.Model):
    """
    Base model fields and meta data for Tracking
    Will be extended with FKs in child models
    """
    id = models.CharField(primary_key=True, default=random_id, max_length=36)
    created_at = models.DateTimeField(auto_now_add=True)

    latitude = models.FloatField(max_length=36)
    longitude = models.FloatField(max_length=36)
    altitude = models.FloatField(max_length=36, null=True, blank=True)
    source = models.CharField(max_length=36)
    uncertainty = models.IntegerField(
        validators=[MinValueValidator(0),
                    MaxValueValidator(100)],
        null=True,
        blank=True)
    speed = models.FloatField(validators=[MinValueValidator(0)],
                              null=True,
                              blank=True)
    timestamp = models.DateTimeField(db_index=True)
    time = AliasField(db_column='timestamp')
    version = models.CharField(max_length=36)
    point = GeometryField(spatial_index=True)

    class Meta:
        abstract = True
        ordering = ('timestamp', )
class Notification(models.Model):
    class Meta:
        verbose_name = 'Notification'
        verbose_name_plural = 'Notifications'

    owner = models.ForeignKey(User,
                              verbose_name='Owner',
                              on_delete=models.CASCADE,
                              null=False,
                              blank=False,
                              related_name='notification')
    title = models.CharField(verbose_name='Title',
                             max_length=128,
                             blank=True,
                             null=True)
    description = models.TextField(verbose_name='Description',
                                   blank=True,
                                   null=True)
    place = GeometryField(verbose_name='Place',
                          geography=True,
                          blank=True,
                          null=True)
    participants = models.ManyToManyField(User,
                                          verbose_name='Participants',
                                          related_name='notifications',
                                          blank=True)
    created_at = models.DateTimeField(verbose_name='Created at',
                                      auto_now_add=True)
    activation_time = models.DateTimeField(verbose_name='Activation time',
                                           blank=False,
                                           null=False)
    sent = models.BooleanField(verbose_name='Has been sent', default=False)
Beispiel #14
0
class Asset(Model):
    """Top level class for entire class hierarchy"""
    class Meta:
        db_table = "asset"

    """Asset type can take following values:
            - pipeline
            - power line
            - electric truss
    """

    PIPELINE = 'PIP'
    POWER_LINE = 'POW'
    ELECTRIC_TRUSS = 'ELE'

    TYPE_CHOICES = (
        (PIPELINE, 'Pipeline'),
        (POWER_LINE, 'Power line'),
        (ELECTRIC_TRUSS, 'Electric truss'),
    )

    id = UUIDField(primary_key=True, default=uuid4, editable=False)
    type = CharField(max_length=3,
                     choices=TYPE_CHOICES,
                     blank=False,
                     null=False)
    name = CharField(max_length=120,
                     blank=False,
                     null=False,
                     default=default_asset_name)
    created = DateTimeField(auto_now_add=True)
    modified = DateTimeField(auto_now=True)
    description = TextField(blank=True, null=True)
    note = TextField(blank=True, null=True)
    geometry = GeometryField(blank=True, null=True, srid=settings.DEFAULT_SRID)
Beispiel #15
0
class GeometryModel(models.Model):
    name = models.CharField(max_length=255)
    geometry = GeometryField(srid=settings.SRID)

    objects = GeoManager()

    def __str__(self):
        return self.name
Beispiel #16
0
def Buffer(geom, radius, num_seg):
    """
    ST_Buffer postgis function
    """
    return Func(geom,
                radius,
                num_seg,
                function='ST_Buffer',
                output_field=GeometryField())
Beispiel #17
0
 def test_geography_value(self):
     p = Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1)))
     area = (
         City.objects.annotate(
             a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))
         )
         .first()
         .a
     )
     self.assertAlmostEqual(area.sq_km, 12305.1, 0)
Beispiel #18
0
    def setUp(self):
        self.point1 = MushroomSpot.objects.create(serialized='SRID=%s;POINT(0 0)' % settings.SRID)
        self.line1 = MushroomSpot.objects.create(serialized='SRID=%s;LINESTRING(0 0, 10 0)' % settings.SRID)
        self.multipoint = MushroomSpot.objects.create(serialized='SRID=%s;MULTIPOINT((1 1), (2 2))' % settings.SRID)

        MushroomSpot.geomfield = GeometryField(name='geom', srid=2154)

        self.serializer = ZipShapeSerializer()
        devnull = open(os.devnull, "wb")
        self.serializer.serialize(MushroomSpot.objects.all(), stream=devnull,
                                  fields=['id', 'name', 'number', 'size', 'boolean'], delete=False)
Beispiel #19
0
    def _get_bbox_query(self, queryset, value):
        try:
            bbox = self._bbox_from_string(value)
            srid = self._get_srid_parameter()
        except ValueError as e:
            rest_serializers.ValidationError(str(e))

        envelope = Func(Value(bbox['x1']),
                        Value(bbox['y1']),
                        Value(bbox['x2']),
                        Value(bbox['y2']),
                        srid,
                        function='ST_MakeEnvelope',
                        output_field=GeometryField())
        transformed_envelope = Func(envelope,
                                    28992,
                                    function='ST_Transform',
                                    output_field=GeometryField())
        return queryset.filter(
            _geolocation_2d_rd__bboverlaps=(transformed_envelope))
Beispiel #20
0
class PoliceForce(ReferenceModel):
    uri = models.URLField(db_index=True)
    comment = models.TextField()
    homepage = models.TextField()
    logo_url = models.TextField()
    dbpedia = models.TextField()
    geometry = GeometryField(null=True, blank=True, db_index=True)

    def get_absolute_url(self):
        return reverse('police-force-detail', args=(self.id, ))

    class Meta:
        ordering = ('label', )
class SpatialUnit(RandomIDModel):
    """
    A single spatial unit: has a type, an optional geometry, a
    type-dependent set of attributes and a set of relationships to
    other spatial units.

    """

    # Possible spatial unit types: TYPE_CHOICES is the well-known name
    # used by the JSONAttributesField field type to manage the range
    # of allowed attribute fields.  The following list of spatial unit
    # types is obviously non-exhaustive.  I've included a
    # "miscellaneous" type to cover things like rights of way,
    # national park boundaries and so on, which would be distinguihsed
    # by attributes.
    PARCEL = 'PA'
    COMMUNITY_BOUNDARY = 'CB'
    BUILDING = 'BU'
    APARTMENT = 'AP'
    PROJECT_EXTENT = 'PX'
    RIGHT_OF_WAY = 'RW'
    UTILITY_CORRIDOR = 'UC'
    NATIONAL_PARK_BOUNDARY = 'NP'
    MISCELLANEOUS = 'MI'
    TYPE_CHOICES = ((PARCEL, 'Parcel'), (COMMUNITY_BOUNDARY,
                                         'Community boundary'),
                    (BUILDING, 'Building'), (APARTMENT, 'Apartment'),
                    (PROJECT_EXTENT, 'Project extent'),
                    (RIGHT_OF_WAY, 'Right-of-way'), (UTILITY_CORRIDOR,
                                                     'Utility corridor'),
                    (NATIONAL_PARK_BOUNDARY, 'National park boundary'),
                    (MISCELLANEOUS, 'Miscellaneous'))

    # All spatial units are associated with a single project.
    project = models.ForeignKey(Project, on_delete=models.CASCADE)

    # Spatial unit geometry is optional: some spatial units may only
    # have a textual description of their location.
    geometry = GeometryField(null=True)

    # Spatial unit type: used to manage range of allowed attributes.
    type = models.CharField(max_length=2, choices=TYPE_CHOICES, default=PARCEL)

    # JSON attributes field with management of allowed members.
    attributes = JSONAttributesField()

    # Spatial unit-spatial unit relationships: includes spatial
    # containment and split/merge relationships.
    relationships = TemporalManyToManyField('self',
                                            through='SpatialUnitRelationship',
                                            through_fields=('su1', 'su2'))
Beispiel #22
0
def polygonStats(request):
    param = request.GET.get('geojson', None)
    if not param:
        raise Http404
    response = {}
    parsed_geojson = json.loads(param)
    geometry = GEOSGeometry(json.dumps(parsed_geojson['geometry']))
    country = models.Country.objects \
        .annotate(geom=Cast('mpoly', GeometryField())) \
        .filter(geom__contains=geometry) \
        .first()
    if country:
        metrics = models.Tile.objects \
            .annotate(geom=Cast('mpoly', GeometryField())) \
            .filter(geom__within=geometry) \
            .aggregate(Avg('tree_density'), Avg('tree_sparsity'), Sum(Area('mpoly')))
        tree_density = 0
        tree_sparsity = 0
        weights = [
            160,  # Tree coverage
            240,  # Tree sparsity
            2  # Relative area
        ]
        if metrics[
                'tree_density__avg']:  # Check if result returned, a.k.a has tiles
            tree_density = metrics['tree_density__avg']
            tree_sparsity = metrics['tree_sparsity__avg']
            rel_area = metrics['Area__sum'].sq_m / country.area
            score = np.dot(weights, [
                tree_density,
                functions.sparsity_to_representable(tree_sparsity), rel_area
            ])
            response['tree_density'] = tree_density
            response['tree_sparsity'] = tree_sparsity
            response['rel_area'] = rel_area
            response['score'] = score
    return JsonResponse(response)
Beispiel #23
0
    def get(self, request, pk=None, project_pk=None):
        """
        Get tile.json for this tasks's orthophoto
        """
        task = self.get_and_check_task(request, pk, project_pk, annotate={
                'orthophoto_area': Envelope(Cast("orthophoto", GeometryField()))
            })

        if task.orthophoto_area is None:
            raise exceptions.ValidationError("An orthophoto has not been processed for this task. Tiles are not available yet.")

        json = get_tile_json(task.name, [
                '/api/projects/{}/tasks/{}/tiles/{{z}}/{{x}}/{{y}}.png'.format(task.project.id, task.id)
            ], task.orthophoto_area.extent)
        return Response(json)
Beispiel #24
0
 def get_queryset(self):
     """
     - group all geometries together (st_collect) by same variable & value
     """
     qs = NsemPsaContour.objects.filter(nsem_psa_variable__nsem=self.nsem)
     qs = qs.values(*[
         'value',
         'color',
         'date',
         'nsem_psa_variable__name',
         'nsem_psa_variable__data_type',
         'nsem_psa_variable__display_name',
         'nsem_psa_variable__units',
     ])
     qs = qs.annotate(geom=Collect(Cast('geo', GeometryField())))
     qs = qs.order_by('nsem_psa_variable__name')
     return qs
Beispiel #25
0
 def get(self, request, pk=None, project_pk=None):
     """
     Get tile.json for this tasks's orthophoto
     """
     task = self.get_and_check_task(request,
                                    pk,
                                    project_pk,
                                    annotate={
                                        'orthophoto_area':
                                        Envelope(
                                            Cast("orthophoto",
                                                 GeometryField()))
                                    })
     json = get_tile_json(task.name, [
         '/api/projects/{}/tasks/{}/tiles/{{z}}/{{x}}/{{y}}.png'.format(
             task.project.id, task.id)
     ], task.orthophoto_area.extent)
     return Response(json)
Beispiel #26
0
class County(models.Model):
    county_name = models.CharField(
        _('us county name'),
        max_length=255,
        blank=True,
    )
    county_name_slug = models.SlugField(
        _('us county name slug'),
        max_length=255,
        blank=True,
    )
    state = models.ForeignKey(
        State,
        related_name='counties',
        on_delete=models.CASCADE,
    )
    geometry = GeometryField(
        _('geometry'),
        null=True,
    )
    county_id = models.PositiveIntegerField(
        _('county us id'),
        null=True,
    )
    geo_id = models.PositiveIntegerField(
        _('geo id'),
        null=True,
    )
    population = models.PositiveIntegerField(
        _('population'),
        null=True,
    )

    class Meta:
        verbose_name = _('county')
        verbose_name_plural = _('counties')

    def __str__(self):
        return self.county_name

    def save(self, *args, **kwargs):
        if not self.county_name_slug and self.county_name:
            self.county_name_slug = slugify(self.county_name)
        super().save(*args, **kwargs)
Beispiel #27
0
class Location(AnonymousHistoricalMixin, models.Model):
    id = models.CharField(primary_key=True, default=random_id, max_length=36)

    phone_regex = RegexValidator(
        regex=r'^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}',
        message="Invalid phone number.")
    country_regex = RegexValidator(
        regex=
        r'^A[^ABCHJKNPVY]|B[^CKPUX]|C[^BEJPQST]|D[EJKMOZ]|E[CEGHRST]|F[IJKMOR]|'
        r'G[^CJKOVXZ]|H[KMNRTU]|I[DEL-OQ-T]|J[EMOP]|K[EGHIMNPRWYZ]|L[ABCIKR-VY]|'
        r'M[^BIJ]|N[ACEFGILOPRUZ]|OM|P[AE-HK-NRSTWY]|QA|R[EOSUW]|S[^FPQUW]|'
        r'T[^ABEIPQSUXY]|U[AGMSYZ]|V[ACEGINU]|WF|WS|YE|YT|Z[AMW]',
        message="Invalid ISO 3166-1 alpha-2 country code.")
    name = models.CharField(max_length=255)
    address_1 = models.CharField(max_length=255, blank=True, null=True)
    address_2 = models.CharField(max_length=255, blank=True, null=True)
    city = models.CharField(max_length=255, blank=True, null=True)
    state = models.CharField(max_length=255, blank=True, null=True)
    country = models.CharField(max_length=2,
                               validators=[country_regex],
                               blank=True,
                               null=True)
    postal_code = models.CharField(max_length=255, blank=True, null=True)

    phone_number = models.CharField(validators=[phone_regex],
                                    max_length=255,
                                    blank=True,
                                    null=True)
    fax_number = models.CharField(validators=[phone_regex],
                                  max_length=255,
                                  blank=True,
                                  null=True)

    # Contact fields
    contact_email = models.EmailField(blank=True, null=True)
    contact_name = models.CharField(max_length=255, blank=True, null=True)

    geometry = GeometryField(null=True)

    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    # Model's history tracking definition
    history = TxmHistoricalRecords()
Beispiel #28
0
    def setUp(self):
        self.point1 = MushroomSpot.objects.create(
            serialized='SRID=%s;POINT(0 0)' % settings.SRID)
        self.point1.tags.add(Tag.objects.create(label="Tag1"))
        self.point1.tags.add(Tag.objects.create(label="Tag2"))
        self.line1 = MushroomSpot.objects.create(
            serialized='SRID=%s;LINESTRING(0 0, 10 0)' % settings.SRID)
        self.multipoint = MushroomSpot.objects.create(
            serialized='SRID=%s;MULTIPOINT((1 1), (2 2))' % settings.SRID)

        MushroomSpot.geomfield = GeometryField(name='geom', srid=settings.SRID)

        self.serializer = ZipShapeSerializer()
        response = HttpResponse()
        self.serializer.serialize(
            MushroomSpot.objects.all(),
            stream=response,
            fields=['id', 'name', 'number', 'size', 'boolean', 'tags'],
            delete=False)
Beispiel #29
0
class State(models.Model):
    center_lat = models.CharField(
        _('center latitude'),
        blank=True,
        null=True,
        max_length=250,
    )
    center_lng = models.CharField(
        _('center longitude'),
        blank=True,
        null=True,
        max_length=250,
    )
    state_code = USStateField(
        _('us state code'),
        validators=[validate_state],
        null=True,
    )
    state_name = models.CharField(
        _('us state name'),
        max_length=255,
        blank=True,
    )
    geometry = GeometryField(
        _('geometry'),
        null=True,
    )
    state_us_id = models.PositiveIntegerField(
        _('state us id'),
        null=True,
        unique=True,
    )
    population = models.PositiveIntegerField(
        _('population'),
        null=True,
    )

    class Meta:
        verbose_name = _('state')
        verbose_name_plural = _('states')

    def __str__(self):
        return '{} - {}'.format(self.state_code, self.state_name)
Beispiel #30
0
class Mission(Model):
    """All data is associated with Mission class, multiply missions can be attached to a single asset"""
    class Meta:
        db_table = "mission"

    asset = ForeignKey(Asset, related_name='missions', on_delete=CASCADE)
    mission_file = ForeignKey(MissionVideo,
                              null=True,
                              related_name='vid_missions',
                              on_delete=CASCADE)

    id = UUIDField(primary_key=True, default=uuid4, editable=False)
    name = CharField(max_length=120,
                     blank=False,
                     null=False,
                     default=default_mission_name)
    description = TextField(blank=True, null=True)
    note = TextField(blank=True, null=True)
    created = DateTimeField(auto_now_add=True)
    modified = DateTimeField(auto_now=True)
    geometry = GeometryField(blank=True, null=True, srid=settings.DEFAULT_SRID)