Exemple #1
0
class TrailcamItemTag(Base):
    __tablename__ = 'trailcam_item_tag'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.Unicode, nullable=False, unique=True)
    description = db.Column(db.Unicode)

    items = db.relationship('TrailcamItem',
                            secondary=trailcam_items_tags_table,
                            back_populates='tags')
Exemple #2
0
class BasemapLayer(Base, Resource):
    identity = 'basemap_layer'
    cls_display_name = _("Basemap")

    __scope__ = DataScope

    url = db.Column(db.Unicode, nullable=False)
    qms = db.Column(db.Unicode)

    @classmethod
    def check_parent(cls, parent):
        return isinstance(parent, ResourceGroup)
Exemple #3
0
class Event(Base):
    __tablename__ = 'groza_events'

    event_id = db.Column(db.Unicode, primary_key=True)
    event_type = db.Column(db.Integer,
                           nullable=False)  # 0 - lighting, 1 - other
    lighting_type = db.Column(
        db.Integer)  # 0 - cloud, 1 - positive ground, 2 - negative ground
    amplitude = db.Column(db.Integer)
    last_modified_ts = db.Column(db.TIMESTAMP, nullable=False)
    event_ts = db.Column(db.TIMESTAMP, nullable=False)
    location = db.Column(ga.Geometry('Point', srid=4326, dimension=3))
    ellipse_major_ax = db.Column(db.DECIMAL)
    ellipse_minor_ax = db.Column(db.DECIMAL)
    ellipse_azimuth = db.Column(db.DECIMAL)
class FileBucket(Base, Resource):
    identity = 'file_bucket'
    cls_display_name = _("File bucket")

    __scope__ = (DataStructureScope, DataScope)

    tstamp = db.Column(db.DateTime())

    @classmethod
    def check_parent(self, parent):
        return isinstance(parent, ResourceGroup)
Exemple #5
0
class MapboxSprite(Base, Resource):
    identity = 'mapbox_sprite'
    cls_display_name = _("Sprite")

    sprite_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)

    sprite_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return isinstance(parent, ResourceGroup)
Exemple #6
0
class Catalog(Base, Resource):
    identity = 'catalog'
    cls_display_name = _("Catalog")

    __scope__ = CatalogScope

    root_item_id = db.Column(db.ForeignKey('catalog_item.id'), nullable=False)
    root_item = db.relationship('CatalogItem', cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return isinstance(parent, ResourceGroup)
Exemple #7
0
class QgisVectorStyle(Base, Resource):
    identity = 'qgis_vector_style'
    cls_display_name = _("QGIS style")

    implements(IRenderableStyle, ILegendableStyle)

    __scope__ = DataScope

    qml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    qml_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return IFeatureLayer.providedBy(parent)

    @property
    def feature_layer(self):
        return self.parent

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs, cond=None):
        return RenderRequest(self, srs, cond)

    def _render_image(self, srs, extent, size, cond, padding=0):
        extended, render_size, target_box = _render_bounds(
            extent, size, padding)

        # Выбираем объекты по экстенту
        feature_query = self.parent.feature_query()

        # Отфильтровываем объекты по условию
        if cond is not None:
            feature_query.filter_by(**cond)

        # FIXME: Тоже самое, но через интерфейсы
        if hasattr(feature_query, 'srs'):
            feature_query.srs(srs)

        feature_query.intersects(box(*extended, srid=srs.id))
        feature_query.geom()
        features = feature_query()

        options = VectorRenderOptions(
            self, features, render_size,
            extended, target_box)
        return env.qgis.renderer_job(options)

    def render_legend(self):
        options = LegendOptions(self)
        return env.qgis.renderer_job(options)
