Remove --without-wagyu option

stable-3.2
Raúl Marín 2021-01-08 16:43:24 +01:00
parent ebc52f4017
commit 9e68f84879
14 changed files with 80 additions and 354 deletions

View File

@ -11,7 +11,6 @@ env:
- tag=pg13-geos39-gdal31-proj71 mode=coverage
- tag=pg13-geos39-gdal31-proj71 mode=usan_gcc
- tag=pg13-clang-geos39-gdal31-proj71 mode=usan_clang
- tag=pg13-geos39-gdal31-proj71 mode=nowagyu
# Run tests with different dependency combinations
- tag=latest mode=tests

2
NEWS
View File

@ -1,6 +1,8 @@
PostGIS 3.2.0
2021/xx/xx
* Breaking changes *
- Removed `--without-wagyu` build option. Using Wagyu is not mandatory to build with MVT support.
PostGIS 3.1.0
2020/12/18

View File

@ -36,7 +36,7 @@ CPPFLAGS="-I${PGPATH}/include" \
LDFLAGS="-L${PGPATH}/lib" ./configure \
--with-pgconfig=${PGPATH}/bin/pg_config \
--with-geosconfig=${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}/bin/geos-config \
--without-raster --without-wagyu
--without-raster --without-protobuf
make clean
cd doc
make update-pot

View File

@ -35,7 +35,7 @@ CPPFLAGS="-I${PGPATH}/include" \
LDFLAGS="-L${PGPATH}/lib" ./configure \
--with-pgconfig=${PGPATH}/bin/pg_config \
--with-geosconfig=${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}/bin/geos-config \
--without-raster --without-wagyu
--without-raster --without-protobuf
make clean
# generating postgis_revision.h in case hasn't been generated

View File

