Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcw committed Dec 26, 2022
0 parents commit b710471
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 0 deletions.
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
### geos/wasm

GEOS and WebAssembly.

Braindump:

I don't think WebAssembly will constitute a big performance advantage for
geographical operations. However, what I do want is battle-tested geometry
operations. I love Turf, and continue to contribute to Turf, but a lot of Turf's
geometry algorithms are implemented from scratch and aren't nearly as robust as
GEOS.

Then Turf uses JSTS for a few of its operations. JSTS - JavaScript port of JTS,
which is a port of GEOS - has gotten a lot better. Maybe JSTS is the real best
option: it gives roughly the code of GEOS, albeit removed two steps from the
original, but doesn't have the full serialization cost of a WASM library.

That said, JSTS is large - we've been trying to remove it from Turf for years
and years, and it's not _exactly_ the same set of bugs as GEOS. If I have bugs,
I want all of the GEOS things to have bugs! And the roaring success of, say,
Shapely, indicates that GEOS's level of bugs is pretty tolerable.

So, the goal of GEOS/WASM is that maybe:

- We can get the same features/bugs as GEOS, with fewer steps to the source than
JSTS.
- We can just use GEOS for a lot of stuff.
- Maybe it'll be fast, or small? I don't really know, this is all TBD. I've
tinkered with WebAssembly but don't know that much about it.

## Other routes

- Maybe rust-geo is robust? But it [doesn't have
buffering](https://github.com/georust/geo/issues/641), so probably a no-go.

This comment has been minimized.

Copy link
@frewsxcv

frewsxcv Dec 27, 2022

Don't mind me creeping on your notes here– in case you didn't see, there is a pull request open for geometry buffering: georust/geo#935, but yeah not yet shipped. Hope you're successful in getting GEOS compiled to WASM!

This comment has been minimized.

Copy link
@tmcw

tmcw Dec 27, 2022

Author Owner

Awesome - and I see you're way ahead of me on thinking about wasm bindings. Building on rust-geo, just doing a little idiomatic API wrapper, might be a great strategy. Basically Shapely is what I want - bindings from JavaScript to a well-maintained core library.


## Implementation options

- Emscripten: oldest and most established option.
- Zig: I like Zig, and maybe this would make the toolchain simpler, and I'd much
prefer to write Zig than C or C++. But on the
other hand, maybe it'd make the process way less documented.
- Clang: looks like it does WASM directly, too. Looks like Emscripten _uses_
LLVM's native support now.

## Notes

Okay, so step one is as painful as expected. Getting the basic GEOS example to compile
using any tool is hard. I can't get it compiled with Zig, Emscripten or cc. It's because
of import paths and stuff. I haven't messed with C in ages.

Looks like there are other people compiling GEOS as a prereq for other stuff.

- https://github.com/bugra9/gdal3.js

Okay, so far seeing:

- I'll need to compile GEOS first, then compile the bindings per the [docs](https://emscripten.org/docs/compiling/Building-Projects.html#using-libraries).
Trying to compile GEOS separately isn't working yet.

```
CXXFLAGS="-fexceptions -DRENAME_INTERNAL_LIBTIFF_SYMBOLS -s ERROR_ON_UNDEFINED_SYMBOLS=0" CFLAGS=" -fexceptions -DRENAME_INTERNAL_LIBTIFF_SYMBOLS -s ERROR_ON_UNDEFINED_SYMBOLS=0" emconfigure ./configure --enable-shared=no --disable-inline
```
6 changes: 6 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FLAGS=`geos-config --cflags`
LIBS=`geos-config --clibs`


cc $LIBS hello_world.c $FLAGS -o hello_world
emcc $LIBS hello_world.c $FLAGS -o hello_world
Binary file added hello_world
Binary file not shown.
50 changes: 50 additions & 0 deletions hello_world.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* geos_hello_world.c */

#include <stdio.h> /* for printf */
#include <stdarg.h> /* for va_list */

/* Only the CAPI header is required */
#include <geos_c.h>

/*
* GEOS requires two message handlers to return
* error and notice message to the calling program.
*
* typedef void(* GEOSMessageHandler) (const char *fmt,...)
*
* Here we stub out an example that just prints the
* messages to stdout.
*/
static void
geos_msg_handler(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf (fmt, ap);
va_end(ap);
}

int main()
{
/* Send notice and error messages to the terminal */
initGEOS(geos_msg_handler, geos_msg_handler);

/* Read WKT into geometry object */
GEOSWKTReader* reader = GEOSWKTReader_create();
GEOSGeometry* geom_a = GEOSWKTReader_read(reader, "POINT(1 1)");

/* Convert result to WKT */
GEOSWKTWriter* writer = GEOSWKTWriter_create();
char* wkt = GEOSWKTWriter_write(writer, geom_a);
printf("Geometry: %s\n", wkt);

/* Clean up allocated objects */
GEOSWKTReader_destroy(reader);
GEOSWKTWriter_destroy(writer);
GEOSGeom_destroy(geom_a);
GEOSFree(wkt);

/* Clean up the global context */
finishGEOS();
return 0;
}

0 comments on commit b710471

Please sign in to comment.