Exemple #8
0
class BasemapWebMap(Base):
    __tablename__ = 'basemap_webmap'

    webmap_id = db.Column(db.ForeignKey(WebMap.id), primary_key=True)
    resource_id = db.Column(db.ForeignKey(Resource.id), primary_key=True)
    position = db.Column(db.Integer)
    display_name = db.Column(db.Unicode, nullable=False)
    enabled = db.Column(db.Boolean)
    opacity = db.Column(db.Float)

    webmap = db.relationship(WebMap,
                             foreign_keys=webmap_id,
                             backref=db.backref(
                                 'basemaps',
                                 cascade='all, delete-orphan',
                                 order_by=position,
                                 collection_class=ordering_list('position')))

    resource = db.relationship(Resource,
                               foreign_keys=resource_id,
                               backref=db.backref('_basemaps', cascade='all'))

    def to_dict(self):
        return dict(resource_id=self.resource_id,
                    position=self.position,
                    display_name=self.display_name,
                    enabled=self.enabled,
                    opacity=self.opacity)
Exemple #9
0
class Trailcam(Base, Resource):
    identity = 'trailcam'
    cls_display_name = _('Trail camera')

    __scope__ = DataScope

    lat = db.Column(db.Float)
    lon = db.Column(db.Float)
    is_auto = db.Column(db.Boolean)
    filter = db.Column(db.Unicode)

    email_connection_id = db.Column(db.ForeignKey(Resource.id), nullable=False)
    email_connection = db.relationship(Resource,
                                       foreign_keys=email_connection_id,
                                       cascade=False,
                                       cascade_backrefs=False)

    items = db.relationship('TrailcamItem', back_populates='trailcam')

    @classmethod
    def check_parent(cls, parent):
        return isinstance(parent, TrailcamGroup)
class LegendSprite(Base, Resource):
    identity = 'legend_sprite'
    cls_display_name = _("Legend")

    __scope__ = DataScope

    description_fileobj_id = db.Column(db.Integer,
                                       db.ForeignKey(FileObj.id),
                                       nullable=True)
    description_fileobj = db.relationship(
        FileObj, foreign_keys=[description_fileobj_id], cascade='all')

    image_fileobj_id = db.Column(db.Integer,
                                 db.ForeignKey(FileObj.id),
                                 nullable=True)
    image_fileobj = db.relationship(FileObj,
                                    foreign_keys=[image_fileobj_id],
                                    cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return IRenderableStyle.providedBy(parent)
class MapboxStyle(Base, Resource):
    identity = 'mapbox_style'
    cls_display_name = _('Mapbox style')

    style = db.Column(db.Unicode, nullable=False)
    sprite_id = db.Column(db.ForeignKey(MapboxSprite.id, ondelete="SET NULL"),
                          nullable=True)
    glyphs_id = db.Column(db.ForeignKey(MapboxGlyph.id, ondelete="SET NULL"),
                          nullable=True)

    sprite = db.relationship(MapboxSprite,
                             foreign_keys=sprite_id,
                             cascade=False,
                             cascade_backrefs=False)
    glyphs = db.relationship(MapboxGlyph,
                             foreign_keys=glyphs_id,
                             cascade=False,
                             cascade_backrefs=False)

    @classmethod
    def check_parent(cls, parent):
        return isinstance(parent, ResourceGroup)
Exemple #12
0
class MapnikStyle(Base, Resource):
    identity = 'mapnik_style'
    cls_display_name = _("Mapnik style")

    __scope__ = DataScope

    xml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    xml_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return IFeatureLayer.providedBy(parent)

    @property
    def feature_layer(self):
        return self.parent

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs, cond=None):
        return RenderRequest(self, srs, cond)

    def _render_image(self, srs, extent, size, cond, padding=0):
        """
        Рендеринг отдельного изображения(картинки, тайла)

        :param SRS srs: модель системы координат
        :param tuple[float] extent: ограничивающий прямоугольник в единицах измерения проекции (метры псевдомеркатора)
        :param tuple[integer] size: размер изображения (256 * 256)
        :param dict cond: дополнительное уловие отбора из модели
        :param float padding: отступ от картинки
        :return:
        """
        extended, render_size, target_box = _render_bounds(extent, size, padding)

        with open(env.file_storage.filename(self.xml_fileobj), mode='r') as f:
            map_xml = f.read()
        options = ImageOptions(self.id, map_xml, render_size, extended, target_box)
        return env.mapnik.renderer_job(options)

    def render_legend(self):
        with open(env.file_storage.filename(self.xml_fileobj), mode='r') as f:
            map_xml = f.read()
        options = LegendOptions(map_xml, self.parent.geometry_type, self.parent.display_name)
        return env.mapnik.renderer_job(options)
Exemple #13
0
class QgisRasterStyle(Base, Resource):
    identity = 'qgis_raster_style'
    cls_display_name = _("QGIS style")

    __scope__ = DataScope

    qml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    qml_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return parent.cls == 'raster_layer'

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs):
        return RenderRequest(self, srs)

    def _render_image(self, srs, extent, size, cond=None, padding=0):
        extended, render_size, target_box = _render_bounds(
            extent, size, padding)

        # We need raster pyramids so use working directory filename
        # instead of original filename.
        gdal_path = env.raster_layer.workdir_filename(self.parent.fileobj)

        env.qgis.qgis_init()

        mreq = MapRequest()
        mreq.set_dpi(96)
        mreq.set_crs(CRS.from_epsg(srs.id))

        style = Style.from_string(
            _qml_cache(env.file_storage.filename(self.qml_fileobj)))

        layer = Layer.from_gdal(gdal_path)
        mreq.add_layer(layer, style)

        res = mreq.render_image(extent, size)
        img = qgis_image_to_pil(res)

        return img
Exemple #14
0
class QgisRasterStyle(Base, Resource):
    identity = 'qgis_raster_style'
    cls_display_name = _("QGIS style")

    implements(IRenderableStyle)

    __scope__ = DataScope

    qml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    qml_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return parent.cls == 'raster_layer'

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs):
        return RenderRequest(self, srs)

    def _render_image(self, srs, extent, size, cond=None, padding=0):
        extended, render_size, target_box = _render_bounds(
            extent, size, padding)

        vsibuf = "/vsimem/%s" % uuid.uuid4()
        gdal.Translate(
            vsibuf,
            env.file_storage.filename(self.parent.fileobj),
            projWin=[extent[0], extent[3], extent[2], extent[1]],
            width=size[0],
            height=size[1],
        )

        options = RasterRenderOptions(
            self, vsibuf, render_size,
            extended, target_box)
        return env.qgis.renderer_job(options)
Exemple #15
0
class EmailConnection(Base, Resource):
    identity = 'trailcam_email_conn'
    cls_display_name = _('Email connection')

    email = db.Column(db.Unicode, unique=True, index=True)
    imap_server = db.Column(db.Unicode)
    imap_server_port = db.Column(db.Integer)
    login = db.Column(db.Unicode)
    password = db.Column(db.Unicode)
    status = db.Column(
        ENUM('registered',
             'first_pulling',
             'ready',
             'updating',
             name='trailcam_email_conn_status_enum'))

    __scope__ = DataScope

    @classmethod
    def check_parent(cls, parent):
        return (parent is None) or isinstance(parent, TrailcamGroup)
class FileBucketFile(Base):
    __tablename__ = 'file_bucket_file'

    id = db.Column(db.Integer, primary_key=True)
    file_bucket_id = db.Column(db.ForeignKey(FileBucket.id), nullable=False)
    fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=False)
    name = db.Column(db.Unicode(255), nullable=False)
    mime_type = db.Column(db.Unicode, nullable=False)
    size = db.Column(db.BigInteger, nullable=False)

    __table_args__ = (db.UniqueConstraint(file_bucket_id, name), )

    fileobj = db.relationship(FileObj, lazy='joined')

    file_bucket = db.relationship(FileBucket,
                                  foreign_keys=file_bucket_id,
                                  backref=db.backref(
                                      'files', cascade='all,delete-orphan'))

    @property
    def path(self):
        return env.file_storage.filename(self.fileobj)
