0

I use Mapserver with the Leaflet JS library and I want to display some attributes informations of a raster file by clicking on the map.
Therefore I use the GetFeatureInfo WMS request in order to return these informations.
I managed to get the infos with the text/html format but I'd like to get a JSON response back in my browser, e.g :

{
    "value": 14.5, // I must precise I use GetFeatureInfo on a raster and the value result corresponds to the value of the pixel 
}

BELOW ARE THE UPDATES :

So I changed the wms_get_feature_info_formalist in the METADATA bloc of my mapfile :

"wms_getfeatureinfo_formatlist" "application/json"

Then, I edited my template as following to return the value of the pixel :

<!-- MapServer Template -->
{
    "value": [value_0] // [value_0] allow the user to get the value of a pixel
}

I edited the mapfile with the OUTPUT format parameter in order to use the JSON format :

OUTPUTFORMAT
  NAME "json"
  MIMETYPE "application/json"
  DRIVER "TEMPLATE"
  FORMATOPTION "FILE=template.js"
END

And as it is written in the docs, I set :

TEMPLATE "EMPTY"

My GetFeatureInfo request is the one (see "application/json" specified in the INFO_FORMAT parameter)

http://IP/cgi-bin/mapserv?map=/var/www/html/mapfiles/test1.map&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&BBOX=465348.6282001531,5431156.607774916,697564.3201305186,5503160.28841955&SRS=EPSG:3857&WIDTH=1519&HEIGHT=471&LAYERS=layer1&STYLES=&FORMAT=image/png&TRANSPARENT=true&QUERY_LAYERS=layer1&INFO_FORMAT=application/json&X=766&Y=261

But when I try the GetFeatureInfo request, my browser returns a JSON response but with the following error message :

SyntaxError: JSON.parse: unexpected character at line 2 column 11 of the JSON data

It seems the [value_0] is not recognized in JSON whereas it works well with the text/html format..
How could I do to make it work ?
I'm really stuck and any help would be greatly appreciated !

8
  • Your template seems too simple. Add add least the curly brackets. Have you seen the GeoJSON example in mapserver.org/output/template_output.html#geojson?
    – user30184
    Sep 14 at 8:25
  • Just tried to add the curly brackets but same result.. Yes I've seen the GeoJSON example but if I use it the browser will download a GeoJSON file whereas I want my browser to display a JSON result
    – Julien
    Sep 14 at 8:45
  • Is what you wrote your whole template? Where is the "value":? I did not mean that you should use the GeoJSON template as is, but to read it as an example of a working json template. What a browser does for downloaded data depends on how it is configured. If you change the mimetype into application/json it is possible that your browser desides to show data as text.
    – user30184
    Sep 14 at 10:02
  • Thanks for your answer ! I just wrote the whole template, see the edits in my first post. The thing is my data is a raster, so I can't use the GeoJSON format since it is used by vector files. To be clearer, what I'd really like to do is getting the attributes values in the JSON format without any references to the geometry.
    – Julien
    Sep 14 at 10:10
  • Please add your OUTPUTFORMAT that you have now for json so others do not need to guess. See examples mapserver.org/output/template_output.html. The attributes that can be used in raster queries is documented in mapserver.org/input/raster.html#raster-query.
    – user30184
    Sep 14 at 10:29

4 Answers 4

2

There is a working example of a raster layer with a GetFeatureInfo query returning GeoJSON at https://app.mapserverstudio.net/#fXO3XBRn No templates are required, just the OUTPUTFORMAT:

    OUTPUTFORMAT
        NAME "geojson"
        DRIVER "OGR/GEOJSON"
        MIMETYPE "application/json; subtype=geojson; charset=utf-8"
        FORMATOPTION "FORM=SIMPLE"
        FORMATOPTION "STORAGE=memory"
        FORMATOPTION "LCO:NATIVE_MEDIA_TYPE=application/vnd.geo+json"
    END

    WEB
        METADATA
            "wms_enable_request" "*"
            # ensure the outputformat is in this list below
            "wms_getfeatureinfo_formatlist" "geojson"
        END
    END

