Section   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 12
c 7
b 0
f 0
dl 0
loc 139
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
B to_long_json() 0 27 4
A __repr__() 0 2 1
A to_json() 0 17 1
A outlatlon() 0 11 2
A inlatlon() 0 11 2
A geojson() 0 15 1
A __str__() 0 2 1
1
"""
2
Model for section
3
"""
4
from flask import url_for
5
from geoalchemy2 import Geometry
6
from geoalchemy2.shape import to_shape
7
from shapely.geometry import mapping
8
9
from app.database import db
10
11
12
# many to many relationship table for sections and regions
13
sections_regions = db.Table(
14
    'sections_regions',
15
    db.Column('section', db.Integer, db.ForeignKey('sections.id')),
16
    db.Column('region', db.Integer, db.ForeignKey('regions.id'))
17
)
18
19
20
class Section(db.Model):
21
    """
22
    River section that is commonly paddled and possibly has a correlation developed for it.
23
24
    Arguments:
25
        id (int): Primary key for Section
26
        name (string): Nice name for section
27
        slug (string): slug used for url
28
        river_id: Foreign River.id that this section is a segment of. \
29
                    If a section spans multiple rivers, use the river that the gage is on.
30
        river: ``River`` object
31
        description (text): Long description for Section that can contain HTML or Markdown within reason.
32
        short_description (text): Short description for section for showing on other pages.
33
        access (string): Access restrictions or issues
34
        location (string): Where is it?
35
        putin (Point): PostGIS Point object for putin. Accepts WKT.
36
        takeout (Point): PostGIS Point object for takeout. Accepts WKT.
37
        path (Linestring): PostGIS Linestring object for river. Accepts WKT.
38
        in_elevation (int): Elevation of the putin
39
        out_elevation (int): Elevation of the takeout
40
        header_image (string): Header image to override default
41
        correlations: List of ``Correlation`` objects that connect this Section to Sensors. \
42
                        Can do ``section.correlations[#].sensor`` and access the sensor attributes.
43
    """
44
    __tablename__ = 'sections'
45
46
    id = db.Column(db.Integer, primary_key=True)
47
    name = db.Column(db.String(80))
48
    slug = db.Column(db.String(80), unique=True)
49
50
    river_id = db.Column(db.Integer, db.ForeignKey('rivers.id'))
51
    river = db.relationship('River', backref='sections')
52
53
    description = db.Column(db.Text)
54
    short_description = db.Column(db.Text)
55
    access = db.Column(db.String)
56
    location = db.Column(db.String)
57
    putin = db.Column(Geometry('POINT', 4326))
58
    takeout = db.Column(Geometry('POINT', 4326))
59
    path = db.Column(Geometry('LINESTRING', 4326))
60
    in_elevation = db.Column(db.Integer)
61
    out_elevation = db.Column(db.Integer)
62
    header_image = db.Column(db.String(80))
63
64
    regions = db.relationship('Region', secondary=sections_regions,
65
                              backref=db.backref('sections', lazy='dynamic'))
66
67
    def inlatlon(self):
68
        """
69
        Returns a shapely point for put-in.
70
        section.inlatlon().y for latitude
71
        section.inlatlon().y for longitude
72
        """
73
        try:
74
            latlon_point = to_shape(self.putin)
75
        except AssertionError:
76
            return None
77
        return latlon_point
78
79
    def outlatlon(self):
80
        """
81
        Returns a shapely point for take-out.
82
        section.outlatlon().y for latitude
83
        section.outlatlon().x for longitude
84
        """
85
        try:
86
            latlon_point = to_shape(self.takeout)
87
        except AssertionError:
88
            return None
89
        return latlon_point
90
91
    def to_json(self):
92
        """
93
        Creates a JSON Object from Section. Used where multiple sections may be
94
        listed at once.
95
        """
96
        json_section = {
97
            'id': self.id,
98
            'name': self.name,
99
            'html': url_for('main.sectionpage',
100
                            slug=self.slug,
101
                            river=self.river.slug,
102
                            _external=True),
103
            'url': url_for('api.get_section',
104
                           sid=self.id,
105
                           _external=True)
106
        }
107
        return json_section
108
109
    def to_long_json(self):
110
        """
111
        Creates a JSON Object from Section. Used where a single section is
112
        displayed.
113
        """
114
        json_section = {
115
            'id': self.id,
116
            'name': self.name,
117
            'html': url_for('main.sectionpage',
118
                            slug=self.slug,
119
                            river=self.river.slug,
120
                            _external=True),
121
            'url': url_for('api.get_section', sid=self.id, _external=True),
122
            'regions': [region.to_json() for region in self.regions],
123
            'sensors': [correlation.sensor.to_json()
124
                        for correlation in self.correlations],
125
            'gages': [correlation.sensor.gage.to_json()
126
                      for correlation in self.correlations],
127
            'description': self.description,
128
            'access': self.access,
129
            'location': self.location,
130
            'in_latitude': self.inlatlon().y,
131
            'in_longitude': self.inlatlon().x,
132
            'out_latitude': self.outlatlon().y,
133
            'out_longitude': self.outlatlon().x
134
        }
135
        return json_section
136
137
    def geojson(self):
138
        """
139
        Creates a GeoJSON Feature from the gage
140
        """
141
        geometry = mapping(to_shape(self.path))
142
        geojson = {
143
            'type': 'Feature',
144
            'geometry': geometry,
145
            'properties': {
146
                'id': self.id,
147
                'name': self.name,
148
                'description': self.description
149
            }
150
        }
151
        return geojson
152
153
154
    def __repr__(self):
155
        return '<Section %r>' % self.name
156
157
    def __str__(self):
158
        return self.name