660{
661 WindowObject winobj = PG_WINDOW_OBJECT();
662 int64 curpos = WinGetCurrentPosition(winobj);
663 int64 rowcount = WinGetPartitionRowCount(winobj);
666 MemoryContext uppercontext = fcinfo->flinfo->fn_mcxt;
667 MemoryContext oldcontext;
669
671 {
672 bool isnull;
673 GEOSGeometry *output = NULL;
674 GEOSGeometry *input = NULL;
675 Datum d;
676
677 if (!fcinfo->flinfo)
678 elog(ERROR, "%s: Could not find upper context", __func__);
679
680 if (rowcount == 0)
681 {
684 PG_RETURN_NULL();
685 }
686
688
690 if (!input)
692
693
695 {
696 bool simplifyBoundary = true;
697 double tolerance = 0.0;
698
699 d = WinGetFuncArgCurrent(winobj, 1, &isnull);
700 if (!isnull) tolerance = DatumGetFloat8(d);
701
702 d = WinGetFuncArgCurrent(winobj, 2, &isnull);
703 if (!isnull) simplifyBoundary = DatumGetFloat8(d);
704
705
706 output = GEOSCoverageSimplifyVW(input, tolerance, !simplifyBoundary);
707 }
709 {
710 double tolerance = 0.0;
711 d = WinGetFuncArgCurrent(winobj, 1, &isnull);
712 if (!isnull) tolerance = DatumGetFloat8(d);
713 GEOSCoverageIsValid(input, tolerance, &output);
714 }
715
716#if POSTGIS_GEOS_VERSION >= 31400
717
718 else if (mode == COVERAGE_CLEAN)
719 {
720 double snappingDistance = 0.0;
721 double gapMaximumWidth = 0.0;
722 text *overlapMergeStrategyText;
723 int overlapMergeStrategy;
724 GEOSCoverageCleanParams *params = NULL;
725
726 d = WinGetFuncArgCurrent(winobj, 1, &isnull);
727 if (!isnull) gapMaximumWidth = DatumGetFloat8(d);
728
729 d = WinGetFuncArgCurrent(winobj, 2, &isnull);
730 if (!isnull) snappingDistance = DatumGetFloat8(d);
731
732 d = WinGetFuncArgCurrent(winobj, 3, &isnull);
733 if (!isnull)
734 {
735 overlapMergeStrategyText = DatumGetTextP(d);
736 overlapMergeStrategy = coverage_merge_strategy(text_to_cstring(overlapMergeStrategyText));
737 }
738 else
739 {
740 overlapMergeStrategy = 0;
741 }
742 if (overlapMergeStrategy < 0)
743 {
745 }
746
747 params = GEOSCoverageCleanParams_create();
748 GEOSCoverageCleanParams_setGapMaximumWidth(params, gapMaximumWidth);
749 GEOSCoverageCleanParams_setSnappingDistance(params, snappingDistance);
750 if (!GEOSCoverageCleanParams_setOverlapMergeStrategy(params, overlapMergeStrategy))
751 {
752 GEOSCoverageCleanParams_destroy(params);
754 }
755
756 output = GEOSCoverageCleanWithParams(input, params);
757 GEOSCoverageCleanParams_destroy(params);
758 }
759#endif
760 else
761 {
762 elog(ERROR, "Unknown mode, never get here");
763 }
764
765 GEOSGeom_destroy(input);
766
767 if (!output)
768 {
770 }
771
772 oldcontext = MemoryContextSwitchTo(uppercontext);
774 MemoryContextSwitchTo(oldcontext);
775 GEOSGeom_destroy(output);
776
778 }
779
780
782 PG_RETURN_NULL();
783
784
785 if (context->
idx[curpos] < 0)
786 PG_RETURN_NULL();
787
788
789
790
791
792
793
794
795
796
797
798 oldcontext = MemoryContextSwitchTo(uppercontext);
801 {
803 }
804 else
805 {
807 }
808 MemoryContextSwitchTo(oldcontext);
809
810
811
812 if (curpos == rowcount - 1)
814
815 if (!
result) PG_RETURN_NULL();
816
817 PG_RETURN_POINTER(
result);
818
819}
char result[OUT_DOUBLE_BUFFER_SIZE]
void lwgeom_geos_error(const char *fmt,...)
void(*) LWGEOM GEOS2LWGEOM)(const GEOSGeometry *geom, uint8_t want3d)
const LWGEOM * lwcollection_getsubgeom(LWCOLLECTION *col, uint32_t gnum)
void lwcollection_free(LWCOLLECTION *col)
static coverage_context * coverage_context_fetch(WindowObject winobj, int64 rowcount)
static GEOSGeometry * coverage_read_partition_into_collection(WindowObject winobj, coverage_context *context)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
#define HANDLE_GEOS_ERROR(label)