Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metwork 1.0: marpserverapi failed on WFS GetFeature request with filter on geometries #12

Closed
dearith opened this issue Dec 18, 2020 · 4 comments · Fixed by #14
Closed

Comments

@dearith
Copy link
Contributor

dearith commented Dec 18, 2020

Since Metwork 1.0, the OGC WFS GetFeature request failed when request contains filter on geometries:

geos_ts_c.cpp:422: void GEOSFree_r(GEOSContextHandle_t, void*): Assertion0 != extHandle' failed.`

It fails on lib.mapserverapi_invoke call in /opt/metwork-mfext-1.0/opt/python3_mapserverapi/lib/python3.7/site-packages/mapserverapi/lib.py

   @staticmethod
    def invoke(mapfile_content, query_string):
        MapserverApi.__make_instance()
        lib = MapserverApi.__lib
        with MapserverApiContext(lib):
            tmp_body = c_void_p()
            tmp_content_type = c_char_p()
            tmp_body_length = c_ulong()
            res = lib.mapserverapi_invoke(six.b(mapfile_content),
                                          six.b(query_string),
                                          byref(tmp_body),
                                          byref(tmp_content_type),
                                          byref(tmp_body_length))
...

To reproduce the issue you can use the data you are using in the mapserverapi tests with the same test.map file : just add tests with the following WFS request :

// Set a GetFeature WFS query on 'land' layer with geometry intersection.
 gchar *query_string_wfs = "version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land&filter=<Filter><Intersects><PropertyName>wkb_geometry</PropertyName><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>45.8362361184359 0.439239133054321 46.231579556351 2.99579336490519 46.073442181185 5.81590988869945 45.4211255086251 5.67753968542917 46.0207297227963 7.43681798415129 45.6583315713742 7.98370973993382 43.9188204445478 7.48953044253997 43.7804502412775 6.19148615471878 43.1479007406134 6.17830804012161 43.0622429957318 4.95933243988344 43.391695860661 3.62175380827074 43.3851068033624 2.20510648907502 43.9451766737421 1.07178863371845 44.7292744922737 0.538074992533092 45.2300428469662 0.22838929949961 45.8362361184359 0.439239133054321</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></Intersects></Filter>";

Notice the following request, without filter, works (I think because there is no geometrie to compute, so geos is not called):
gchar *query_string_wfs = "version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land";

I have built a test case in C, based and similar to your mapservserapi tests.

Here is my C code:

#include <mapserverapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>

int main(void) {

    FILE *f = fopen("./resource/files/test.map", "rb");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET);  /* same as rewind(f); */
    gchar *mapfile_content = malloc(fsize + 1);
    fread(mapfile_content, 1, fsize, f);
    fclose(f);

    mapfile_content[fsize] = 0;

    g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG,  g_log_default_handler, NULL);

    // Init mapserver
    mapserverapi_init();

    g_setenv("REQUEST_METHOD", "GET", TRUE);


    // Set a GetFeature WFS query on 'land' layer with geometry intersection.
    gchar *query_string_wfs = "version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land&filter=<Filter><Intersects><PropertyName>wkb_geometry</PropertyName><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>45.8362361184359 0.439239133054321 46.231579556351 2.99579336490519 46.073442181185 5.81590988869945 45.4211255086251 5.67753968542917 46.0207297227963 7.43681798415129 45.6583315713742 7.98370973993382 43.9188204445478 7.48953044253997 43.7804502412775 6.19148615471878 43.1479007406134 6.17830804012161 43.0622429957318 4.95933243988344 43.391695860661 3.62175380827074 43.3851068033624 2.20510648907502 43.9451766737421 1.07178863371845 44.7292744922737 0.538074992533092 45.2300428469662 0.22838929949961 45.8362361184359 0.439239133054321</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></Intersects></Filter>";
    // gchar *query_string_wfs = "version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land";

    void *body;
    gchar *content_type = NULL;
    gsize body_length;
    int i = 0;

    gboolean b = mapserverapi_invoke(mapfile_content, query_string_wfs, &body, &content_type, &body_length);

    if (b == TRUE) {
        // you have the full body (WFS XML response in this example) in body variable (this buffer is managed by the library, don't free it by yourself !)
        // you have the body length in body_length variable.
        // you have the content_type of the body in content_type variable (you have to free it after use).

        // Write the WFS response into a file
        FILE *fout = fopen("result_wfs.xml", "w");
        fprintf(fout,"%s", body);
        fclose(fout);

        g_free(content_type);
    }

    // Set a GetMap WMS query on 'ocean' layer
    gchar *query_string_wms = "LAYERS=ocean&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_xml&SRS=EPSG%3A4326&BBOX=-180.0,-90.0,180.0,90.0&WIDTH=500&HEIGHT=250";

    b = mapserverapi_invoke(mapfile_content, query_string_wms, &body, &content_type, &body_length);

    if (b == TRUE) {
        // you have the full body (PNG image in this example) in body variable (this buffer is managed by the library, don't free it by yourself !)
        // you have the body length in body_length variable.
        // you have the content_type of the body in content_type variable (you have to free it after use).

        // Write the WMS response into a file
        FILE *fout = fopen("result_wms.png", "wb");
        fwrite(body, body_length, 1, fout);
        fclose(fout);

        g_free(content_type);
        }

    // Release mapserver
    mapserverapi_destroy();
}

