This is version 0.2.x of erlgeom.
Breaking Changes
Compared to its predecessors in version 0.1.x (See forks) this version introduces a breaking change in geometry construction. Where in previous versions you would create a geometry object like this
1> Geom1 = erlgeom:to_geom({'LineString', [[3,3],[10,10]]}),
You know have to explicietely check for errors in construction, i.e.
2> {ok, Geom1} = erlgeom:to_geom({'LineString', [[3,3],[10,10]]}),
In case of an error erlgeom:to_geom
returns ``{error, []}` with a list of error messages created by GEOS.
New Features
You can now use prepared geometries.
prepared_intersects_test_() ->
{ok, Geom1} = erlgeom:to_geom({'LineString', [[1,1],[10,10]]}),
{ok, Geom2} = erlgeom:to_geom({'LineString', [[2,2],[9,9]]}),
{ok, PreparedGeom1} = erlgeom:prepare(Geom1),
[{"Prepared Linestring intersects works", ?_assert(erlgeom:prepared_intersects(PreparedGeom1, Geom2))}].
See src/erlgeom.erl for more examples.
Install
Build it with:
rebar co
Run tests with:
rebar eunit
Dependency
This version of erlgeom depends on GEOS Version ~> 2.5. This is due to the reentrant error reporting methods available starting with this version.
On MacOSX
If you use brew it's as easy as
brew install geos
On Ubuntu 16.04 Xenial
The provided version of libgeos is 1.5.0, install it with
apt-get install libgeos-dev
On Ubuntu 14.04 Trusty
Use the ubuntugis-unstable PPA or install from source.
On Windows
You need to have GEOS installed, let's say it was installed to C:\cygwin\opt\couchbase
.
Open a shell which has all compilers and the MSVC environment set up (e.g. the Windows SDK 7.1 Command Prompt).
Now set it up so that GEOS and Erlang can be found:
SET INCLUDE=%INCLUDE%;C:\cygwin\opt\couchbase\include
SET LIB=%LIB%;C:\cygwin\opt\couchbase\lib
SET PATH=%PATH%;C:\cygwin\opt\couchbase\bin;C:\erl5.9.1\bin
And finally compile the whole thing:
rebar compile
Examples
Here's an example session in the erlang shell. See the src/erlgeom.erl file for more examples.
$ erl -pa ebin
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
Eshell V5.8.4 (abort with ^G)
1> {ok, Geom1} = erlgeom:to_geom({'LineString', [[3,3],[10,10]]}),
1> {ok, Geom2} = erlgeom:to_geom({'LineString', [[1,1],[7,7]]}),
1> erlgeom:intersects(Geom1, Geom2).
true
2> {ok, Geom1} = erlgeom:to_geom({'LineString', [[3,3],[10,10]]}),
2> {ok, Geom2} = erlgeom:to_geom({'LineString', [[1,1],[7,7]]}),
2> Geom3 = erlgeom:intersection(Geom1, Geom2),
2> erlgeom:from_geom(Geom3).
{'LineString', [[3,3],[7,7]]}
3> WktReader = erlgeom:wktreader_create(),
3> Geom2 = erlgeom:wktreader_read(WktReader,
3> "POLYGON((0 0, 1 1, 1 2, 1 1, 0 0))"),
3> erlgeom:is_valid(Geom2).
false
4> {ok, Geom1} = erlgeom:to_geom({'LineString', [[4,4],[10,10]]}),
4> Geom2 = erlgeom:get_centroid(Geom1),
4> erlgeom:from_geom(Geom2).
{'Point',[7.0,7.0]}
5> {ok, Geom1} = erlgeom:to_geom({'LineString', [[4,4], [4.5, 4.5], [10,10]]}),
5> erlgeom:topology_preserve_simplify(Geom1, 1).
{'LineString',[[4.0,4.0],[10.0,10.0]]}
6> {ok, Geom1} = erlgeom:to_geom({'LineString', [[4,4], [4.5, 4.5], [10,10]]}),
6> erlgeom:is_valid(Geom1).
true
7> WktReader = erlgeom:wktreader_create(),
7> Geom = erlgeom:wktreader_read(WktReader, "POINT(10 10)"),
7> erlgeom:from_geom(Geom).
{'Point',[10.0,10.0]}
8> WktReader = erlgeom:wktreader_create(),
8> Geom = erlgeom:wktreader_read(WktReader, "POINT(10.0 10.0)"),
8> WkbWriter = erlgeom:wkbwriter_create(),
8> Bin = erlgeom:wkbwriter_write(WkbWriter, Geom),
8> WkbReader = erlgeom:wkbreader_create(),
8> Geom2 = erlgeom:wkbreader_read(WkbReader, Bin),
8> erlgeom:from_geom(Geom2).
{'Point',[10.0,10.0]}
9> WkbReader = erlgeom:wkbreader_create(),
9> Geom = erlgeom:wkbreader_readhex(WkbReader,
9> "010100000000000000000024400000000000002440"),
9> erlgeom:from_geom(Geom).
{'Point',[10.0,10.0]}
10> WktReader = erlgeom:wktreader_create(),
10> Geom = erlgeom:wktreader_read(WktReader, "POINT(10 10)"),
10> WktWriter = erlgeom:wktwriter_create(),
10> erlgeom:wktwriter_write(WktWriter, Geom).
"Point(10.0000000000000000 10.0000000000000000)"
11> WktReader = erlgeom:wktreader_create(),
11> Geom = erlgeom:wktreader_read(WktReader, "POINT(10.0 10.0)"),
11> WkbWriter = erlgeom:wkbwriter_create(),
11> erlgeom:wkbwriter_write(WkbWriter, Geom).
<<1,1,0,0,0,0,0,0,0,0,0,36,64,0,0,0,0,0,0,36,64>>
12> WktReader = erlgeom:wktreader_create(),
12> Geom = erlgeom:wktreader_read(WktReader, "POINT(10.0 10.0)"),
12> WkbWriter = erlgeom:wkbwriter_create(),
12> erlgeom:wkbwriter_writehex(WkbWriter, Geom).
"010100000000000000000024400000000000002440"