예제 #1
0
    def get_toponyms(self, req: gws.IWebRequest,
                     p: GetToponymsParams) -> GetToponymsResponse:
        """Return all Toponyms (Gemeinde/Gemarkung/Strasse) in the area"""

        req.require_project(p.projectUid)
        res = self.provider.find_strasse(types.FindStrasseQuery(p))

        gemeinde = {}
        gemarkung = {}

        for s in res.strassen:
            if s.gemeindeUid not in gemeinde:
                gemeinde[s.gemeindeUid] = ToponymGemeinde(name=re.sub(
                    r'^Stadt\s+', '', s.gemeinde),
                                                          uid=s.gemeindeUid)
            if s.gemarkungUid not in gemarkung:
                gemarkung[s.gemarkungUid] = ToponymGemarkung(
                    name=s.gemarkung,
                    uid=s.gemarkungUid,
                    gemeindeUid=s.gemeindeUid)

        return GetToponymsResponse(
            gemeinden=sorted(gemeinde.values(), key=lambda x: x.name),
            gemarkungen=sorted(gemarkung.values(), key=lambda x: x.name),
            strasseNames=[s.strasse for s in res.strassen],
            strasseGemarkungUids=[s.gemarkungUid for s in res.strassen],
        )
예제 #2
0
    def api_connect(self, req: gws.IWebRequest,
                    p: ConnectParams) -> ConnectResponse:
        req.require_project(p.projectUid)

        shape = gws.lib.shape.union(
            gws.lib.shape.from_props(s) for s in p.shapes)

        request_id = self._new_request(shape)
        if not request_id:
            raise gws.base.web.error.NotFound()

        url = self.request_url.replace('{REQUEST_ID}', request_id)

        return ConnectResponse(url=url)
예제 #3
0
    def _get_box(self, req: gws.IWebRequest, p: GetBoxParams) -> gws.BytesResponse:
        layer = req.require_layer(p.layerUid)
        content = None

        mri = gws.MapRenderInput(

        )

        extra_params = {}
        if p.layers:
            extra_params['layers'] = p.layers

        view = gws.gis.render.map_view_from_bbox(
            crs=gws.gis.crs.get(p.crs) or layer.map.crs,
            bbox=p.bbox,
            size=(p.width, p.height, units.PX),
            dpi=units.OGC_SCREEN_PPI,
            rotation=0
        )

        ts = gws.time_start(f'RENDER_BOX layer={p.layerUid} view={view!r}')
        try:
            content = layer.render_box(view, extra_params)
        except:
            gws.log.exception()
        gws.time_end(ts)

        return self._image_response(content)
예제 #4
0
    def export(self, req: gws.IWebRequest, p: ExportParams) -> ExportResponse:
        """Export Flurstueck features"""

        project = req.require_project(p.projectUid)

        fp = p.findParams
        fp.projectUid = project.uid
        fp.localeUid = p.localeUid

        res = self._find(req, fp, self.limit)

        if not res.features:
            raise gws.base.web.error.NotFound()

        combined_rules: t.List[gws.base.model.Rule] = []
        group_indexes = sorted(int(i) for i in p.groupIndexes)

        for i in group_indexes:
            combined_rules.extend(self.export_groups[i].data_model.rules)

        combined_model = self.root.create_object(
            gws.base.model.Object,
            gws.Config(rules=combined_rules),
            shared=True,
            key=group_indexes)

        csv_bytes = util.export.to_csv(self, res.features, combined_model)

        return ExportResponse(content=csv_bytes, mime='text/csv')
예제 #5
0
    def find_features(self, req: gws.IWebRequest, p: Params) -> Response:
        """Perform a search"""

        project = req.require_project(p.projectUid)

        bounds = gws.Bounds(
            crs=p.crs or project.map.crs,
            extent=p.bbox or project.map.extent,
        )

        limit = self.limit
        if p.limit:
            limit = min(int(p.limit), self.limit)

        shapes = []
        if p.shapes:
            shapes = [gws.gis.shape.from_props(s) for s in p.shapes]

        tolerance = None
        if p.tolerance:
            tolerance = gws.lib.units.parse(p.tolerance,
                                            default=gws.lib.units.PX)

        args = gws.SearchArgs(
            bounds=bounds,
            keyword=(p.keyword or '').strip(),
            layers=gws.compact(
                req.acquire('gws.ext.layer', uid) for uid in p.layerUids),
            limit=limit,
            project=project,
            resolution=p.resolution,
            shapes=shapes,
            tolerance=tolerance,
        )

        found = runner.run(req, args)

        for f in found:
            # @TODO only pull specified props from a feature
            f.transform_to(args.bounds.crs)
            f.apply_templates()
            f.apply_data_model()

        return Response(
            features=[gws.props(f, req.user, context=self) for f in found])
