Ejemplo n.º 1
0
def query_features(lang, layers, query):
    features = []
    max_features_pro_layer = int(10 / len(layers))
    terms = query.split()
    terms1 = ' & '.join([term + ('' if term.isdigit() else ':*')  for term in terms])
    if lang == 'fr' or lang == 'it':
       bodsearch = BodLayerFr
    else:
       bodsearch = BodLayerDe

    c.baseUrl = ''
    c.lang = lang
    c.path_url = ''

    for layer in layers:
        bodlayer = Session.query(bodsearch).get(layer)
        for model in models_from_name(layer):
            if hasattr(model, '__queryable_attributes__'):
                ftsFilter = 'to_tsvector(\'english\',' + ' || \' \' || '.join(["coalesce(%s::text,'') " % s for s in
                                                                   model.__queryable_attributes__]) + ") @@ to_tsquery('english','%s')" % terms1

                for feature in Session.query(model).filter(ftsFilter).limit(max_features_pro_layer).all():
                    feature.compute_attribute()
                    feature.compute_template(layer, bodlayer)

                    layername = _(layer)
                    html = '<b>%s </b><br>%s' % (layername[0:35]+'...' if len(layername) > 35 else layername,
                       feature.preview)
                    feature.attributes['html'] = html
                    feature.layer_id = layer
                    features.append(feature)
    return features
Ejemplo n.º 2
0
Archivo: wmts.py Proyecto: gjn/mf-chsdi
    def index(self, format='html'):
        """GET /wmts: GetCapabilities document"""

        response.headers['Content-Type'] = 'text/xml'
        response.headers['Pragma'] = 'public'
        response.headers['Expires'] = '0'
        response.headers['Cache-Control'] = 'no-cache'
        response.charset = 'utf-8'  


        http_host = request.environ.get("HTTP_HOST")
        request_uri = request.environ.get("REQUEST_URI", "")
        if request_uri.find("1.0.0"): # new bucket WMTS
            onlineressource = "%s://wmts.geo.admin.ch" % c.scheme
        else:
            onlineressource = "%s://api.geo.admin.ch/wmts" % c.scheme
        # for ssWMTS
        c.is_swisstopowmts = request.params.get('mode', '') == 'swisstopowmts' 
        if c.is_swisstopowmts:
            c.layers = Session.query(self.GetCap).filter_by(sswmts=True).all()
            onlineressource = "%s://wmts.swistopo.admin.ch" % c.scheme
            c.service_metadata = Session.query(self.ServiceMetadata).filter(self.ServiceMetadata.pk_map_name.like('%wmts-swisstopo%')).first()
        else:
            c.layers = Session.query(self.GetCap).all()
            c.service_metadata = Session.query(self.ServiceMetadata).filter(self.ServiceMetadata.pk_map_name.like('%wmts-bgdi%')).first()

        
        c.onlineressource = onlineressource
        c.themes = Session.query(self.GetCapThemes).all()
        c.lang = self.lang

        if c.layers is None or c.themes is None:
            abort(404)

        return render('/WMTSCapabilities.mako') 
Ejemplo n.º 3
0
 def decode(self, id=None):
     if id is None or id == 'robots.txt':
         abort(400, 'A short url is required')
     else:
         query = Session.query(ShortUrl)
         query = query.filter(ShortUrl.url_short == '' + id)
         for r in query:
             url = r.url
         redirect(url)
Ejemplo n.º 4
0
def shorten(myUrl):
    # Check that myUrl is not already in the database
    query1 = Session.query(ShortUrl)
    query1 = query1.filter(ShortUrl.url == myUrl)
    dontExist = True
    for r1 in query1:
        dontExist = False
        shorturl = r1.url_short
        break
        # The current time is hashed and then, only the seven first characters are used.
    if dontExist:
        try:
            shorturl = hashlib.md5(str(datetime.now())).hexdigest()[:8]
            shortUrlObject = ShortUrl(url_short=shorturl, url=myUrl)
            Session.add(shortUrlObject)
            Session.commit()
        except Exception, e:
            mail("*****@*****.**", "Error in ShortenerController", "Database insert error", "")
            raise Exception('Error by database insert in Shortener')
Ejemplo n.º 5
0
 def decode(self, id=None):
     url = None
     if id is None or id == 'robots.txt':
         abort(400, 'A short url is required')
     else:
         query = Session.query(ShortUrl)
         query = query.filter(ShortUrl.url_short == '' + id)
         for r in query:
             url = r.url
         if url is not None:
             redirect(url)
         abort(404, 'No long url correspond to given short url.')