Exemple #17
0
class QgisVectorStyle(Base, Resource):
    identity = 'qgis_vector_style'
    cls_display_name = _("QGIS style")

    __scope__ = (DataScope, DataStructureScope)

    qml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    svg_marker_library_id = db.Column(db.ForeignKey(SVGMarkerLibrary.id),
                                      nullable=True)

    qml_fileobj = db.relationship(FileObj, cascade='all')
    svg_marker_library = db.relationship(
        SVGMarkerLibrary,
        foreign_keys=svg_marker_library_id,
        cascade=False,
        cascade_backrefs=False,
    )

    @classmethod
    def check_parent(cls, parent):
        return IFeatureLayer.providedBy(parent)

    @property
    def feature_layer(self):
        return self.parent

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs, cond=None):
        return RenderRequest(self, srs, cond)

    def _render_image(self, srs, extent, size, cond, padding=0):
        extended, render_size, target_box = _render_bounds(
            extent, size, padding)

        feature_query = self.parent.feature_query()

        # Apply filter condition
        if cond is not None:
            feature_query.filter_by(**cond)

        # TODO: Do this via interfaces
        if hasattr(feature_query, 'srs'):
            feature_query.srs(srs)

        feature_query.intersects(box(*extended, srid=srs.id))
        feature_query.geom()

        env.qgis.qgis_init()

        crs = CRS.from_epsg(srs.id)

        mreq = MapRequest()
        mreq.set_dpi(96)
        mreq.set_crs(crs)

        def path_resolver(name):
            for skip_path in SKIP_PATHS:
                if name.startswith(skip_path):
                    name = name.replace(skip_path, '', 1)
                    break

            if path.isabs(name):
                raise ValueError("Absolute paths are not allowed.")

            name = path.normpath(name)
            if name[-4:].lower() == '.svg':
                name = name[:-4]

            items = name.split(path.sep)
            for i in range(len(items)):
                candidate = path.sep.join(items[i:])
                filename = env.svg_marker_library.lookup(
                    candidate, self.svg_marker_library)
                if filename is not None:
                    return filename

            return name

        style = Style.from_string(
            _qml_cache(env.file_storage.filename(self.qml_fileobj)),
            path_resolver)

        style_attrs = style.used_attributes()

        qhl_fields = list()
        cnv_fields = list()
        qry_fields = list()

        for field in self.parent.fields:
            fkeyname = field.keyname
            if (style_attrs is not None) and (fkeyname not in style_attrs):
                continue
            field_to_qgis = _FIELD_TYPE_TO_QGIS[field.datatype]
            qhl_fields.append((fkeyname, field_to_qgis[0]))
            cnv_fields.append((fkeyname, field_to_qgis[1]))
            qry_fields.append(fkeyname)

        feature_query.fields(*qry_fields)

        features = list()
        for feat in feature_query():
            features.append((feat.id, feat.geom.wkb,
                             tuple([
                                 convert(feat.fields[field])
                                 for field, convert in cnv_fields
                             ])))

        if len(features) == 0:
            return None

        layer = Layer.from_data(_GEOM_TYPE_TO_QGIS[self.parent.geometry_type],
                                crs, tuple(qhl_fields), tuple(features))

        mreq.add_layer(layer, style)

        res = mreq.render_image(extent, size)
        return qgis_image_to_pil(res)

    def render_legend(self):
        env.qgis.qgis_init()

        mreq = MapRequest()
        mreq.set_dpi(96)

        style = Style.from_string(
            _qml_cache(env.file_storage.filename(self.qml_fileobj)))

        layer = Layer.from_data(_GEOM_TYPE_TO_QGIS[self.parent.geometry_type],
                                CRS.from_epsg(self.parent.srs.id), (), ())

        mreq.add_layer(layer, style)
        res = mreq.render_legend()
        img = qgis_image_to_pil(res)

        # PNG-compressed buffer is required for render_legend()
        # TODO: Switch to PIL Image in future!
        buf = BytesIO()
        img.save(buf, 'png')
        buf.seek(0)
        return buf
