2

For some reason, I try to use Flask as a proxy layer between client and server to control all requests sent to the geoserver.

The thing that I want to do is to send the GetMap request to the GeoServer through a Flask application to log some information and check some security matters and then allow the requests to reach GeoServer. Finally I need to display the images as tiles to help map to be rendered faster and more optimized.

On the client side, I used Leaflet as follows:

createWMSLayer(name: string): any {
    const wmsParams = new WMS(name);
    const url = `http://localhost:5000/geoservice/wms${createURLString(wmsParams)}`;
    var wmsLayer = new L.tileLayer.wms(url);
    wmsLayer.addTo(this.map);
}

On the server side, I used flask and OWSlib to check token and some other things:

from owslib.wms import WebMapService

geoserver_rest_endpoint = f'http://{GEOSERVER_HOST}:{GEOSERVER_PORT}/geoserver/{ws}/wms'

wms = WebMapService(geoserver_rest_endpoint, version='1.1.1')

response = wms.getmap(
    layers=[layer_name, ],
    styles='',
    bbox=(xmin, ymin, xmax, ymax),
    format='image/png',
    size=(256, 256),
    srs='EPSG:4326',
    time='2018-09-16',
    transparent=True)

return response.read()

The tiles are positioned successfully on map but the result is strange because the tiles are not being generated correctly. Here is the results.

What mistake am I making?

enter image description here

2
  • 1
    I think you are missing some steps from your question - are you making a tiled request to flask or trying to use it to take tiles from GeoServer and return a single large image to the client? Either way you need to add the code that calculates your bounding box and some example URLs
    – Ian Turton
    Commented Jun 11, 2021 at 9:41
  • @IanTurton I added more information considering my issue. I want to display GetMap response on map in terms of tiles using new L.tileLayer.wms(url)
    – ArashMad
    Commented Jun 11, 2021 at 16:49

1 Answer 1

1

Taking time, I could figure out the problem. It was due to setting wrong bounding box. I replaced it by one that comes from client. On client side, I made these changes:

const wmsParams = new WMS(name, true, 'image/png');
const url = `${environment.apiUrl}/geoservice/wms${createURLString(wmsParams)}`;
var wmsLayer = new L.tileLayer.wms(url);

in which, WMS is a class to create an object for WMS GetMap request:

export class WMS {
    public name: string;

    constructor(name: string, transparent: boolean, format: string) {
        this.name = name;
        this.transparent = transparent;
        this.format = format;
        this.token = getToken();
    }
}

In the Flask application, I removed OWSLib and re-wrote the code from the scratch as follow:

args = request.args

if not decode_token(args.get('token')):
    return Response(
        json.dumps({"msg": "Unauthorized User!"}),
        status=status.HTTP_403_FORBIDDEN,
        mimetype='application/json')

layer_name = args.get('name', type=str).strip()

wms_params = {}
for _key, _val in request.args.items():
    if _key == 'token':
        continue
    if _key == 'transparent':
        _val = 'true'
    if _key in ['width', 'height']:
        _val = int(_val)
    if _key == 'layers':
        _val = f'{workspace_name}:{layer_name}'

    wms_params[_key] = _val

geoserver_rest_endpoint = f'http://{GEOSERVER_HOST}:{GEOSERVER_PORT}/geoserver/{workspace_name}/wms'

form_data = urllib.parse.urlencode(wms_params)
request_headers = {
    "Content-Length": str(len(form_data)),
    "Content-Type": 'application/x-www-form-urlencoded'
}

r = requests.post(
    geoserver_rest_endpoint,
    data=urllib.parse.urlencode(wms_params),
    headers=request_headers,
    verify=False)

return Response(
    response=r._content,
    status=r.status_code)

Here is the results: enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.