45

I need to insert a polygon from GeoJSON to my PostGIS table. This is how the SQL query looks like.

INSERT INTO tablename (name, polygon)
VALUES (
    'Name',
    ST_GeomFromGeoJSON(
        '{
            "type": "Polygon",
            "coordinates": [
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }'
    )
)

Unfortunately, I get an error message.

ERROR:  Geometry SRID (0) does not match column SRID (3857)

The GeoJSON is already in the right reference system. But this isn't specified. How do I specify the SRID in the GeoJSON? What does the GeoJSON need to look like?

Update: When I wrap the geometry created by ST_GeomFromGeoJSON with ST_SetSRID(..., 3857) it throws another error. In my view it doesn't seem that the geometry has a Z dimension.

ERROR:  Geometry has Z dimension but column does not
2
  • I think you need to specify that the table has srid:4326, it looks that your table has srid:3857 but your geojson has long/latitude (ie. srid:4326 or WGS84)
    – Gery
    Commented May 16, 2013 at 10:44
  • I want to use 3857. How does the GeoJSON have to look like then?
    – danijar
    Commented May 16, 2013 at 10:46

4 Answers 4

43

Taking a look at the source code of PostGIS I found out how it parses SRIDs. Here is the correct way to specify the SRID in GeoJSON.

The GeoJSON specification says that the coordinates of a polygon are an array of line strings. Therefore I had to wrap them with additional brackets.

{
    "type":"Polygon",
    "coordinates":
    [
        [
            [-91.23046875,45.460130637921],
            [-79.8046875,49.837982453085],
            [-69.08203125,43.452918893555],
            [-88.2421875,32.694865977875],
            [-91.23046875,45.460130637921]
        ]
    ],
    "crs":{"type":"name","properties":{"name":"EPSG:3857"}}
}
2
  • 1
    Did that work? What one is supposed to specify in crs - SRID of the data in the GeoJSON, or a SRID of the target one wants to convert it to? I mean your coordinates here look like they are in lat/lng, which is EPSG:4326 I believe? And still you got EPSG:3857 in there.
    – jayarjo
    Commented May 23, 2020 at 5:32
  • Checked with more complete URN syntax at name, urn:ogc:def:crs:EPSG::3857 ? Commented Apr 4, 2021 at 23:31
24

There are a couple of problems with your JSON.

  1. Firstly, the coordinates should be an array of arrays.
  2. Secondly, looking at the coordinates, it looks like the values are Latlong in a Geographic coordinate system, most probably EPSG:4326. That then needs to be transformed to EPSG:3857.

Once you correct these two things, you can insert the row, using the following SQL Query:

INSERT INTO "Parcels"("Name", the_geom)
    VALUES ('Corrected_Shape', 
    ST_TRANSFORM(ST_GeomFromGeoJSON('{
    "type":"Polygon",
    "coordinates":[[
        [-91.23046875,45.460130637921],
        [-79.8046875,49.837982453085],
        [-69.08203125,43.452918893555],
        [-88.2421875,32.694865977875],
        [-91.23046875,45.460130637921]
    ]],
    "crs":{"type":"name","properties":{"name":"EPSG:4326"}}
}'),3857));

If this does not work, (i.e. you are still getting the error with Z diemsnion), please update the question with the PostGis version, and the Create Statement of your table.

9
  • Why do you think the coordinates are not in EPSG:3857?
    – danijar
    Commented May 17, 2013 at 9:30
  • 4
    Because the units of EPSG:3857 are (pseudo)meters, and the origin is in the Atlantic Ocean. You wouldn't have 6 decimal accuracy with meters, and this data would lie in the Atlantic Ocean near the coast of Africa. Commented May 17, 2013 at 10:59
  • The coordinates are from input on a map and have a lot of decimals. For testing I drew an area in the Atlantic Ocean near Africa. But thanks to you I can improve the map to round the coordinates to whole meters.
    – danijar
    Commented May 17, 2013 at 11:13
  • @danijar: Then it's all right. If these coordinates were in EPSG:4326, then it would lie over the eastern states of the US. Commented May 17, 2013 at 11:40
  • why are you converting it back to EPSG: 3857, why can't we leave it in EPSG: 4326?
    – Dhruv garg
    Commented Aug 5, 2021 at 8:47
5

your geojson must have UTM values instead, you could transform that with Proj or other online tools, but you can do it easily and directly with postgis before inserting it into your table, try this (untested):

SELECT ST_AsText(ST_Transform(ST_GeomFromGeoJSON
    (
        {
            "type":"Polygon",
            "coordinates":[
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }
    ),4326),3857));
4
  • So you suggest to convert the SRID over 4326 to 3857? Then I could directly try ST_Transform(ST_SetSRID(..., 4326), 3857), couldn't I? Why would this extra transformation step be necessary?
    – danijar
    Commented May 16, 2013 at 11:18
  • I think you should test what you're asking, probably what you suggest is the only step you need, try it and post what you got
    – Gery
    Commented May 16, 2013 at 11:50
  • This is what I get. ERROR: transform: couldn't project point (9.25253e-302 6.08985e+159 1.18576e-322): latitude or longitude exceeded limits (-14)
    – danijar
    Commented May 16, 2013 at 12:36
  • I didn't know ST_GeomFromGeoJSON accepts second arguments of SRID, does it? It is not documented: postgis.net/docs/ST_GeomFromGeoJSON.html
    – jayarjo
    Commented May 23, 2020 at 5:30
5
INSERT INTO tablename (name, polygon)
VALUES
(
    'Name',
    ST_GeomFromGeoJSON
    (
        '{
            "type":"Polygon",
            "coordinates":[
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }'
    )
)

missing "'"

3
  • 4
    Could you add more context to this answer and explain how it answers OP's question, and is different from existing answers Commented Mar 27, 2015 at 12:17
  • Honestly, the JSON does have to be a string, it is not a string in the question and it is not a string in at least one of the answers. This answer might point out the obvious, but it's not necessarily obvious to everyone, so deserves some credit. Commented Apr 13, 2016 at 13:54
  • I tried this example literally, but give: SQL Error [XX000]: ERROR: The 'coordinates' in GeoJSON are not sufficiently nested ERROR: The 'coordinates' in GeoJSON are not sufficiently nested ERROR: The 'coordinates' in GeoJSON are not sufficiently nested Commented Jul 30, 2020 at 14:24

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.