Exemple #18
0
class Meta(Base):
    __tablename__ = 'groza_meta'

    key = db.Column(db.Unicode, primary_key=True)
    value = db.Column(db.Unicode, primary_key=True)
Exemple #19
0
class QgisVectorStyle(Base, Resource):
    identity = 'qgis_vector_style'
    cls_display_name = _("QGIS style")

    implements(IRenderableStyle)

    __scope__ = DataScope

    qml_fileobj_id = db.Column(db.ForeignKey(FileObj.id), nullable=True)
    qml_fileobj = db.relationship(FileObj, cascade='all')

    @classmethod
    def check_parent(cls, parent):
        return IFeatureLayer.providedBy(parent)

    @property
    def feature_layer(self):
        return self.parent

    @property
    def srs(self):
        return self.parent.srs

    def render_request(self, srs):
        return RenderRequest(self, srs)

    def _render_image(self, srs, extent, size, padding=0):
        res_x = (extent[2] - extent[0]) / size[0]
        res_y = (extent[3] - extent[1]) / size[1]

        # Экстент с учетом отступов
        extended = (
            max(srs.minx, extent[0] - res_x * padding),
            max(srs.miny, extent[1] - res_y * padding),
            min(srs.maxx, extent[2] + res_x * padding),
            min(srs.maxy, extent[3] + res_y * padding),
        )

        # Маска отступов
        pmask = (extended[0] != srs.minx, extended[1] != srs.miny,
                 extended[2] != srs.maxx, extended[3] != srs.maxy)

        # Размер изображения с учетом отступов
        render_size = (size[0] + int(pmask[0] + pmask[2]) * padding,
                       size[1] + int(pmask[1] + pmask[3]) * padding)

        # Фрагмент изображения размера size
        target_box = (pmask[0] * padding, pmask[3] * padding,
                      size[0] + pmask[0] * padding,
                      size[1] + pmask[3] * padding)

        # Выбираем объекты по экстенту
        feature_query = self.parent.feature_query()

        # FIXME: Тоже самое, но через интерфейсы
        if hasattr(feature_query, 'srs'):
            feature_query.srs(srs)

        feature_query.intersects(box(*extended, srid=srs.id))
        feature_query.geom()
        features = feature_query()

        res_img = None
        try:
            dirname, fndata, fnstyle = None, None, None

            dirname = mkdtemp()
            fndata = os.path.join(dirname, 'layer.geojson')

            with open(fndata, 'wb') as fd:
                fd.write(geojson.dumps(features))

            fnstyle = os.path.join(dirname, 'layer.qml')
            os.symlink(env.file_storage.filename(self.qml_fileobj), fnstyle)

            result = Queue()
            env.qgis.queue.put(
                (fndata, self.srs, render_size, extended, target_box, result))
            render_timeout = int(env.qgis.settings.get('render_timeout'))
            res_img = result.get(block=True, timeout=render_timeout)

        finally:
            if fndata and os.path.isfile(fndata):
                os.unlink(fndata)
            if fnstyle and os.path.isfile(fnstyle):
                os.unlink(fnstyle)
            if dirname and os.path.isdir(dirname):
                os.rmdir(dirname)

        return res_img
Exemple #20
0

class TrailcamGroup(Base, Resource):
    identity = 'trailcam_group'
    cls_display_name = _('Trail cameras')

    __scope__ = DataScope

    @classmethod
    def check_parent(cls, parent):
        return (parent is None) or isinstance(parent, ResourceGroup)