예제 #6
0
    def handle_request(self, req: gws.IWebRequest) -> gws.ContentResponse:
        # services can be configured globally (in which case, self.project == None)
        # and applied to multiple projects with the projectUid param
        # or, configured just for a single project (self.project != None)

        project = None

        p = req.param('projectUid')
        if p:
            project = req.require_project(p)
            if self.project and project != self.project:
                gws.log.debug(f'service={self.uid!r}: wrong project={p!r}')
                raise gws.base.web.error.NotFound('Project not found')
        elif self.project:
            # for in-project services, ensure the user can access the project
            project = req.require_project(self.project.uid)

        rd = Request(req=req, project=project)

        return self.dispatch_request(rd, req.param('request', ''))
예제 #7
0
    def info(self, req: gws.IWebRequest, p: gws.Params) -> InfoResponse:
        """Return the project configuration"""

        project = req.require_project(p.projectUid)

        locale_uid = p.localeUid
        if locale_uid not in project.locale_uids:
            locale_uid = project.locale_uids[0]

        return InfoResponse(
            project=gws.props(project, req.user),
            locale=gws.lib.intl.locale(locale_uid),
            user=None if req.user.is_guest else gws.props(req.user, req.user))
예제 #8
0
    def api_get_data(self, req: gws.IWebRequest,
                     p: GetDataParams) -> GetDataResponse:

        req.require_project(p.projectUid)
        request_id = p.requestId
        geom = self._selection_for_request(request_id)

        if not geom:
            gws.log.warn(f'request {request_id!r} not found')
            raise gws.base.web.error.NotFound()

        self._populate_data_table()
        atts = self._select_data(request_id)
        shape = gws.lib.shape.from_wkb_hex(geom, self.alkis.crs)

        f = gws.lib.feature.Feature(
            uid=f'dprocon_{request_id}',
            attributes=atts,
            shape=shape,
        )

        f.apply_templates(self.templates, {'title': self.var('infoTitle')})

        return GetDataResponse(feature=f.props)
예제 #9
0
    def _get_features(self, req: gws.IWebRequest, p: GetFeaturesParams) -> t.List[gws.IFeature]:
        layer = req.require_layer(p.layerUid)
        bounds = gws.Bounds(
            crs=gws.gis.crs.get(p.crs) or layer.map.crs,
            extent=p.get('bbox') or layer.map.extent
        )

        found = layer.get_features(bounds, p.get('limit'))

        for f in found:
            f.transform_to(bounds.crs)
            f.apply_templates(subjects=['label', 'title'])
            f.apply_data_model()

        return found
예제 #10
0
    def api_find_fs(self, req: gws.IWebRequest,
                    p: GetFsParams) -> GetFsResponse:
        if not self.alkis:
            raise gws.base.web.error.NotFound()

        feature = self._find_alkis_feature(p)

        if not feature:
            raise gws.base.web.error.NotFound()

        project = req.require_project(p.projectUid)
        feature.transform_to(project.map.crs)

        f = feature.apply_templates(self.templates).props
        f.attributes = []

        return GetFsResponse(feature=f)
예제 #11
0
def _parse_header(req: gws.IWebRequest):
    h = req.header('Authorization')
    if not h:
        return

    a = h.strip().split()
    if len(a) != 2 or a[0].lower() != 'basic':
        return

    try:
        b = gws.to_str(base64.decodebytes(gws.to_bytes(a[1])))
    except ValueError:
        return

    c = b.split(':')
    if len(c) != 2:
        return

    return c
예제 #12
0
    def print(self, req: gws.IWebRequest,
              p: PrintParams) -> gws.base.printer.types.StatusResponse:
        """Print Flurstueck features"""

        project = req.require_project(p.projectUid)

        fp = p.findParams
        fp.projectUid = project.uid
        fp.localeUid = p.localeUid

        res = self._find(req, fp, self.limit)

        if not res.features:
            raise gws.base.web.error.NotFound()

        pp = p.printParams
        pp.projectUid = p.projectUid
        pp.localeUid = p.localeUid
        pp.templateUid = self.print_template.uid
        pp.sections = []

        for feature in res.features:
            if not feature.shape:
                gws.log.warn(f'feature {feature.uid!r} has no shape')
                continue
            center = feature.shape.centroid
            pp.sections.append(
                gws.base.printer.types.Section(
                    center=[center.x, center.y],
                    context=feature.template_context,
                    items=[
                        gws.base.printer.types.ItemFeatures(
                            type='features',
                            features=[feature],
                            style=p.highlightStyle,
                        )
                    ]))

        job = gws.base.printer.job.start(req, pp)
        return gws.base.printer.job.status(job)