Ejemplo n.º 6
0
 def layers(self):
     p = request.params.get("project") or "mf-chsdi"
     query = Session.query(self.BodLayer)
     query = query.filter(self.BodLayer.projekte.op("~")(p + "[,]?"))
     swissimage = [{"id": "ch.swisstopo.swissimage", "description": "Swissimage"}]
     pixelmap = [{"id": "ch.swisstopo.pixelkarte-farbe", "description": "Pixelmap Color"}]
     pixelmap_gray = [{"id": "ch.swisstopo.pixelkarte-grau", "description": "Pixelmap Gray"}]
     res = [r.json_layer() for r in query]
     res.extend(swissimage)
     res.extend(pixelmap)
     res.extend(pixelmap_gray)
     return {"results": res}
Ejemplo n.º 7
0
 def layers(self):
     p = request.params.get('project') or 'mf-chsdi'
     query = Session.query(self.BodLayer)
     query = query.filter(self.BodLayer.projekte.op('~')(p+'[,]?'))
     swissimage =  [{'id': 'ch.swisstopo.swissimage', 'description': 'Swissimage'}]
     pixelmap =  [{'id': 'ch.swisstopo.pixelkarte-farbe', 'description': 'Pixelmap Color'}]
     pixelmap_gray =  [{'id': 'ch.swisstopo.pixelkarte-grau', 'description': 'Pixelmap Gray'}]
     res = [r.json_layer() for r in query]
     res.extend(swissimage)
     res.extend(pixelmap)
     res.extend(pixelmap_gray)
     return {'results': res}
Ejemplo n.º 8
0
def get_features(layer, ids):
    features = []
    for model in models_from_name(layer):
        for fid in ids:
            if len(features) < MAX_FEATURES:
                try:
                    feature = Session.query(model).get(fid)
                    if feature:
                        features.append(feature)
                except exc.SQLAlchemyError:
                    pass
            else:
                break
    return features
Ejemplo n.º 9
0
    def datenstand(self, layer_id, datenstand):
        """
        if the value in bod.dataset.datenstand == TAG_DATENSTAND, return the most recent date of the data table,
        else return the regular value datenstand.
        """

        if datenstand == self.TAG_DATENSTAND:
            try:
                for model in models_from_name(layer_id):
                    modified = Session.query(func.max(model.bgdi_created))
                return modified.first()[0].strftime("%Y%m%d")
            except:
                return datenstand
        else:
            return datenstand
Ejemplo n.º 10
0
    def details(self, id=None):
        c.host = request.params.get('h', '')
        c.full = True
        c.hilight = ''
        c.layer = Session.query(self.BodLayer).get(id)
        if c.layer is None:
            abort(404)

        c.legend = Session.query(self.BodLayer).get(id)
        if c.legend is None:
            abort(404)

        c.legend.datenstand = self.datenstand(c.layer.bod_layer_id, c.legend.datenstand)

        if 'print' in request.params:
            return render('/bod-details-print.mako')
        else:
            if self.rawjson:
                output =  {}
                legend = {}
                for col in c.layer.__table__.columns:
                    output[col.name] = getattr(c.layer,col.name)
                for col in c.legend.__table__.columns:
                    legend[col.name] = getattr(c.legend,col.name)

                output['legend'] = legend
                output = simplejson.dumps(output)
            else:
                output = simplejson.dumps(render('/bod-details.mako'))
            cb_name = request.params.get('cb')
            if cb_name is not None:
                response.headers['Content-Type'] = 'text/javascript'
                return str(cb_name) + '(' + output + ');'
            else:
                response.headers['Content-Type'] = 'application/json'
                return output
Ejemplo n.º 11
0
    def details(self, id=None):
        c.host = request.params.get("h", "")
        c.full = True
        c.hilight = ""
        c.layer = Session.query(self.BodLayer).get(id)
        if c.layer is None:
            abort(404)

        c.legend = Session.query(self.BodLayer).get(id)
        if c.legend is None:
            abort(404)

        c.legend.datenstand = self.datenstand(c.layer.bod_layer_id, c.legend.datenstand)

        if "print" in request.params:
            return render("/bod-details-print.mako")
        else:
            if self.rawjson:
                output = {}
                legend = {}
                for col in c.layer.__table__.columns:
                    output[col.name] = getattr(c.layer, col.name)
                for col in c.legend.__table__.columns:
                    legend[col.name] = getattr(c.legend, col.name)

                output["legend"] = legend
                output = simplejson.dumps(output)
            else:
                output = simplejson.dumps(render("/bod-details.mako"))
            cb_name = request.params.get("cb")
            if cb_name is not None:
                response.headers["Content-Type"] = "text/javascript"
                return str(cb_name) + "(" + output + ");"
            else:
                response.headers["Content-Type"] = "application/json"
                return output