trailcam_items_tags_table = db.Table(
    'trailcam_items_tags', Base.metadata,
    db.Column('trailcam_id', db.Integer, db.ForeignKey('trailcam_items.id')),
    db.Column('tag_id', db.Integer, db.ForeignKey('trailcam_item_tag.id')))


class TrailcamItemTag(Base):
    __tablename__ = 'trailcam_item_tag'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.Unicode, nullable=False, unique=True)
    description = db.Column(db.Unicode)

    items = db.relationship('TrailcamItem',
                            secondary=trailcam_items_tags_table,
                            back_populates='tags')

Exemple #21
0
class TrailcamItem(Base, JsonifyMixin):
    __tablename__ = 'trailcam_items'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email_uid = db.Column(db.Unicode, index=True)
    name = db.Column(db.Unicode, nullable=False)
    description = db.Column(db.Unicode)
    date_received = db.Column(db.DateTime(timezone=True), nullable=False)
    date_original = db.Column(db.DateTime(timezone=True), nullable=False)
    message_body = db.Column(db.Unicode)
    file_name = db.Column(db.Unicode)
    file_path = db.Column(db.Unicode)
    file_path_thumbnail = db.Column(db.Unicode)
    file_size = db.Column(db.BigInteger)

    trailcam_id = db.Column(db.Integer, db.ForeignKey('trailcam.id'))
    trailcam = db.relationship('Trailcam', back_populates='items')

    tags = db.relationship('TrailcamItemTag',
                           secondary=trailcam_items_tags_table,
                           back_populates="items")
Exemple #22
0
class CatalogItem(Base):
    __tablename__ = 'catalog_item'

    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('catalog_item.id'))
    item_type = db.Column(db.Enum('root', 'group', 'layer'), nullable=False)
    position = db.Column(db.Integer)
    display_name = db.Column(db.Unicode)
    description = db.Column(db.Unicode)
    layer_enabled = db.Column(db.Boolean)
    layer_wms_id = db.Column(db.ForeignKey(Resource.id))
    layer_wfs_id = db.Column(db.ForeignKey(Resource.id))
    layer_webmap_id = db.Column(db.ForeignKey(Resource.id))
    layer_resource_id = db.Column(db.ForeignKey(Resource.id), nullable=True)

    parent = db.relationship(
        'CatalogItem', remote_side=id, backref=db.backref(
            'children', order_by=position, cascade='all, delete-orphan',
            collection_class=ordering_list('position')))

    def to_dict(self):
        if self.item_type in ('root', 'group'):
            children = list(self.children)
            sorted(children, key=lambda c: c.position)

            if self.item_type == 'root':
                return dict(
                    item_type=self.item_type,
                    children=[i.to_dict() for i in children],
                )

            elif self.item_type == 'group':
                return dict(
                    item_type=self.item_type,
                    display_name=self.display_name,
                    description=self.description,
                    children=[i.to_dict() for i in children],
                )

        elif self.item_type == 'layer':
            return dict(
                item_type=self.item_type,
                display_name=self.display_name,
                description=self.description,
                layer_enabled=self.layer_enabled,
                layer_webmap_id=self.layer_webmap_id,
                layer_wms_id=self.layer_wms_id,
                layer_wfs_id=self.layer_wfs_id,
                layer_resource_id=self.layer_resource_id
            )

    def from_dict(self, data):
        assert data['item_type'] == self.item_type
        if data['item_type'] in ('root', 'group') and 'children' in data:
            self.children = []
            for i in data['children']:
                child = CatalogItem(parent=self, item_type=i['item_type'])
                child.from_dict(i)
                self.children.append(child)

        for a in ('display_name',
                  'description',
                  'layer_enabled',
                  'layer_webmap_id',
                  'layer_wms_id',
                  'layer_wfs_id',
                  'layer_resource_id'):

            if a in data:
                setattr(self, a, data[a])