PostGIS GeoJSON – Fixing Unsupported GeoJSON Type from AJAX Request to PostGIS Database

ajaxgeojsonopenlayersPHPpostgis

I'm trying to use a GeoJSON to build a layer on an OpenLayers map of MultiPolygons from my PostGIS database.

However the following error is thrown:

Uncaught Error: Unsupported GeoJSON type: undefined

b_                     GeoJSON.js:323
readFeatureFromObject  GeoJSON.js:113
readFeaturesFromObject GeoJSON.js:157
readFeatures           JSONFeature.js:54
<anonymous>            prova.js:19

I've already tried to check the GeoJSON on GeoJSONlint as suggested here, but it gives right hand rule error. I've tried to fix this usingthis solution, but the error was in my coordinates, as @pavlos noted and corrected.

I've also tried to correct the feature projection, but the error persist.

This is the PHP script that is called by AJAX:

<?php
    $conn = pg_connect("host=localhost port=5432 user=postgres password=root dbname=benilun");
    if (!$conn) {
        die("Connessione PostgreSQL fallita.");
    };
    $res = pg_query($conn, "SELECT json_build_object( 'type', 'FeatureCollection', 'features', json_agg(ST_AsGeoJSON(t.*)::json) )
FROM ( SELECT id, identificazione, area FROM luogo ) as t(id, name, geom);");
    echo json_encode(pg_fetch_row($res));
?>

This is the JavaScript which should build the OpenLayers map; I've updated it with a @JGH suggestion, that doesn't change the error but is indeed more correct:

var res;
var dati = new FormData();
$.ajax({
    url: "php/prova.php",
    type: "POST",
    data: dati,
    success: function (resJ) {
        res = JSON.parse(resJ);
        var vectorSource = new ol.source.VectorSource({
          features: new ol.format.GeoJSON().readFeatures(res, {featureProjection: 'EPSG:3857'})
        });
        var stile = new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'red',
              width: 1,
            }),
            fill: new ol.style.Fill({
              color: 'rgba(255, 0, 0, 0.1)',
            }),
        });
        var vectorLayer = new ol.layer.VectorLayer({
          source: vectorSource,
          style: stile
        });
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                vectorLayer
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([15, 15]),
                zoom: 4
            })
        });
    },
    cache: false,
    contentType: false,
    processData: false
});

And this is the GeoJSON object that is sent as response to the AJAX interrogation (suggested by @TomazicM, in the last edit I forgot the object):

{
  "type" : "FeatureCollection",
  "features" : [{
    "type": "Feature",
    "geometry": {
      "type":"MultiPolygon",
      "coordinates":[[[[10,30],[30,30],[30,60],[10,10],[10,30]]]]
    },
    "properties": {"id": 1, "name": "Parrocchia Santa Caterina"}
  }]
}

Could you help me?

Best Answer

JavaScript will not wait for the ajax call to return before continuing processing your code. The only thing that will happen once the Ajax call is completed is success: function (resJ) { res = JSON.parse(resJ); }, but it is too late, the map is already loaded with an empty json (the initial content of restJ).

You will want to load the layer after the Ajax call is completed. You can put all the code that comes after the $.ajax({..}) (i.e. the code creating the layers, the map etc) inside a function, and call this function from within the success: section.

Related Question