2

I have a function to return a reduced size version of the geometries in our database.

CREATE OR REPLACE FUNCTION fog.small_kml(
    shape geometry,
    max_length integer)
    RETURNS text
    LANGUAGE 'plpgsql'
AS $BODY$
 DECLARE kml text;
 DECLARE tolerance float;
BEGIN
    tolerance:=0.001;
    SELECT ST_ASKML(shape) INTO kml;

    WHILE LENGTH(kml) > max_length LOOP
        SELECT ST_ASKML(ST_SIMPLIFY(shape, tolerance)) INTO kml;
        tolerance = tolerance + 0.001;
    END LOOP;

    return kml;
END
 $BODY$;

when I run this on certain geometries I get get the result

ERROR:  parse error - invalid geometry
HINT:  "<M" <-- parse error at position 2 within geometry
SQL state: XX000

occurring due to the statement SELECT ST_ASKML(ST_SIMPLIFY(shape, tolerance)) INTO kml;. However, ST_ISVALID says that the geometries are all valid.

Is there anything I can do to force the geometries into a state where I can simplify them? The length of the KML is around 12 million characters for the largest, which is why I want to simplify (and why I can't paste the whole thing here).

Each one starts <MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates> and I've had no issues with them before other than being slow. It seems to be ST_SIMPLIFY only that has an issue.

5
  • 3
    The simplify operation can make a geometry invalid if it collapses holes. Have you tried to test the validity after ST_Simplify?
    – Vince
    May 1 '19 at 10:53
  • @Vince, I can't test validity after ST_Simplify as ST_Simplify errors. May 1 '19 at 11:00
  • Actually, no, I was wrong, it's the ST_ASKML failing on the simplified geometry. I'll look into this. May 1 '19 at 11:03
  • Yes, Vice was correct and changing the line to SELECT ST_ASKML(ST_SIMPLIFY(ST_MAKEVALID(shape), tolerance)) INTO kml; fixes it. I'll leave a while to let him answer. If he doesn't I'll self answer. May 1 '19 at 11:17
  • Go ahead and self-answer (though the MakeValid before Simplify confuses the issue of where invalidity arose).
    – Vince
    May 1 '19 at 11:38
3

Vince got it correct in the comments - simplification led to an invalid geometry and then it was the ST_AsKML function which threw the error.

I fixed it by changing that line to

SELECT ST_AsKML(ST_MakeValid(ST_Simplify(shape, tolerance))) INTO kml;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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