Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically load GEOSPreparedContainsXY where available #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions geos_perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>

#include "geos_perf.h"
#include <dlfcn.h>

void* geos_lib_handle;

/************************************************************************
* REGISTER NEW TESTS HERE
Expand Down Expand Up @@ -134,6 +136,31 @@ geomlist_print(GEOSGeometryList* gl)
GEOSWKTWriter_destroy(writer);
}

/************************************************************************
* Utility functions to probe GEOS capabilities
*/

int geos_version_major() {
const char* geos_ver = GEOSversion();

return atoi(geos_ver);
}

int geos_version_minor() {
const char* geos_ver = GEOSversion();
size_t nchar = strlen(geos_ver);

size_t dot1 = 0;

for (size_t i = 0; i < nchar; i++) {
if (geos_ver[i] == '.') {
dot1 = i;
break;
}
}

return atoi(geos_ver + dot1 + 1);
}

/************************************************************************
* Utility functions to polyfill old GEOS versions
Expand Down Expand Up @@ -287,9 +314,15 @@ int
main(int argc, char *argv[])
{
initGEOS(geos_log_stderr, geos_log_stderr);

log_stderr("VERSION [GEOS %s]\n", GEOSversion());

geos_lib_handle = dlopen("libgeos_c.so", RTLD_LAZY);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, will need to do something about file extensions, "libgeos_c.dylib" is what I've got. There is a dlopen() documented so that part might work. I will experiemnt.

if (!geos_lib_handle)
{
log_stderr("Failed to dynamically load libgeos_c.so");
}


gp_config_func* config_func;
for (config_func = gp_config_funcs; *config_func != NULL; config_func++)
{
Expand Down Expand Up @@ -317,6 +350,7 @@ main(int argc, char *argv[])
}

finishGEOS();
dlclose(geos_lib_handle);

return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions geos_perf.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ size_t geomlist_size(GEOSGeometryList* gl);
GEOSGeometry* geomlist_pop(GEOSGeometryList* gl);
const GEOSGeometry* geomlist_get(GEOSGeometryList* gl, size_t i);

int geos_version_major();
int geos_version_minor();

extern void* geos_lib_handle;

/**
* Read a wkt.gz file, with one wkt geometry per line, gzipped.
* File name is relative to the data directory.
Expand Down
31 changes: 28 additions & 3 deletions geos_perf_test_pip.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <float.h>
#include <dlfcn.h>

#include "geos_perf.h"

Expand All @@ -12,6 +13,7 @@ static GEOSGeometryList watersheds;
static GEOSGeometryList prepared_watersheds;
static GEOSSTRtree* tree;

extern char GEOSPreparedContainsXY(const GEOSPreparedGeometry*, double x, double y);

/* Read any data we need, and create any structures */
static void
Expand Down Expand Up @@ -49,11 +51,36 @@ getGeometryBounds(const GEOSGeometry* g, double* xmin, double* ymin, double* xma
GEOSGeom_destroy(env);
}

static void contains_test_kernel_1(const GEOSPreparedGeometry* prepgeom, double x, double y) {
GEOSGeometry* pt = createPointFromXY(x, y);
char in = GEOSPreparedContains(prepgeom, pt);
GEOSGeom_destroy(pt);
}

static char (*prep_contains_xy)(const GEOSPreparedGeometry* pg, double x, double y) = NULL;

static void contains_test_kernel_2(const GEOSPreparedGeometry* prepgeom, double x, double y) {
prep_contains_xy = dlsym(geos_lib_handle, "GEOSPreparedContainsXY");

if (!prep_contains_xy) {
debug_stderr(0, "%s\n", "Failed to load GEOSPreparedContainsXY");
}

char in = prep_contains_xy(prepgeom, x, y);
}

/* For each watershed, prepare the geometry, then hit it with
a bunch of points for in/out test */
static void
run(void)
{
void (*test_kernel)(const GEOSPreparedGeometry* pg, double x, double y) = NULL;
if (geos_version_major() >= 3 && geos_version_minor() >= 12) {
test_kernel = contains_test_kernel_2;
} else {
test_kernel = contains_test_kernel_1;
}

size_t i;
for (i = 0; i < geomlist_size(&watersheds); i++)
{
Expand All @@ -76,9 +103,7 @@ run(void)
{
for (y = ymin; y < ymax; y += r)
{
GEOSGeometry* pt = createPointFromXY(x, y);
char in = GEOSPreparedContains(prepgeom, pt);
GEOSGeom_destroy(pt);
test_kernel(prepgeom, x, y);
}
}
GEOSPreparedGeom_destroy(prepgeom);
Expand Down