Ejemplo n.º 12
0
 def compute_template(self, layer_id, bodlayer):
     c.feature = self
     c.layer_bezeichnung = bodlayer.bezeichnung if hasattr(bodlayer, 'bezeichnung') else ''
     c.layer_datenherr = bodlayer.datenherr if hasattr(bodlayer, 'datenherr') else  ''
     c.layer_id = layer_id
     if bodlayer.datenstand == 'bgdi_created':
         for model in models_from_name(layer_id):
             modified = Session.query(func.max(model.bgdi_created))
         c.datenstand = modified.first()[0].strftime("%d.%m.%Y")
     else:
         c.datenstand = bodlayer.datenstand
     c.stable_id = c.feature.stable_id
     self.layer_id= layer_id
     c.html_type = 'full'
     self.html = render(self.__template__)
     c.html_type = 'preview'
     self.preview = render(self.__template__).strip()
Ejemplo n.º 13
0
    def search(self):
        q = request.params.get('query')
        if q is None:
            abort(400, "missing 'query' parameter")
        p = request.params.get('project') or 'mf-geoadmin2'
        # Filter by staging attribute

        query = Session.query(self.BodLayer).order_by(self.BodLayer.kurzbezeichnung).order_by(self.BodLayer.bezeichnung).order_by(self.BodLayer.geobasisdatensatz_name)
        
        if 'integration' in self.Geodata_staging:
            query = query.filter(or_(self.BodLayer.staging == 'integration', self.BodLayer.staging == 'prod'))
        elif 'prod' in self.Geodata_staging:
            query = query.filter(self.BodLayer.staging == 'prod')

        query = query.filter(self.BodLayer.volltextsuche.ilike('%' + q + '%')).filter(self.BodLayer.projekte.op('~')(p + '(,|\s|$)'))

        return {'results': [r.json(q, self.rawjson) for r in query]}
Ejemplo n.º 14
0
    def index(self):
            layers = []
            format = request.params.get('format','json')
            query = Session.query(self.BodGrid)

            for layer in query:
               layers.append(layer)
            c.layers = layers

            results = {'results': [l.toDict() for l in layers]}
            response.headers['Cache-Control'] = 'no-cache'
            if 'callback' in request.params:
                response.headers['Content-Type'] = 'text/javascript; charset=utf-8'
                return request.params['callback'] + '(' + json_dumps(results) + ');'
            else:
                response.headers['Content-Type'] = 'application/json'
                return json_dumps(results)
Ejemplo n.º 15
0
    def reversegeocoding(self):
        lon = request.params.get('easting')
        if lon is None:
            abort(400, "missing 'easting' parameter")
        try:
            lon = float(lon)
        except:
            abort(400, "parameter 'easting' is not a number")

        lat = request.params.get('northing')
        if lat is None:
            abort(400, "missing 'northing' parameter")
        try:
            lat = float(lat)
        except:
            abort(400, "parameter 'northing' is not a number")

        tolerance = request.params.get('tolerance')
        if tolerance is None:
            tolerance = 10
        try:
            tolerance = float(tolerance)
        except:
            abort(400, "parameter 'tolerance' is not a number")

        # search for everything except sn25 data (who did not have 'the_geom_poly' geom)
        gfilter_poly = SwissSearch.within_filter(lon, lat, tolerance=tolerance, column='the_geom_poly')

        # now search for sn25 data
        gfilter_point = SwissSearch.within_filter(lon, lat, tolerance=tolerance, column='the_geom_point')

        query = Session.query(SwissSearch)
        query = query.filter(or_(gfilter_poly, gfilter_point))

        # remove the translated results
        query = query.filter(SwissSearch.translated == False)

        if self.origins:
            query = query.filter(SwissSearch.origin.in_(self.origins))

        query = query.limit(MAX_FEATURES_REVERSEGEOCODING)
        if self.rawjson:
            return FeatureCollection(list(self.getRawFeatures(query)))
        else:
            return [f.json(rawjson=False, nogeom=self.no_geom) for f in query.all()]
