From b7104719d7edffe1588935838876c66558097a4f Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 26 Dec 2022 12:04:38 -0500 Subject: [PATCH] . --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ build.sh | 6 +++++ hello_world | Bin 0 -> 34152 bytes hello_world.c | 50 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 README.md create mode 100755 build.sh create mode 100755 hello_world create mode 100644 hello_world.c diff --git a/README.md b/README.md new file mode 100644 index 0000000..c52d5f7 --- /dev/null +++ b/README.md @@ -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. + +## 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 +``` diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..1daf4e4 --- /dev/null +++ b/build.sh @@ -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 diff --git a/hello_world b/hello_world new file mode 100755 index 0000000000000000000000000000000000000000..ade4c35b1121ea6a5050efa0933dd336c9867f41 GIT binary patch literal 34152 zcmeI5U2IfU5XaBmEfkP`NKNsRt|TB3(ozADqHs%F+6L1$rH1N54{i6hyK%c)cej>G zBMTLU@E}W;1QH%1`>HSyO4r2=iat=FCrnnng1lS zXJ*cs*>ivQyw15l-MM{lrVyGSagoj<^<@aLLwLv%;u+E^QYq_7D=XfvsITQ{x~Syz z&;uUV*+~nfY^Z2#NS{{udU{M){uBzc(w3A+88tRXEr$kYy(O#7hxx@?!ahIOgk*@= zgiVH&k!V*-WFq9OH*<|yZ;!QteS5uWRy|^RN@%j z6lCRhl}jpRd&u@09$Ie`tyQ9%`IaZ9k}=MVW0U9Xjp~~973J0AXC&s>7x^qcJ`^Op zA9a3|C&V%#V!S_o%T+Y7)bgvg39*F2%;ssHCO?P9;q5{sX?%jTj+BM#vGQ7eX8S(L zO_NT_=Xy@brhtc(bBnqn;i7=QrO4Y8@RHB+94Y4|l84URTfXYz;j=v}Js;oQ{W8To zr2PLvWRa1jY~F{^mbn+vpq`I?k_GfAT!+uOUHE_bOz<2(hxQ~_)I?FJGg{;ebr>yS zqgy%cMku0oM>}L&wiXr_(oX#?l%V$iDvjfHgm{U_Q=Rc=qIDa3B2lBGaP4H45c4UA z_qlnS5YuQ}X!*>Y%n~n^wg~-P)0AYHOvw+eE*+ zAldJhNj2BGI!?X0iT=Jh$>lVT=84p3o}T)&uPM2L{Tz|HnWLv}xkY?|CQ`JmJ>uZ% z_)1krCg-XgJw<(_RHG?L{iu|qr}Ai|p4i0bZ2k1umhu7GUwp_dFWv7Gv`=kdtW3m5 zGli;qm~5^+nyII*x%JdM${X8KIzVex4)voB=DPHha1~rq_Eeia!)9mO>{&KD-)28+ zv*+0Cxi)*g&0b`)3r)MOwz{TaL9wTJp{O*dWj7k`De=sU%-~nXEwj(FL1G`d*Oz;N ziM7%!tG}FmvzJ+;zT1h0TdS=;H)ck1W1LT&xiQsmOryCVH)gh5=f=2io98pFk$ZdD zpKgt6bL4YBHAzhU;s*pk00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1VG@C1U$5&jxf&jA8zjMyt0~b2o2B5QH3g>Bbfq<4zT0+`Jnjrm# z^d@P(CN!P2Q4_8JX)k5S%8J?z>%xX%T71!g^cs<9IMicCHm+}|H=4ahShj|Z=BTx9 zGWw9kwAMROU}M-HeXxKPbr!I~-JBz2n?LA}_;`~-k{LCv&agiiZ4>f6%b8Q#%(^I-31KG0!aqdo5Ojy@wU%>*QyXb(!vL-~gA%(dhOG67~rt z`R1Jt?DJg@G_t9Lzq4-l`CILFzsBJk4!_6Yf8y{zclcjB{0k0$#Pk&jGQ|~#&-Y63 znd18-==2D_M}qH=;QJ%^?g+j&g3lm*`Cep`KJI#tkpIA6D*peEqbA#pP(*e_+NG~K z=nWWQqBJRYew#T&CtyEC#?Q!86r=Z{eJET+-ldM1m*yL-EJEKm>~SgVR_NabeSA{$ z8G%4Zc89_NuehH1>*XVb2UZO4y4vz?@gE0*vv+70Pc-#^_QOY~&Xv4={)?^0zG@78 zf2(aMJ){EzF9Qm^T*xvkW%Vw-C|8w8B#$S;~)&H;a mdvBj?^8R>b=z6p=fBB);5=$2+<+*J)lJc#y7uHlv&H5Xus9i4r literal 0 HcmV?d00001 diff --git a/hello_world.c b/hello_world.c new file mode 100644 index 0000000..ab60b7c --- /dev/null +++ b/hello_world.c @@ -0,0 +1,50 @@ +/* geos_hello_world.c */ + +#include /* for printf */ +#include /* for va_list */ + +/* Only the CAPI header is required */ +#include + +/* +* 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; +} \ No newline at end of file