Here is my mapfile :

MAP
    IMAGETYPE png
    SIZE 500 300
    UNITS DD
    EXTENT -180 -90 180 90
    WEB
        IMAGEPATH "/tmp/"
        METADATA
            "wms_title"           "WMS Demo Server"
            "wms_onlineresource"  "http://demo.mapserver.org/cgi-bin/mapserv?"
            "wms_srs"             "EPSG:4326"
            "ows_enable_request"  "*"
            'wfs_onlineresource' 'https://demo.mapserver.org/cgi-bin/mapserv/wfs?'
            'ows_enable_request' '*'
            'wfs_enable_request' '*'
        END
    END
    PROJECTION
        "init=epsg:4326"
    END

    LAYER
        NAME 'land'
        TYPE POLYGON
        STATUS ON
        #CONNECTIONTYPE OGR
        # A full (absolute) path is required for the CONNECTION parameter, for these virtual layers.
        #CONNECTION "/vsizip//home/dearith10/metgateswim/mfdata/wfsingestion/test/resource/files/ne_110m_land.zip"
        PROJECTION
            'init=epsg:4326'
        END
        DATA "/home/dearith10/metgateswim/mfdata/wfsingestion/test/resource/files/ne_110m_land"
        CLASS
            NAME "ne_110m_land"
            STYLE
                COLOR 238 236 223
                OUTLINECOLOR 255 255 0
                WIDTH 1.5
            END
        END
    END

    LAYER
        NAME 'ocean'
        TYPE POLYGON
        #CONNECTIONTYPE OGR
        # A full (absolute) path is required for the CONNECTION parameter, for these virtual layers.
        #CONNECTION "/vsizip//home/dearith10/metgateswim/mfdata/wfsingestion/test/resource/files/ne_110m_ocean.zip"
        STATUS ON
        PROJECTION
            'init=epsg:4326'
        END
        DATA "/home/dearith10/metgateswim/mfdata/wfsingestion/test/resource/files/ne_110m_ocean"
        CLASS
            NAME "ne_110m_ocean"
            STYLE
                COLOR 198 226 242
            END
        END
    END

END

The same tests with filter works with Metwork 0.9 (I notice the geos and mapserver versions have been upgraded in Metwork 1.0).

Notice the same request works with a mapserv command line (either with Metwork 1.0 or Metwork 0.9):

Metwork 1.0 :

 which mapserv
/opt/metwork-mfext-1.0/opt/mapserver/bin/mapserv

mapserv "QUERY_STRING=map=/home/dearith/metgateswim/mfdata/wfsingestion/test/resource/files/test.map&version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land&filter=<Filter><Intersects><PropertyName>wkb_geometry</PropertyName><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>45.8362361184359 0.439239133054321 46.231579556351 2.99579336490519 46.073442181185 5.81590988869945 45.4211255086251 5.67753968542917 46.0207297227963 7.43681798415129 45.6583315713742 7.98370973993382 43.9188204445478 7.48953044253997 43.7804502412775 6.19148615471878 43.1479007406134 6.17830804012161 43.0622429957318 4.95933243988344 43.391695860661 3.62175380827074 43.3851068033624 2.20510648907502 43.9451766737421 1.07178863371845 44.7292744922737 0.538074992533092 45.2300428469662 0.22838929949961 45.8362361184359 0.439239133054321</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></Intersects></Filter>"

It works.

Metwork 0.9 :

 which mapserv
/opt/metwork-mfext-0.9/opt/mapserver/bin/mapserv

mapserv "QUERY_STRING=map=/home/dearith/metgateswim/mfdata/wfsingestion/test/resource/files/test.map&version=2.0.0&SERVICE=WFS&REQUEST=GetFeature&typename=land&filter=<Filter><Intersects><PropertyName>wkb_geometry</PropertyName><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList>45.8362361184359 0.439239133054321 46.231579556351 2.99579336490519 46.073442181185 5.81590988869945 45.4211255086251 5.67753968542917 46.0207297227963 7.43681798415129 45.6583315713742 7.98370973993382 43.9188204445478 7.48953044253997 43.7804502412775 6.19148615471878 43.1479007406134 6.17830804012161 43.0622429957318 4.95933243988344 43.391695860661 3.62175380827074 43.3851068033624 2.20510648907502 43.9451766737421 1.07178863371845 44.7292744922737 0.538074992533092 45.2300428469662 0.22838929949961 45.8362361184359 0.439239133054321</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></Intersects></Filter>"

It works.

@thebaptiste
Copy link
Contributor

thebaptiste commented Dec 18, 2020

Sorry, but most of the team is in holidays. We probably won't be able to answer this (possibly difficult) issue until January.

@thebaptiste
Copy link
Contributor

The problem is identified and will be soon fixed.
A workaround is to temporarly unset TMPDIR when using mapserverapi (if it does not bring other problem)

@thebaptiste
Copy link
Contributor

A new release (1.0.1) of the mapserver addon is available.
Please check the problem is solved.
For the record, nothing to do with mapserver or geos upgrades, just a bug in mapserverapi when env variable TMPDIR is set...

@dearith
Copy link
Contributor Author

dearith commented Jan 4, 2021

I have upgraded the new version. It works. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants