Skip to content

Commit b710471

Browse files
committed
.
0 parents  commit b710471

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

README.md

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
### geos/wasm
2+
3+
GEOS and WebAssembly.
4+
5+
Braindump:
6+
7+
I don't think WebAssembly will constitute a big performance advantage for
8+
geographical operations. However, what I do want is battle-tested geometry
9+
operations. I love Turf, and continue to contribute to Turf, but a lot of Turf's
10+
geometry algorithms are implemented from scratch and aren't nearly as robust as
11+
GEOS.
12+
13+
Then Turf uses JSTS for a few of its operations. JSTS - JavaScript port of JTS,
14+
which is a port of GEOS - has gotten a lot better. Maybe JSTS is the real best
15+
option: it gives roughly the code of GEOS, albeit removed two steps from the
16+
original, but doesn't have the full serialization cost of a WASM library.
17+
18+
That said, JSTS is large - we've been trying to remove it from Turf for years
19+
and years, and it's not _exactly_ the same set of bugs as GEOS. If I have bugs,
20+
I want all of the GEOS things to have bugs! And the roaring success of, say,
21+
Shapely, indicates that GEOS's level of bugs is pretty tolerable.
22+
23+
So, the goal of GEOS/WASM is that maybe:
24+
25+
- We can get the same features/bugs as GEOS, with fewer steps to the source than
26+
JSTS.
27+
- We can just use GEOS for a lot of stuff.
28+
- Maybe it'll be fast, or small? I don't really know, this is all TBD. I've
29+
tinkered with WebAssembly but don't know that much about it.
30+
31+
## Other routes
32+
33+
- Maybe rust-geo is robust? But it [doesn't have
34+
buffering](https://github.com/georust/geo/issues/641), so probably a no-go.
35+
36+
## Implementation options
37+
38+
- Emscripten: oldest and most established option.
39+
- Zig: I like Zig, and maybe this would make the toolchain simpler, and I'd much
40+
prefer to write Zig than C or C++. But on the
41+
other hand, maybe it'd make the process way less documented.
42+
- Clang: looks like it does WASM directly, too. Looks like Emscripten _uses_
43+
LLVM's native support now.
44+
45+
## Notes
46+
47+
Okay, so step one is as painful as expected. Getting the basic GEOS example to compile
48+
using any tool is hard. I can't get it compiled with Zig, Emscripten or cc. It's because
49+
of import paths and stuff. I haven't messed with C in ages.
50+
51+
Looks like there are other people compiling GEOS as a prereq for other stuff.
52+
53+
- https://github.com/bugra9/gdal3.js
54+
55+
Okay, so far seeing:
56+
57+
- I'll need to compile GEOS first, then compile the bindings per the [docs](https://emscripten.org/docs/compiling/Building-Projects.html#using-libraries).
58+
Trying to compile GEOS separately isn't working yet.
59+
60+
```
61+
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
62+
```

build.sh

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FLAGS=`geos-config --cflags`
2+
LIBS=`geos-config --clibs`
3+
4+
5+
cc $LIBS hello_world.c $FLAGS -o hello_world
6+
emcc $LIBS hello_world.c $FLAGS -o hello_world

hello_world

33.4 KB
Binary file not shown.

hello_world.c

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* geos_hello_world.c */
2+
3+
#include <stdio.h> /* for printf */
4+
#include <stdarg.h> /* for va_list */
5+
6+
/* Only the CAPI header is required */
7+
#include <geos_c.h>
8+
9+
/*
10+
* GEOS requires two message handlers to return
11+
* error and notice message to the calling program.
12+
*
13+
* typedef void(* GEOSMessageHandler) (const char *fmt,...)
14+
*
15+
* Here we stub out an example that just prints the
16+
* messages to stdout.
17+
*/
18+
static void
19+
geos_msg_handler(const char* fmt, ...)
20+
{
21+
va_list ap;
22+
va_start(ap, fmt);
23+
vprintf (fmt, ap);
24+
va_end(ap);
25+
}
26+
27+
int main()
28+
{
29+
/* Send notice and error messages to the terminal */
30+
initGEOS(geos_msg_handler, geos_msg_handler);
31+
32+
/* Read WKT into geometry object */
33+
GEOSWKTReader* reader = GEOSWKTReader_create();
34+
GEOSGeometry* geom_a = GEOSWKTReader_read(reader, "POINT(1 1)");
35+
36+
/* Convert result to WKT */
37+
GEOSWKTWriter* writer = GEOSWKTWriter_create();
38+
char* wkt = GEOSWKTWriter_write(writer, geom_a);
39+
printf("Geometry: %s\n", wkt);
40+
41+
/* Clean up allocated objects */
42+
GEOSWKTReader_destroy(reader);
43+
GEOSWKTWriter_destroy(writer);
44+
GEOSGeom_destroy(geom_a);
45+
GEOSFree(wkt);
46+
47+
/* Clean up the global context */
48+
finishGEOS();
49+
return 0;
50+
}

0 commit comments

Comments
 (0)