Ejemplo n.º 16
0
    def search(self):
        q = request.params.get("query")
        if q is None:
            abort(400, "missing 'query' parameter")
        p = request.params.get("project") or "mf-geoadmin2"
        # Filter by staging attribute

        query = (
            Session.query(self.BodLayer)
            .order_by(self.BodLayer.kurzbezeichnung)
            .order_by(self.BodLayer.bezeichnung)
            .order_by(self.BodLayer.geobasisdatensatz_name)
        )

        if "test_integration" not in self.Geodata_staging:
            query = query.filter(self.BodLayer.staging == "prod")

        query = query.filter(self.BodLayer.volltextsuche.ilike("%" + q + "%")).filter(
            self.BodLayer.projekte.op("~")(p + "(,|\s|$)")
        )

        return {"results": [r.json(q, self.rawjson) for r in query]}
Ejemplo n.º 17
0
    def index(self):
            layers = []
            format = request.params.get('format','json')
            # any better way to detect layer group ?
            query = Session.query(self.klass).filter(self.klass.kurzbezeichnung != None).order_by(self.klass.kurzbezeichnung)

            if 'inspire_id' in request.params:
                inspire_id = request.params.get('inspire_id')
                query = query.filter(self.klass.inspire_id == inspire_id)
        
            for layer in query:
               layers.append(layer)
            c.layers = layers
                
            results = {'results': [l.toDict() for l in layers]}
            response.headers['Cache-Control'] = 'no-cache'            
            if 'callback' in request.params:
                response.headers['Content-Type'] = 'text/javascript; charset=utf-8'
                return request.params['callback'] + '(' + json_dumps(results) + ');'
            else:
                response.headers['Content-Type'] = 'application/json'
                return json_dumps(results)
Ejemplo n.º 18
0
    def index(self):

        lon = request.params.get('easting')
        if lon is None:
            abort(400, "missing 'easting' parameter")
        try:
            lon = float(lon)
        except:
            abort(400, "parameter 'easting' is not a number")

        lat = request.params.get('northing')
        if lat is None:
            abort(400, "missing 'northing' parameter")
        try:
            lat = float(lat)
        except:
            abort(400, "parameter 'northing' is not a number")
        
        # Manage scale dependent view
        mymodel = Zeitreihen_Metadata_15
        tolerance = 500
        if c.scale > 50005 and c.scale <= 100005:
            mymodel =  Zeitreihen_Metadata_20
            tolerance = c.scale/100
        if c.scale > 25005 and c.scale <= 50005:
            mymodel =  Zeitreihen_Metadata_21
            tolerance = c.scale/100
        if c.scale > 1 and c.scale <= 25005:
            mymodel =  Zeitreihen_Metadata_22
            tolerance = c.scale/100


        query = Session.query(mymodel)
        spatialFilter = mymodel.within_filter(lon, lat, tolerance=tolerance, column='the_geom')
        query = query.filter(spatialFilter)

        #Default timestamp
        timestamps = ['1938','1950','1960','1970','1980','1990','2000','2010']
        counter = 0
        minYear = 2020
        minTimestamp = 1844

        # Fill the array in time descending direction
        for f in query.all():
            if counter == 0:
                timestamps = []
                counter = 1
            for x in f.release_year:
                if int(x) < minYear and int(x) >= minTimestamp:
                    timestamps.append(str(x))
                    minYear = x
                if int(x) < minTimestamp:
                    timestamps.append(str(minTimestamp))
        # Remove duplicate items
        timestamps = list(set(timestamps))

        counter = 0
        for value in timestamps:
            # TODO: 1231 will be modified if we recreate tiles for some layers
            day = '1231'
            # Example
            if timestamps[counter] == '1938':
                day = '1231'
            timestamps[counter] = int(str(str(timestamps[counter])+day))
            counter = counter+1

        timestamps.sort()

        counter = 0
        for value in timestamps:
            timestamps[counter] = str(timestamps[counter])
            counter = counter+1

        myjson = json_dumps(timestamps)

        response.headers['Cache-Control'] = 'no-cache'
        if 'cb' in request.params:
            response.headers['Content-Type'] = 'text/javascript; charset=utf-8'
            return request.params['cb'] + '(' + myjson + ');'
        else:
            response.headers['Content-Type'] = 'application/json'
            return myjson