Counter intuitively the "gml_include_items" is important at the LAYER level even though it is for a raster layer.

    LAYER
        NAME "hillsahde"
        STATUS ON
        TYPE RASTER
        DATA "/data/copernicus/eu_dem_v11_E10N00.TIF"
        PROCESSING "BANDS=1"
        CLASS
            STYLE
                COLORRANGE "#abc270" "#f7f1e5"
                DATARANGE 0 2000
            END
        END
        TEMPLATE "ttt"
        METADATA
            "gml_include_items" "all"
            "gml_types" "auto"
        END
    END

A sample request is:

https://api.mapserverstudio.net/mapserver/?map=/etc/mapserver/mapfiles/output/f920137d-5f1d-4ac4-9bf4-4a86bf4f2b7e.map&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image/png&TRANSPARENT=true&QUERY_LAYERS=hillsahde&LAYERS=hillsahde&STYLES=&FILTER=&INFO_FORMAT=geojson&I=50&J=50&CRS=EPSG:3857&WIDTH=101&HEIGHT=101&BBOX=1799862.1893692566,967876.9675296084,1801451.8980644122,969466.6762247642&_dc=1694810648114

GeoJSON response

This returns the following GeoJSON:

{
"type": "FeatureCollection",
"name": "hillsahde",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3857" } },
"features": [
{ "type": "Feature", "properties": { "x": "1800662.5", "y": "968662.5", "value_0": "1349.0573", "value_list": "1349.0573", "class": "0", "red": "-1", "green": "-1", "blue": "-1" }, "geometry": { "type": "Point", "coordinates": [ 1800662.5, 968662.5 ] } }
]
}

You can construct and call this URL with JavaScript with a fetch call (or older style AJAX call) and you can do whatever you want with the GeoJSON in the browser. In the example above the GeoJSON is displayed in a grid when the map is clicked. This functionality is part of a client like OpenLayers - https://openlayers.org/en/latest/examples/getfeatureinfo-tile.html

8
  • Thank you very much for your great answer, that is nearly what I'd like to do. But I want to obtain the json/geojson code in my browser instead of downloading a file (the geojson in your example). Do you think if it is possible and how could I do this ? Thanks again.
    – Julien
    Sep 16 at 13:35
  • 1
    @Julien - sure you can do whatever you want with the GeoJSON response in the browser - see updated answer above. Sep 16 at 17:17
  • 1
    You either need to change your QueryString to ensure GeoJSON is requested - &INFO_FORMAT=geojson or change the name of your OUTPUTFORMAT from NAME "geojson" to NAME "application/json" Sep 18 at 9:55
  • 1
    METADATA "wms_enable_request" "*" # ensure the outputformat is in this list below "wms_getfeatureinfo_formatlist" "geojson" END Sep 18 at 12:43
  • 1
    Just tried it and it perfectly works !! Then I use the fetch function in order to get the content of the GeoJSON in my browser and it works too ! Thank you very very much for all your help, that is greatly appreciated !
    – Julien
    Sep 19 at 12:29
2

Meanwhile you wrote your mail I managed to make the JSON output to work to some extent.

In my mapfile I have now at level MAP-WEB-METADATA an entry

 "wms_feature_info_mime_type" "application/json"

I wrote a section for json output

OUTPUTFORMAT
  NAME "json"
  MIMETYPE "application/json"
  DRIVER "TEMPLATE"
  FORMATOPTION "FILE=c:/ms4w_data/myTemplate.js"
END

As a template file I used this

<!-- mapserver template -->
{"foo": "bar"}

In LAYER I have dummy TEMPLATE

TEMPLATE "EMPTY"

The only reason to have the keyword TEMPLATE here is to make the the layer queryable. If the value points to some existing file instead of "EMPTY" the file still won't be read.

Now the GetFeatureInfo request with INFO_FORMAT=application/json returns a response that opens directly on a browser

enter image description here

and it opens to browser because the MIME type is set correctly

enter image description here

What I did not manage to work yet is how to use the raster attributes https://mapserver.org/input/raster.html#raster-query inside the JSON template.