@ -1,18 +0,0 @@
#!/usr/bin/env bash
set -e
WARNINGS="-Werror -Wall -Wextra -Wformat -Werror=format-security"
WARNINGS_DISABLED="-Wno-unused-parameter -Wno-implicit-fallthrough -Wno-cast-function-type"
# Build with coverage
CFLAGS="-g -O0 --coverage -mtune=generic -fno-omit-frame-pointer ${WARNINGS} ${WARNINGS_DISABLED}"
LDFLAGS="--coverage"
/usr/local/pgsql/bin/pg_ctl -c -l /tmp/logfile -o '-F' start
./autogen.sh
# Standard build
./configure --without-wagyu CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
bash ./ci/travis/logbt -- make -j
bash ./ci/travis/logbt -- make check RUNTESTFLAGS=--verbose
(curl -S -f https://codecov.io/bash -o .github/codecov.bash && bash .github/codecov.bash) || echo "Coverage report failed"

View File

@ -1462,74 +1462,67 @@ dnl ===========================================================================
dnl Wagyu will only be necessary if protobuf is present to build MVTs
HAVE_WAGYU=no
if test "x$HAVE_PROTOBUF" = "xyes"; then
AC_ARG_WITH([wagyu], AC_HELP_STRING([--without-wagyu], [Don't use the wagyu library]), [], [])
DEPS_SUBDIR="deps"
AC_SUBST([DEPS_SUBDIR])
if test "x$with_wagyu" != xno; then
AC_MSG_RESULT([WAGYU: Wagyu usage requested])
WAGYU_LIB=libwagyu.la
AC_SUBST([WAGYU_LIB])
DEPS_SUBDIR="deps"
AC_SUBST([DEPS_SUBDIR])
dnl ============================================================
dnl We force to use the same compiler as Postgresql
dnl ============================================================
CXX_SAVE="$CXX"
CC_SAVE="$CC"
CFLAGS_SAVE="$CFLAGS"
CXXFLAGS_SAVE="$CXXFLAGS"
CPPFLAGS_SAVE="$CPPFLAGS"
LDFLAGS_SAVE="$LDFLAGS"
LIBS_SAVE="$LIBS"
WAGYU_LIB=libwagyu.la
AC_SUBST([WAGYU_LIB])
WAGYU_CXX=`"$PG_CONFIG" --cc`
CPPFLAGS="-x c++"
CFLAGS=""
LDFLAGS=""
LIBS=""
CXX="$WAGYU_CXX"
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
WAGYU_CXX="$CXX -x c++"
dnl ============================================================
dnl We force to use the same compiler as Postgresql
dnl ============================================================
CXX_SAVE="$CXX"
CC_SAVE="$CC"
CFLAGS_SAVE="$CFLAGS"
CXXFLAGS_SAVE="$CXXFLAGS"
CPPFLAGS_SAVE="$CPPFLAGS"
LDFLAGS_SAVE="$LDFLAGS"
LIBS_SAVE="$LIBS"
dnl ============================================================
dnl Check if we can declare the c++ stdlib
dnl ============================================================
CC="$WAGYU_CXX"
WAGYU_CXX=`"$PG_CONFIG" --cc`
CPPFLAGS="-x c++"
CFLAGS=""
LDFLAGS=""
LIBS=""
CXX="$WAGYU_CXX"
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
WAGYU_CXX="$CXX -x c++"
AC_CHECK_LIB(c++, main, [HAVE_CPP=yes], [HAVE_CPP=no])
AC_CHECK_LIB(stdc++, main, [HAVE_STDCPP=yes], [HAVE_STDCPP=no])
dnl ============================================================
dnl Check if we can declare the c++ stdlib
dnl ============================================================
CC="$WAGYU_CXX"
AC_CHECK_LIB(c++, main, [HAVE_CPP=yes], [HAVE_CPP=no])
AC_CHECK_LIB(stdc++, main, [HAVE_STDCPP=yes], [HAVE_STDCPP=no])
if test "x$HAVE_CPP" = "xyes"; then
WAGYU_LDFLAGS="-lc++"
elif test "x$HAVE_STDCPP" = "xyes"; then
WAGYU_LDFLAGS="-lstdc++"
else
AC_MSG_WARN("Could not find a C++ standard library")
WAGYU_LDFLAGS=""
fi
CXX="$CXX_SAVE"
CC="$CC_SAVE"
CFLAGS="$CFLAGS_SAVE"
CXXFLAGS="$CXXFLAGS_SAVE"
CPPFLAGS="$CPPFLAGS_SAVE"
LDFLAGS="$LDFLAGS_SAVE"
LIBS="$LIBS_SAVE"
HAVE_WAGYU=yes
AC_DEFINE([HAVE_WAGYU], [1], [Define to 1 if wagyu is being built])
AC_SUBST([HAVE_WAGYU])
AC_SUBST([WAGYU_CXX])
AC_SUBST([WAGYU_LDFLAGS])
DEPS_MAKEFILE_LIST="$DEPS_MAKEFILE_LIST
deps/wagyu/Makefile"
if test "x$HAVE_CPP" = "xyes"; then
WAGYU_LDFLAGS="-lc++"
elif test "x$HAVE_STDCPP" = "xyes"; then
WAGYU_LDFLAGS="-lstdc++"
else
AC_MSG_WARN("Could not find a C++ standard library")
WAGYU_LDFLAGS=""
fi
CXX="$CXX_SAVE"
CC="$CC_SAVE"
CFLAGS="$CFLAGS_SAVE"
CXXFLAGS="$CXXFLAGS_SAVE"
CPPFLAGS="$CPPFLAGS_SAVE"
LDFLAGS="$LDFLAGS_SAVE"
LIBS="$LIBS_SAVE"
HAVE_WAGYU=yes
AC_DEFINE([HAVE_WAGYU], [1], [Define to 1 if wagyu is being built])
AC_SUBST([HAVE_WAGYU])
AC_SUBST([WAGYU_CXX])
AC_SUBST([WAGYU_LDFLAGS])
DEPS_MAKEFILE_LIST="$DEPS_MAKEFILE_LIST
deps/wagyu/Makefile"
fi
dnl ===========================================================================
@ -1653,7 +1646,6 @@ fi
AC_MSG_RESULT([ PCRE support: ${HAVE_PCRE}])
AC_MSG_RESULT([ Perl: ${PERL}])
AC_MSG_RESULT([ Wagyu: ${HAVE_WAGYU}])
AC_MSG_RESULT()
AC_MSG_RESULT([ --------------- Extensions --------------- ])

View File

@ -521,14 +521,6 @@ tar -xvzf postgis-&last_release_version;.tar.gz</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>--without-wagyu</command></term>
<listitem>
<para>
When building with MVT support, Postgis will use <ulink url="https://github.com/mapbox/wagyu/">Wagyu</ulink> to clip and validate MVT polygons. Wagyu is the fastest alternative and guarantees producing correct values for this specific case, but it requires a C++-11 compiler. With this optional argument you can disable using this library; GEOS will be used instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>--without-phony-revision</command></term>
<listitem>

View File

@ -53,13 +53,12 @@ ifeq (@HAVE_SPGIST@,yes)
SPGIST_OBJ= gserialized_spgist_2d.o gserialized_spgist_3d.o gserialized_spgist_nd.o
endif
WAGYU_LIBPATH = ../deps/wagyu/@WAGYU_LIB@
ifeq (@HAVE_PROTOBUF@,yes)
PROTOBUF_OBJ = vector_tile.pb-c.o geobuf.pb-c.o
UTHASH_INCLUDE = -I../deps/uthash/include
endif
WAGYU_LIBPATH = ../deps/wagyu/@WAGYU_LIB@
ifeq (@HAVE_WAGYU@,yes)
WAYGU_INCLUDE = -I../deps/wagyu
WAYGU_LIB = $(WAGYU_LIBPATH) @WAGYU_LDFLAGS@
WAGYU_DEP = $(WAGYU_LIBPATH)

View File

@ -34,6 +34,8 @@
#ifdef HAVE_LIBPROTOBUF
#include "utils/jsonb.h"
#include "lwgeom_wagyu.h"
#if POSTGIS_PGSQL_VERSION < 110
/* See trac ticket #3867 */
# define DatumGetJsonbP DatumGetJsonb
@ -836,261 +838,34 @@ mvt_unsafe_clip_by_box(LWGEOM *lwg_in, GBOX *clip_box)
return geom_clipped;
}
/**
* Clips an input geometry using GEOSIntersection
* It used to try to use GEOSClipByRect (as mvt_unsafe_clip_by_box) but since that produces
* invalid output when an invalid geometry is given and detecting it resulted to be impossible,
* we use intersection instead and, upon error, force validation of the input and retry.
* Might return NULL
*/
static LWGEOM *
mvt_safe_clip_polygon_by_box(LWGEOM *lwg_in, GBOX *clip_box)
{
LWGEOM *geom_clipped, *envelope;
GBOX geom_box;
GEOSGeometry *geos_input, *geos_box, *geos_result;
gbox_init(&geom_box);
FLAGS_SET_GEODETIC(geom_box.flags, 0);
lwgeom_calculate_gbox(lwg_in, &geom_box);
if (!gbox_overlaps_2d(&geom_box, clip_box))
{
POSTGIS_DEBUG(3, "mvt_geom: geometry outside clip box");
return NULL;
}
if (gbox_contains_2d(clip_box, &geom_box))
{
POSTGIS_DEBUG(3, "mvt_geom: geometry contained fully inside the box");
return lwg_in;
}
initGEOS(lwnotice, lwgeom_geos_error);
if (!(geos_input = LWGEOM2GEOS(lwg_in, 1)))
return NULL;
envelope = (LWGEOM *)lwpoly_construct_envelope(
lwg_in->srid, clip_box->xmin, clip_box->ymin, clip_box->xmax, clip_box->ymax);
geos_box = LWGEOM2GEOS(envelope, 1);
lwgeom_free(envelope);
if (!geos_box)
{
GEOSGeom_destroy(geos_input);
return NULL;
}
geos_result = GEOSIntersection(geos_input, geos_box);
if (!geos_result)
{
POSTGIS_DEBUG(3, "mvt_geom: no geometry after intersection. Retrying after validation");
GEOSGeom_destroy(geos_input);
lwg_in = lwgeom_make_valid(lwg_in);
if (!(geos_input = LWGEOM2GEOS(lwg_in, 1)))
{
GEOSGeom_destroy(geos_box);
return NULL;
}
geos_result = GEOSIntersection(geos_input, geos_box);
if (!geos_result)
{
GEOSGeom_destroy(geos_box);
GEOSGeom_destroy(geos_input);
return NULL;
}
}
GEOSSetSRID(geos_result, lwg_in->srid);
geom_clipped = GEOS2LWGEOM(geos_result, 0);
GEOSGeom_destroy(geos_box);
GEOSGeom_destroy(geos_input);
GEOSGeom_destroy(geos_result);
if (!geom_clipped || lwgeom_is_empty(geom_clipped))
{
POSTGIS_DEBUG(3, "mvt_geom: no geometry after clipping");
return NULL;
}
return geom_clipped;
}
/**
* Clips the geometry using GEOSIntersection in a "safe way", cleaning the input
* if necessary and clipping MULTIPOLYGONs separately to reduce the impact
* of using invalid input in GEOS
* Might return NULL
*/
static LWGEOM *
mvt_iterate_clip_by_box_geos(LWGEOM *lwgeom, GBOX *clip_gbox, uint8_t basic_type)
{
if (basic_type != POLYGONTYPE)
{
return mvt_unsafe_clip_by_box(lwgeom, clip_gbox);
}
if (lwgeom->type != MULTIPOLYGONTYPE || ((LWMPOLY *)lwgeom)->ngeoms == 1)
{
return mvt_safe_clip_polygon_by_box(lwgeom, clip_gbox);
}
else
{
GBOX geom_box;
uint32_t i;
LWCOLLECTION *lwmg;
LWCOLLECTION *res;
gbox_init(&geom_box);
FLAGS_SET_GEODETIC(geom_box.flags, 0);
lwgeom_calculate_gbox(lwgeom, &geom_box);
lwmg = ((LWCOLLECTION *)lwgeom);
res = lwcollection_construct_empty(
MULTIPOLYGONTYPE, lwgeom->srid, FLAGS_GET_Z(lwgeom->flags), FLAGS_GET_M(lwgeom->flags));
for (i = 0; i < lwmg->ngeoms; i++)
{
LWGEOM *clipped = mvt_safe_clip_polygon_by_box(lwcollection_getsubgeom(lwmg, i), clip_gbox);
if (clipped)
{
clipped = lwgeom_to_basic_type(clipped, POLYGONTYPE);
if (!lwgeom_is_empty(clipped) &&
(clipped->type == POLYGONTYPE || clipped->type == MULTIPOLYGONTYPE))
{
if (!lwgeom_is_collection(clipped))
{
lwcollection_add_lwgeom(res, clipped);
}
else
{
uint32_t j;
for (j = 0; j < ((LWCOLLECTION *)clipped)->ngeoms; j++)
lwcollection_add_lwgeom(
res, lwcollection_getsubgeom((LWCOLLECTION *)clipped, j));
}
}
}
}
return lwcollection_as_lwgeom(res);
}
}
/**
* Given a geometry, it uses GEOS operations to make sure that it's valid according
* to the MVT spec and that all points are snapped into int coordinates
* It iterates several times if needed, if it fails, returns NULL
*/
static LWGEOM *
mvt_grid_and_validate_geos(LWGEOM *ng, uint8_t basic_type)
{
gridspec grid = {0, 0, 0, 0, 1, 1, 0, 0};
ng = lwgeom_to_basic_type(ng, basic_type);
if (basic_type != POLYGONTYPE)
{
/* Make sure there is no pending float values (clipping can do that) */
lwgeom_grid_in_place(ng, &grid);
}
else
{
/* For polygons we have to both snap to the integer grid and force validation.
* The problem with this procedure is that snapping to the grid can create
* an invalid geometry and making it valid can create float values; so
* we iterate several times (up to 3) to generate a valid geom with int coordinates
*/
GEOSGeometry *geo;
uint32_t iterations = 0;
static const uint32_t max_iterations = 3;
bool valid = false;
/* Grid to int */
lwgeom_grid_in_place(ng, &grid);
initGEOS(lwgeom_geos_error, lwgeom_geos_error);
geo = LWGEOM2GEOS(ng, 0);
if (!geo)
return NULL;
valid = GEOSisValid(geo) == 1;
while (!valid && iterations < max_iterations)
{
#if POSTGIS_GEOS_VERSION < 38
GEOSGeometry *geo_valid = LWGEOM_GEOS_makeValid(geo);
#else
GEOSGeometry *geo_valid = GEOSMakeValid(geo);
#endif
GEOSGeom_destroy(geo);
if (!geo_valid)
return NULL;
ng = GEOS2LWGEOM(geo_valid, 0);
GEOSGeom_destroy(geo_valid);
if (!ng)
return NULL;
lwgeom_grid_in_place(ng, &grid);
ng = lwgeom_to_basic_type(ng, basic_type);
geo = LWGEOM2GEOS(ng, 0);
valid = GEOSisValid(geo) == 1;
iterations++;
}
GEOSGeom_destroy(geo);
if (!valid)
{
POSTGIS_DEBUG(1, "mvt_geom: Could not transform into a valid MVT geometry");
return NULL;
}
/* In image coordinates CW actually comes out a CCW, so we reverse */
lwgeom_force_clockwise(ng);
lwgeom_reverse_in_place(ng);
}
return ng;
}
/* Clips and validates a geometry for MVT using GEOS
/* Clips a geometry for MVT using GEOS.
* Does NOT work for polygons
* Might return NULL
*/
static LWGEOM *
mvt_clip_and_validate_geos(LWGEOM *lwgeom, uint8_t basic_type, uint32_t extent, uint32_t buffer, bool clip_geom)
{
LWGEOM *ng = lwgeom;
assert(lwgeom->type != POLYGONTYPE);
assert(lwgeom->type != MULTIPOLYGONTYPE);
if (clip_geom)
{
gridspec grid = {0, 0, 0, 0, 1, 1, 0, 0};
GBOX bgbox;
gbox_init(&bgbox);
bgbox.xmax = bgbox.ymax = (double)extent + (double)buffer;
bgbox.xmin = bgbox.ymin = -(double)buffer;
FLAGS_SET_GEODETIC(bgbox.flags, 0);
ng = mvt_iterate_clip_by_box_geos(lwgeom, &bgbox, basic_type);
if (!ng || lwgeom_is_empty(ng))
{
POSTGIS_DEBUG(3, "mvt_geom: no geometry after clip");
return NULL;
}
}
ng = mvt_unsafe_clip_by_box(ng, &bgbox);
ng = mvt_grid_and_validate_geos(ng, basic_type);
/* Make sure we return the expected type */
if (!ng || basic_type != lwgeom_get_basic_type(ng))
{
/* Drop type changes to play nice with MVT renderers */
POSTGIS_DEBUG(1, "mvt_geom: Dropping geometry after type change");
return NULL;
/* Make sure there is no pending float values (clipping can do that) */
lwgeom_grid_in_place(ng, &grid);
}
return ng;
}
#ifdef HAVE_WAGYU
#include "lwgeom_wagyu.h"
static LWGEOM *
mvt_clip_and_validate(LWGEOM *lwgeom, uint8_t basic_type, uint32_t extent, uint32_t buffer, bool clip_geom)
{
@ -1120,15 +895,6 @@ mvt_clip_and_validate(LWGEOM *lwgeom, uint8_t basic_type, uint32_t extent, uint3
return clipped_lwgeom;
}
#else /* ! HAVE_WAGYU */
static LWGEOM *
mvt_clip_and_validate(LWGEOM *lwgeom, uint8_t basic_type, uint32_t extent, uint32_t buffer, bool clip_geom)
{
return mvt_clip_and_validate_geos(lwgeom, basic_type, extent, buffer, clip_geom);
}
#endif
/**
* Transform a geometry into vector tile coordinate space.
*

View File

@ -5,9 +5,6 @@
#ifdef HAVE_LIBPROTOBUF
#include <protobuf-c/protobuf-c.h>
#endif
#ifdef HAVE_WAGYU
#include "lwgeom_wagyu.h"
#endif
@ -26,9 +23,9 @@ Datum postgis_libprotobuf_version(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(postgis_wagyu_version);
Datum postgis_wagyu_version(PG_FUNCTION_ARGS)
{
#ifndef HAVE_WAGYU
#ifndef HAVE_LIBPROTOBUF
PG_RETURN_NULL();
#else /* HAVE_WAGYU */
#else /* HAVE_LIBPROTOBUF */
const char *ver = libwagyu_version();
text *result = cstring_to_text(ver);
PG_RETURN_POINTER(result);

View File

@ -35,7 +35,7 @@
#include "lwgeom_pg.h"
#include "geos_c.h"
#ifdef HAVE_WAGYU
#ifdef HAVE_LIBPROTOBUF
#include "lwgeom_wagyu.h"
#endif
@ -97,7 +97,7 @@ handleInterrupt(int sig)
GEOS_interruptRequest();
#ifdef HAVE_WAGYU
#ifdef HAVE_LIBPROTOBUF
lwgeom_wagyu_interruptRequest();
#endif

View File

@ -71,9 +71,6 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if wagyu is being built */
#undef HAVE_WAGYU
/* Define to 1 if sfcgal is being built */
#undef HAVE_SFCGAL

View File

@ -727,10 +727,10 @@ SELECT '#4348Crash', COALESCE(ST_Npoints(ST_AsMVTGeom(
)), 0) BETWEEN 0 AND 100;
WITH geom AS (
SELECT 'TRIANGLE((0 0, 1 1, 0 1, 0 0))'::geometry geom
SELECT 1 as id, 'TRIANGLE((0 0, 1 1, 0 1, 0 0))'::geometry geom
union all
SELECT 'TIN(((0 0, 1 1, 0 1, 0 0)))'::geometry geom
SELECT 2 as id, 'TIN(((0 0, 1 1, 0 1, 0 0)))'::geometry geom
union all
SELECT 'TRIANGLE EMPTY'::geometry geom
SELECT 3 as id, 'TRIANGLE EMPTY'::geometry geom
)
select '#4399', 'ST_AsMVTGeom', ST_AsMVTGeom(geom, ST_MakeBox2D(ST_Point(0, 0), ST_Point(32, 32)))::text from geom;
select '#4399', id, 'ST_AsMVTGeom', ST_AsText(ST_AsMVTGeom(geom, ST_MakeBox2D(ST_Point(0, 0), ST_Point(32, 32))))::text from geom order by id asc;

View File

@ -142,6 +142,6 @@ Ag==
#4348Reversed2|t
#4348Point|t
#4348Crash|t
#4399|ST_AsMVTGeom|011100000001000000040000000000000000000000000000000000B0400000000000000000000000000000AF400000000000006040000000000000AF400000000000000000000000000000B040
#4399|ST_AsMVTGeom|011100000001000000040000000000000000000000000000000000B0400000000000000000000000000000AF400000000000006040000000000000AF400000000000000000000000000000B040
#4399|ST_AsMVTGeom|
#4399|1|ST_AsMVTGeom|TRIANGLE((0 4096,128 3968,0 3968,0 4096))
#4399|2|ST_AsMVTGeom|TRIANGLE((0 4096,128 3968,0 3968,0 4096))
#4399|3|ST_AsMVTGeom|