Ejemplo n.º 19
0
    def index(self):
    # if a list of layers was provided the first layer in the
    # list will be taken
        layer = c.layers[0]

        features = []
        urlContent = request.url.split("?")
        id = urlContent[0].split("/")[len(urlContent[0].split("/")) - 1]

        # extended infos
        if '.html' in id:
            id = id.strip('.html')
            ids = id.split(',')
            if len(ids) > 1:
                innerHtml = ''
                for model in models_from_name(layer):
                    items_nb = len(ids)
                    item_count = 0
                    for fid in ids:
                        feature = Session.query(model).get(fid)
                        bodlayer = Session.query(self.bodsearch).get(layer)
                        if feature is not None:
                            feature.compute_template(layer, bodlayer)
                            feature.compute_attribute()
                            c.html_type = 'extended'
                            c.feature = feature
                            item_count = item_count + 1
                            if items_nb == item_count:
                                c.last = True
                            else:
                                c.last = False
                            innerHtml = innerHtml + render(feature.__template__)
                        else:
                            abort(404, 'One of the id you provided is not valid')
                feature.html = innerHtml
                body_tooltip = render('/tooltips/extended_tooltips.mako')
                feature.html = body_tooltip.encode('utf8')
            else:
                c.last = True
                for model in models_from_name(layer):
                    if len(features) < MAX_FEATURES:
                        feature = Session.query(model).get(id)
                        bodlayer = Session.query(self.bodsearch).get(layer)
       
                        if feature is not None:
                            properties = {}
                            feature.compute_template(layer, bodlayer)
                            feature.compute_attribute()
                            properties = feature.attributes
                            c.html_type = 'extended'
                            feature.html = render(feature.__template__)
                            body_tooltip = render('/tooltips/extended_tooltips.mako')
                            feature.html = body_tooltip.encode('utf8')
    
    
                            if (self.no_geom):
                                features.append(Feature(id=feature.id,
                                                    bbox=feature.geometry.bounds,
                                                    properties=feature.attributes))
                            else:
                                features.append(feature)
                            response.headers['Content-Type'] = 'text/html'
                            return feature.html
                        else:
                            abort(404, 'One of the id you provided is not valid')
                    else:
                        break

            response.headers['Content-Type'] = 'text/html'
            return feature.html
        # not extended info
        for model in models_from_name(layer):
            if len(features) < MAX_FEATURES:
                feature = Session.query(model).get(id)
                if feature:
                    properties = {}
                    if self.format =='html':
                        bodlayer = Session.query(self.bodsearch).get(layer)
                        feature.compute_template(layer, bodlayer)
                        c.html_type = 'full'
                        feature.html = render(feature.__template__)
                        properties['html'] = feature.html
                    else:
                        feature.compute_attribute()
                        properties = feature.attributes
                    if (self.no_geom):
                        features.append(Feature(id=feature.id,
                                                bbox=feature.geometry.bounds,
                                                properties=properties))
                    else:
                        features.append(feature)

            else:
                break

        output = simplejson.dumps(FeatureCollection(features), cls=MapFishEncoder)
        cb_name = request.params.get('cb')

        if cb_name is not None:
            response.headers['Content-Type'] = 'text/javascript'
            return str(cb_name) + '(' + output + ');'
        else:
            response.headers['Content-Type'] = 'application/json'
            return output
Ejemplo n.º 20
0
    def search(self):
        # optional paramater "extent"
        # Get current map extent or calculate a 'sensitive' default based on available information  (scale !) 
        extent = request.params.get('extent')
        if extent is not None:
            try:
                extent = map(float, extent.split(','))
            except ValueError:
                abort(400, "Parameter 'extent' is invalid. Use extent=656430,254350,657930,25585 for instance.")
        else:
            resolution = 1 / ((1 / (c.scale > 0 or 1000.0)) * 39.3701 * 72)
            meters = 300 * resolution
            cx, cy = c.bbox[0:2]
            extent = (cx - meters, cy - meters, cx + meters, cy + meters)

        c.extent = Polygon(((extent[0], extent[1]), (extent[0], extent[3]),
                                (extent[2], extent[3]), (extent[2], extent[1]),
                                (extent[0], extent[1])))

        c.baseUrl = request.params.get('baseUrl')  or ''

        # Request features
        features = []
        layerCounter = 0
        for layer_name in c.layers:
            layerCounter = layerCounter + 1
            for model in models_from_name(layer_name):
                geom_filter = model.bbox_filter(c.scale, c.bbox)
                if c.timestamps is not None:
                    time_filter = model.time_filter(c.timestamps[layerCounter-1])
                else:
                    time_filter = None
                if geom_filter is not None:
                    query = Session.query(model).filter(geom_filter)
                    if time_filter is not None:
                        query = query.filter(time_filter)
                    bodlayer = Session.query(self.bodsearch).get(layer_name)

                    for feature in query.limit(MAX_FEATURES).all():
                        properties = {}
                        feature.compute_template(layer_name, bodlayer)
                        if self.format == 'raw':
                            feature.compute_attribute()
                            properties = feature.attributes
                        properties['html'] = feature.html
                        properties['layer_id'] = feature.layer_id
                        properties['preview'] = feature.preview
                        if (self.no_geom or layer_name == 'ch.kantone.cadastralwebmap-farbe') and 'print' not in request.params:
                            features.append(Feature(id=feature.id,
                                                    bbox=feature.geometry.bounds,
                                                    properties=properties))
                        else:
                            features.append(feature)

        # Send features back 
        if 'print' in request.params:
            c.features = features
            return render('/tooltips/_print.mako')
        else:
            output = simplejson.dumps(FeatureCollection(features), cls=MapFishEncoder)
            cb_name = request.params.get('cb')
            if cb_name is not None:
                response.headers['Content-Type'] = 'text/javascript'
                return str(cb_name) + '(' + output + ');'
            else:
                response.headers['Content-Type'] = 'application/json'
                return output
Ejemplo n.º 21
0
    def index(self):
        q = request.params.get('query')
        egid = request.params.get('egid')
        if q is None:
            if egid is None:
                abort(400, "missing 'query' or 'egid' parameter")

        # layers are used for the advanced search
        layers = request.params.get('layers')

        if layers is not None and len(layers) > 0:
            layers = layers.split(',')
        else:
            layers = None

        bfsnr = request.params.get('bfsnr')
        if bfsnr is None:
            bfsnr = request.params.get('citynr')
        onlyOneTerm = False

        if egid is not None:
            query = Session.query(SwissSearch).filter(SwissSearch.egid == '' + egid)
            ftsOrderBy = "egid"
        else:
            # order addresses by 1/gid instead of similarity, addresses (gid) are sorted in import table by house number, street etc.
            # otherwise limit 20 is truncating important results (e.g. Kirchweg Glis -> there is no kirchweg 11 or kirchweg 15)
            ftsOrderBy = "rank asc, CASE WHEN origin = 'address' THEN 1/gid::float WHEN origin = 'parcel' THEN 1/SUBSTRING(name FROM '([0-9]+)')::float ELSE similarity(search_name,'%(query)s') END desc" % {'query': q.replace("'","''").replace('"','\"') }            
            terms = q.split()
            if len(terms) == 1:
               onlyOneTerm = True
            terms1 = ' & '.join([term + ('' if term.isdigit() else ':*')  for term in terms])
            tsvector = 'to_tsvector(\'english\',search_name)'
            terms1 =  terms1.replace("'", "''").replace('"', '\"')
            ftsFilter = "%(tsvector)s @@ to_tsquery('english', remove_accents('%(terms1)s'))" %{'tsvector': tsvector, 'terms1': terms1}
            query = Session.query(SwissSearch).filter(ftsFilter)

            # Try to optimize search if initial search doesn't return something. It results in an additional query
            # Remove all numbers with more than 3 characters (in order to solve the postcode issue)
            if query.count() == 0:
               terms2 = ' '.join([('' if term.isdigit() and len(term) > 3 else term+('' if term.isdigit() else ':*'))  for term in terms])
               terms2 = terms2.split()
               if len(terms2) == 1:
                  onlyOneTerm = True
               terms2 = ' & '.join([term for term in terms2])
               terms2 =  terms2.replace("'", "''").replace('"', '\"')
               ftsFilter = "%(tsvector)s @@ to_tsquery('english', remove_accents('%(terms2)s'))" %{'tsvector': tsvector, 'terms2': terms2}
               query = Session.query(SwissSearch).filter(ftsFilter)

            # Remove all strings starting with a number
            if query.count() == 0:
               terms3 = ' '.join([('' if term[0].isdigit() else term+('' if term.isdigit() else ':*'))  for term in terms])
               terms3 = terms3.split()
               if len(terms3) == 1:
                  onlyOneTerm = True
               terms3 = ' & '.join([term for term in terms3])
               terms3 =  terms3.replace("'", "''").replace('"', '\"')
               ftsFilter = "%(tsvector)s @@ to_tsquery('english', remove_accents('%(terms3)s'))" %{'tsvector': tsvector, 'terms3': terms3}
               query = Session.query(SwissSearch).filter(ftsFilter)

        # If only one search term is used, this can't be a parcel or an address
        if onlyOneTerm:
            query = query.filter(SwissSearch.origin  != 'parcel')

        # FIXME Address search is only for some allowed referers (see list in production.ini.in)
        # For "awk.ch", see email from lttsb from 18.nov. 2011
        # cadastre.ch see ticket #3695
        # rollstuhlparkplatz.ch see ticket #3846 
        referer = request.headers.get('referer', '')
        allowed_referers = config['address_search_referers'].split(',')
        if not any([ref in referer  for ref in allowed_referers]):
            if not self.no_geom:
               self.origins = [o for o in self.origins if o != 'address']
        
        query = query.filter(SwissSearch.origin.in_(self.origins))

        if bfsnr is not None:
            query = query.filter(SwissSearch.bfsnr == '' + bfsnr)
       
        maxFeaturesGeocoding = MAX_FEATURES_GEOCODING
 
        if layers:
           maxFeaturesGeocoding = MAX_FEATURES_GEOCODING - 10
           features = list(query_features(self.lang, layers, q))
           allfeatures = list(self.getLayerFeatures(features))

        query = query.order_by(ftsOrderBy).limit(maxFeaturesGeocoding)

        if self.rawjson:
            if layers:
                return FeatureCollection(allfeatures.append(self.getRawFeatures(query)))
            else:
                return FeatureCollection(list(self.getRawFeatures(query)))
        else:
            # Put in the good order...
            allfeatures = query.all()
            if layers:
                allfeatures += features
            return {'results': [f.json(rawjson=False, nogeom=self.no_geom) for f in allfeatures]}
Ejemplo n.º 22
0
    def index(self, id=None):

##----------------------------------------Session----------------------------------------##     	
    	  # Define which view are taken into account
        if self.mode in ['all','legend','bodsearch','preview','mobile']:
            query = Session.query(self.BodLayer)
            # Global variable defined in the config files
            Geodata_staging  = config['geodata_staging'].split(',')
        # Query only view_bod_wmts_getcapabilities_{lang}
        elif self.mode == 'wmts':
            query = Session.query(self.GetCap)
            self.BodLayer = self.GetCap
            # random variable so that no filter is applied 
            Geodata_staging = ['geodata_staging']
        else:
            abort(400, 'The parameter provided for mode is not valid') 
            
##----------------------------------------Properties----------------------------------------##    	
        # Per default all the properties are returned
        properties = request.params.get('properties','all')
        if properties == 'all':
            # Create a list with all the properties 
            properties = []
            # Create a list with all the properties of the selected table(s)
            for key in self.map_properties.keys():
                # Populate the list of the properties with all the available keys
                properties.append(key)
        else:
            properties = properties.split(',')
            # Check if the property exists
            for prop in properties:
                if prop not in self.map_properties.keys():
                    abort(400, 'The property(-ies) you provided is not valid')
        if not isinstance(properties,list):
            abort(400, 'An error occured while parsing the properties')             

##----------------------------------------Project----------------------------------------##            
        # Per default the project api is selected
        if self.mode == 'legend':
           project = ['all']
        else:
           project = request.params.get('project','api')
           project = project.split(',')
        if not isinstance(project,list):
            abort(400, 'An error occured while parsing the projects')           

##----------------------------------------Layer_id----------------------------------------##
        if id is None:        
            # Per default all layers are taken into account
            layer_id = request.params.get('layer','all')
            layer_id = layer_id.split(',')
            if not isinstance(layer_id,list):
                abort(400, 'An error occured while parsing the layer Id(s)')
        else:
            layer_id = id
            layer_id = layer_id.split(',')
            if not isinstance(layer_id,list):
                abort(400, 'An error occured while parsing the layer Id(s)')        

##----------------------------------------SecureWMTS----------------------------------------##
        # This parameter is only used in mode = wmts

##----------------------------------------QueryString----------------------------------------##                 
        # Per default no query string are applied 
        query_string = request.params.get('query') 

##----------------------------------------Filters----------------------------------------##    
        # Filter by staging attribute
        # If one if these 3 layers are in the list do not filter by staging mode 
        if 'ch.swisstopo.pixelkarte-farbe' in layer_id or 'ch.swisstopo.pixelkarte-grau' in layer_id or 'ch.swisstopo.tml3d-hintergrund-karte' in layer_id and self.mode == 'legend':
            pass
        elif self.mode in ['all','legend','bodsearch','preview','mobile']:
            if 'integration' in Geodata_staging:
                query = query.filter(or_(self.BodLayer.staging == 'integration', self.BodLayer.staging == 'prod'))
            elif 'prod' in Geodata_staging:
                query = query.filter(self.BodLayer.staging == 'prod')
        
        if self.mode in ['bodsearch']:
            query = query.filter(self.BodLayer.bodsearch == 'true')
             
        # Filter by layer_id
        if layer_id[0] != 'all':
            list_layers = []
            for l_id in layer_id:
                list_layers.append(self.BodLayer.bod_layer_id == l_id)
            query = query.filter(or_(*list_layers))

        # Filter by project
        if project[0] != 'all':
            list_projects = []
            for proj in project:
                 list_projects.append(self.BodLayer.projekte.ilike('%%%s%%' % proj))
            query = query.filter(or_(*list_projects))

        # Filter by query string
        if query_string is not None:
            columns = []
            # Iterate on the properties we are intrested in
            for prop in properties:
                columns.append(column_from_name(prop, self.map_properties).ilike('%%%s%%' % query_string))
            # Full text search
            query = query.filter(or_(*columns))
        