6
  • 1
    Thanks ! That almost works ! I have the JSON in my browser that is what I want. I just tried to replace "bar" by the value of each raster pixel ([value_0]) but it indeed does not work.- It would be perfect if that last problem was resolved !
    – Julien
    Sep 14 at 13:52
  • Any ideas or updates on that ? Thanks !!
    – Julien
    Sep 15 at 9:36
  • @Julien what output do you get when using [value_0]? is it empty JSON? Maybe try [red] or [value_list] Sep 15 at 13:50
  • @geographika With [value_0] I should have the pixel value. With the text/html format it works but it fails with JSON. I tried both [red] and [value_list] but same error : SyntaxError: JSON.parse: unexpected character at ... of the JSON data
    – Julien
    Sep 15 at 14:06
  • @Julien - what does your template look like? Did you add quotes around the value? {"foo": "[value_0]"} Sep 15 at 14:53
1

In the past I have used the following, but neither worked for me correctly, things may have changed in recent versions:

# Neither GeoJSON outputs work as expected... (formatoptions issue related to GDAL version?)
# Supported GDAL should support options so MapServer issue?
# Can get GeoJSON by requesting srsname=EPSG:4326 even if bounding box is different
# GeoJSON 2008 (any CRS) BUT missing "crs" property in output)
# See https://www.gdal.org/drv_geojson.html for FORMATOPTIONs
# LCO: ~ is layer creation options prefix
# Pure GeoJSON (CRS:84 only)
# need to use outputformat=application/vnd.geo%2Bjson& in URL request
# or shortcut use name like outputformat=GeoJSON
OUTPUTFORMAT
    NAME "GeoJSON"
    DRIVER "OGR/GEOJSON"
    # MIMETYPE "application/geo+json"
    MIMETYPE "application/vnd.geo+json"
    EXTENSION "geojson"
    FORMATOPTION "LCO:RFC7946=YES"
    FORMATOPTION "STORAGE=stream"
    FORMATOPTION "FORM=SIMPLE"
    FORMATOPTION "LCO:NATIVE_DATA=YES"
    #FORMATOPTION "LCO:NATIVE_MEDIA_TYPE=application/geo+json"
    # Above is correct for GeoJSON, but GDAL requires older deprecated version
    FORMATOPTION "LCO:NATIVE_MEDIA_TYPE=application/vnd.geo+json"
    FORMATOPTION "LCO:COORDINATE_PRECISION=8"
    FORMATOPTION "LCO:WRITE_BBOX=YES"
    FORMATOPTION "FILENAME=result.geojson"
    FORMATOPTION "LCO:DESCRIPTION=This should be GeoJSON (RFC7946); i.e. coordinates in CRS:84 WGS84 datum and decimal degrees in lon lat order, but at the moment it's not working or not supported (https://github.com/mapserver/mapserver/issues/5723)"
END
OUTPUTFORMAT
    NAME "JSON"
    DRIVER "OGR/GEOJSON"
    EXTENSION "json"
    FORMATOPTION "FILENAME=result.json"
    FORMATOPTION "FORM=SIMPLE"
    FORMATOPTION "LCO:COORDINATE_PRECISION=8"
    FORMATOPTION "LCO:DESCRIPTION=This should be GeoJSON 2008; the projection may not be in CRS:84, but if not there should be a crs: member telling you what projection has been used"
    FORMATOPTION "LCO:NATIVE_DATA=YES"
    FORMATOPTION "LCO:WRITE_BBOX=YES"
    FORMATOPTION "STORAGE=stream"
    MIMETYPE "application/json; subtype=geojson"
END
1
  • Thanks for your answer ! but unfortunately I have the same error messages ; it seems that Mapserver can't understand the template ("Web application error. Malformed template name (DUMMY)"). Could it be because my template is not well formed ? Would you have an example of a template created with json format ?
    – Julien
    Sep 14 at 12:17
0

Have you looked at that gml_* entries - you can use them to return attribute data that leaflet should be able to work with e.g.

"gml_include_items" "all"
"gml_featureid" "ID"

1
  • Thanks for your answer. But my data is a raster file, so I don't think that the gml properties could be used in this case..
    – Julien
    Sep 14 at 14:58

Your Answer

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

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