예제 #13
0
    def _get_xyz(self, req: gws.IWebRequest, p: GetXyzParams) -> gws.BytesResponse:
        layer = req.require_layer(p.layerUid)
        content = None

        ts = gws.time_start(f'RENDER_XYZ layer={p.layerUid} xyz={p.x}/{p.y}/{p.z}')
        try:
            content = layer.render_xyz(p.x, p.y, p.z)
        except:
            gws.log.exception()
        gws.time_end(ts)

        # for public tiled layers, write tiles to the web cache
        # so they will be subsequently served directly by nginx

        if content and gws.is_public_object(layer) and layer.has_cache:
            path = gws.base.layer.layer_url_path(layer.uid, kind='tile')
            path = path.replace('{x}', str(p.x))
            path = path.replace('{y}', str(p.y))
            path = path.replace('{z}', str(p.z))
            gws.gis.cache.store_in_web_cache(path, content)

        return self._image_response(content)
예제 #14
0
    def _log_eigentuemer_access(self,
                                req: gws.IWebRequest,
                                p: FindFlurstueckParams,
                                is_ok,
                                total=0,
                                features=None):
        if not self.log_table:
            gws.log.debug('_log_eigentuemer_access', is_ok, 'no log table!')
            return

        has_relevant_params = any(
            p.get(s) for s in self._log_eigentuemer_access_params)

        if is_ok and not has_relevant_params:
            gws.log.debug('_log_eigentuemer_access', is_ok,
                          'no relevant params!')
            return

        fs_ids = ''
        if features:
            fs_ids = ','.join(f.uid for f in features)

        data = {
            'app_name': 'gws',
            'date_time': gws.lib.date.now_iso(),
            'ip': req.env('REMOTE_ADDR', ''),
            'login': req.user.uid,
            'user_name': req.user.display_name,
            'control_input': (p.controlInput or '').strip(),
            'control_result': 1 if is_ok else 0,
            'fs_count': total,
            'fs_ids': fs_ids
        }

        with self.provider.connection() as conn:
            conn.insert_one(self.log_table, 'id', data)

        gws.log.debug('_log_eigentuemer_access', is_ok, 'ok')
예제 #15
0
    def handle_request(self, req: gws.IWebRequest) -> gws.ContentResponse:
        rd = core.Request(req=req, project=None, service=self)

        if req.method == 'GET':
            return self.dispatch_request(
                rd, req.param('request', default='record'))

        # CSW should accept POST'ed xml, which can be wrapped in a SOAP envelope

        try:
            rd.xml_element = xml2.from_string(req.text)
        except xml2.Error:
            raise gws.base.web.error.BadRequest()

        if rd.xml_element.name.lower() == 'envelope':
            rd.xml_is_soap = True
            try:
                rd.xml_element = xml2.first(xml2.first('body'))
            except Exception:
                raise gws.base.web.error.BadRequest()

        return self.dispatch_request(
            rd, xml2.unqualify_name(rd.xml_element.name.lower()))
예제 #16
0
def _serve_path(root: gws.IRoot,
                req: gws.IWebRequest,
                p: GetAssetParams,
                as_attachment=False):
    spath = str(p.get('path') or '')
    if not spath:
        raise gws.base.web.error.NotFound()

    site_assets = req.site.assets_root

    project = None
    project_assets = None

    project_uid = p.get('projectUid')
    if project_uid:
        project = req.require_project(project_uid)
        project_assets = project.assets_root

    rpath = None

    if project_assets:
        rpath = _abs_path(spath, project_assets.dir)
    if not rpath and site_assets:
        rpath = _abs_path(spath, site_assets.dir)
    if not rpath:
        raise gws.base.web.error.NotFound()

    locale_uid = p.localeUid
    if project and locale_uid not in project.locale_uids:
        locale_uid = project.locale_uids[0]

    tpl = gws.base.template.create_from_path(root, rpath)

    if tpl:
        # give the template an empty response to manipulate (e.g. add 'location')
        res = gws.ContentResponse()
        context = {
            'project': project,
            'projects': _projects_for_user(root, req.user),
            'request': req,
            'user': req.user,
            'params': p,
            'response': res,
            'localeUid': locale_uid,
        }

        render_res = tpl.render(gws.TemplateRenderInput(context=context))

        if gws.is_empty(res):
            res = render_res

        return res

    mime = gws.lib.mime.for_path(rpath)

    if not _valid_mime_type(mime, project_assets, site_assets):
        gws.log.error(f'invalid mime path={rpath!r} mime={mime!r}')
        # NB: pretend the file doesn't exist
        raise gws.base.web.error.NotFound()

    gws.log.debug(f'serving {rpath!r} for {spath!r}')

    return gws.ContentResponse(mime=mime,
                               path=rpath,
                               as_attachment=as_attachment)
예제 #17
0
 def _get_legend(self, req: gws.IWebRequest, p: GetLegendParams) -> gws.BytesResponse:
     layer = req.require_layer(p.layerUid)
     content = gws.gis.legend.to_bytes(layer.render_legend_with_cache())
     return self._image_response(content)
예제 #18
0
 def describe_layer(self, req: gws.IWebRequest, p: DescribeLayerParams) -> DescribeLayerResponse:
     layer = req.require_layer(p.layerUid)
     return DescribeLayerResponse(description=layer.description)