##----------------------------------------ResultsPreparation----------------------------------------##           
                         
        if self.mode == 'bodsearch':
            if query_string is None:
                abort(400, 'Please provide a query parameter')
            # Order the results
            query = query.order_by(self.BodLayer.kurzbezeichnung).order_by(self.BodLayer.bezeichnung).order_by(self.BodLayer.geobasisdatensatz_name)
            results = [r.json(query_string) for r in query]    
        elif self.mode == 'legend':
            c.host = request.params.get('h', '%s://api.geo.admin.ch' % c.scheme)
            c.full = True
            c.hilight = ''
            for r in query:
                c.layer = r
                c.legend = r
            # If value in bod.dataset.datenstand == bgdi_created, return the most recent date of the data table
            if c.legend.datenstand == 'bgdi_created':
                for model in models_from_name(c.layer.bod_layer_id):
                    modified = Session.query(func.max(model.bgdi_created))
                c.legend.datenstand = modified.first()[0].strftime("%Y%m%d")
        elif self.mode == 'mobile':
            results = [r.json(query_string) for r in query]
        elif self.mode == 'wmts':
            c.layers = query
            c.themes = Session.query(self.GetCapThemes).all() 
            # Per default the parameter secure wmts is set to false
            c.is_swisstopowmts = False 
            c.service_metadata = Session.query(self.ServiceMetadata).filter(self.ServiceMetadata.pk_map_name.like('%wmts-bgdi%')).first()
            request_uri = request.environ.get("REQUEST_URI", "")
            if request_uri.find("1.0.0"): # new bucket WMTS
                c.onlineressource = "%s://wmts.geo.admin.ch" % c.scheme
            else:
                c.onlineressource = "%s://api.geo.admin.ch/wmts" % c.scheme
        elif self.mode == 'all':
            results = [q.layers_results(properties) for q in query]
        elif self.mode == 'preview':
            result = [q.layers_results(['bod_layer_id']) for q in query]
        
##----------------------------------------Results----------------------------------------##
        cb_name = request.params.get('cb')
        print_legend = request.params.get('print', False)
        #self.format = request.params.get('format','json')

        if self.mode == 'bodsearch' or self.mode == 'mobile':    
            if cb_name is not None:
                response.headers['Content-Type'] = 'text/javascript'
                results = simplejson.dumps({"results": results})
                return str(cb_name) + '(' + results + ');' 
            else:
                response.headers['Content-Type'] = 'application/json'
                return simplejson.dumps({'results': results})        
        elif self.mode == 'legend':
            # Query only one layer at a time in legend mode
            if len(layer_id) != 1 or layer_id[0] == 'all':
                abort(400, "Please provide only one layer at a time")
            if not hasattr(c, 'layer'):
                abort(400, "The parameters you provided didn't return any layer")
            if print_legend == "true":
                return render('/bod-details-print.mako')
            else:
                response.headers['Content-Type'] = 'text/javascript'
                results = simplejson.dumps(render('/bod-details.mako'))
                if cb_name is not None:
                    return str(cb_name) + '(' + results + ');'
                else:
                    return results
        elif self.mode == 'wmts':
            response.headers['Content-Type'] = 'text/xml'
            response.headers['Pragma'] = 'public'
            response.headers['Expires'] = '0'
            response.headers['Cache-Control'] = 'no-cache'
            response.charset = 'utf-8'
            return render('/WMTSCapabilities.mako')
        elif self.mode == 'all':
            if cb_name is not None:
                response.headers['Content-Type'] = 'text/javascript'
                results = simplejson.dumps({"results": results})
                return str(cb_name) + '(' + results + ');'
            else:
                response.headers['Content-Type'] = 'application/json'             
                return simplejson.dumps({'results': results})
        elif self.mode == 'preview':
            c.layers = []
            for object in result:
                for id,bodLayerId in object.iteritems():
                    if bodLayerId not in c.layers:
                       c.layers.append(bodLayerId)
            response.headers['Content-Type'] = mimetypes.types_map['.html']
            response.charset = 'utf8'
            map_width = request.params.get('width',250)
            c.map_width = map_width
            return render('/layersPreview.mako')