postgis/lwgeom
Sandro Santilli 8bf9b37d4a bug fixed in lwgeom_mem_size
git-svn-id: http://svn.osgeo.org/postgis/trunk@706 b70326c6-7e19-0410-871a-916f4a2858ee
2004-08-20 09:31:32 +00:00
..
regress removed user connect command 2004-06-08 17:40:34 +00:00
.cvsignore Added y.output 2004-06-04 15:24:39 +00:00
lwgeom.h fixed some of the buch of broken comments 2004-08-19 09:28:37 +00:00
lwgeom.sql.in added extent(lwgeom) and support functions. 2004-08-17 15:27:47 +00:00
lwgeom_api.c some indentation fixes 2004-08-19 13:16:16 +00:00
lwgeom_box2dfloat4.c some indentation fixes 2004-08-19 13:16:16 +00:00
lwgeom_btree.c fixed typos 2004-08-19 13:10:13 +00:00
lwgeom_estimate.c cpp checks updated to use 80 instead of 75 for USE_VERSION 2004-08-19 13:54:15 +00:00
lwgeom_functions_analytic.c Empty files - preparing for writting actual code. 2004-03-05 18:25:34 +00:00
lwgeom_functions_basic.c bug fixed in lwgeom_mem_size 2004-08-20 09:31:32 +00:00
lwgeom_geos.c Empty files - preparing for writting actual code. 2004-03-05 18:25:34 +00:00
lwgeom_gist.c Added finite coordinate check. 2004-08-19 14:05:24 +00:00
lwgeom_inout.c indentation fixes 2004-08-19 14:16:41 +00:00
lwgeom_transform.c Empty files - preparing for writting actual code. 2004-03-05 18:25:34 +00:00
lwgparse.c added 'static' modifiers for the 'error' function, possibly clashing with some other declaration 2004-06-08 08:20:40 +00:00
lwpostgis.sql.in cpp checks updated to use 80 instead of 75 for USE_VERSION 2004-08-19 13:54:15 +00:00
Makefile added lwpostgis.sql build rule 2004-08-19 14:15:09 +00:00
MISSING_OBJECTS mem_size removed from list 2004-08-19 13:57:38 +00:00
README minor changes 2004-04-28 22:59:56 +00:00
stringBuffer.c Added a cstring(lwgeom) function that returns WKT! 2004-04-07 23:12:31 +00:00
stringBuffer.h Added a cstring(lwgeom) function that returns WKT! 2004-04-07 23:12:31 +00:00
wktparse.h Initial working version - based on Ralph Masons WKT and WKB parser/writer. 2004-04-26 23:05:20 +00:00
wktparse.lex Added missing prototypes. 2004-06-07 09:16:06 +00:00
wktparse.y added semicolumns at end of blocks 2004-06-04 15:23:01 +00:00
wktunparse.c Added missing prototypes. 2004-06-07 09:16:06 +00:00

Welcome to the Initial version of LWGEOM.

More information is available on the PostGIS user's mailing list and 
the PostGIS developer's mailing list.  

See "Installing', below, on how to build.


Differences
-----------

The LWGEOM is very much like the original PostGIS GEOMETRY type.  The 
main differences are:

a) LWGEOMs are much smaller than the PostGIS GEOMETRY
b) LWGEOMs natively support 2d, 3d, and 4d points
c) LWGEOMs are indexed using single-precision bounding boxes.  This
   make the indexes significantly smaller than PostGIS GEOMETRY
   indexes.
d) LWGEOMs are internally very similar to OGC WKB   
e) The "normal" view of LWGEOMs is OGC WKB - PostGIS GEOMETRY is OGC WKT
f) PostGIS geometries have a built-in BOX3D.  LWGEOMs have an *optional*
   BOX2D (see below).


Also included with the LWGEOMs is a type called 'box2d'.  This is
very similar to PostGIS BOX3D type:

a) BOX2Ds are 2D - BOX3D is 3D
b) BOX2Ds are represented by single-precision floating point numbers,
   while BOX3Ds are double-precision floating point numbers.
c) BOX2Ds will sometimes be slightly larger than you might expect.
   This is because the conversion from double-precision to 
   single-precision is inexact.  When this happens, the BOX2D will
   automatically expand itself.
   

Installing
----------
1. Build PostGIS normally
2. Go into the "lwgeom/" directory underneath your PostGIS installation
3. type 'make'
4. Install PostGIS normally into your database
5. Install LWGEOM into your database using the produced "lwgeom.sql" file.
     \i lwgeom.sql
6. If you don't get any errors, LWGEOM is installed

Testing
-------
1. type this in your database:
      SELECT asText('POINT(0 0)'::lwgeom);
2. it should respond with
        POINT(0 0)
   if it didn't, LWGEOM did not install properly.
3. There are three regression tests to run.  They are located
   in the "lwgeom/regress/" directory.
      ./run_regress
      ./run_regress2
      ./run_regress3
   When you run these, it should be obvious if it passes or
   fails.


Usage
-----

There are not many actual LWGEOM functions available.  Currently, there
are:

1. all the functions necessary to support the BOX2D and LWGEOM types
2. functions required to build indexes on LWGEOMs
3. conversion and casting functions to move between LWGEOM and GEOMETRYs
4. OGC Well Known Text (WKT) and OGC Well Known Binary (WKB) parsing and
   writing functions (Thanks to Ralph Mason).
   
This means you can do most normal things with LWGEOMs.


-- create a simple table.  Notice that the_geom column is of
--  type 'lwgeom'
CREATE TABLE lwgeom_test (the_geom lwgeom, id int);

--insert a geometry into the table (WKT version)
INSERT INTO lwgeom_test VALUES ('POINT(1 1)', 1);

-- insert a geometry into the table (WKB version)
--  WKB is usually used by programs NOT humans
INSERT INTO lwgeom_test VALUES ('0101000000000000000000F03F000000000000F03F', 2);


-- See whats in the table:
-- NOTICE that the 'normal' view of LWGEOMs is WKB - NOT WKT
SELECT * FROM lwgeom_test;
                  the_geom                  | id 
--------------------------------------------+----
 0101000000000000000000F03F000000000000F03F |  1
 0101000000000000000000F03F000000000000F03F |  2
(2 rows)

-- View it as WKT
SELECT asText(the_Geom),id FROM lwgeom_test;
   astext   | id 
------------+----
 POINT(1 1) |  1
 POINT(1 1) |  2
(2 rows)


   
-- explicit conversions.

--  PostGIS -> LWGEOM
SELECT   lwgeom('POINT(0 0)'::geometry);

--  LWGEOM --> PostGIS
SELECT   geometry('POINT(0 0)'::lwgeom);

-- You can run  PostGIS functions on LWGEOMs.  All PostGIS functions
--  are runnable this way.
-- NOTE: this is doing a hidden LWGEOM->PostGIS GEOMETRY step
--       This is actually running the length(GEOMETRY) function.
SELECT length('LINESTRING(0 0, 0 10)'::lwgeom);
    length 
   --------
        10
   (1 row)
   

-- Find the BOX2D bounding box of a geometry
SELECT box2d('LINESTRING(0 0, 0 10)'::lwgeom);
     box2d     
---------------
 BOX(0 0,0 10)
(1 row)




Building Indexes
----------------

This is very similar to PostGIS 
(use "GIST_LWGEOM_OPS" instead of GIST_GEOMETRY_OPS):

CREATE INDEX <name> ON <table> USING GIST (<lwgeom column> GIST_LWGEOM_OPS);

ie. CREATE INDEX lwgeom_test_lwgeom_idx ON lwgeom_test
	USING GIST ( the_geom GIST_LWGEOM_OPS);

Don't forget to VACUUM ANALYSE your table:
VACUUM ANALYSE <table>;

Bounding Boxes
--------------

<this section for advanced users.  Ignore it if you don't understand
 what its saying.>

Bounding boxes are optional in LWGEOMs.  By not having one, you are
saving a small amount of space per LWGEOM geometry (16 bytes).

If you are cross-joining tables, you might want to explicitly put a
bounding box inside the LWGEOM to make it faster.

DROP INDEX <lwgeom index name>;
UPDATE <table> SET <lwgeom column> = AddBBOX(<lwgeom column>);
CREATE INDEX <lwgeom index name> ON <table> USING GIST 
    (<lwgeom column> GIST_LWGEOM_OPS);
VACUUM ANALYSE <table>;


A cross-joining query looks like this:

SELECT  nodes1.id as node_id1,
        nodes2.id as node_id2
FROM    nodes nodes1,
        nodes nodes2
WHERE   nodes1.the_geom && nodes2.the_geom;

For every row in nodes, postgresql searches all the rows in nodes
for ones that overlap that lwgeom .  If nodes has 10,000 rows, 
this query will do 10,000 index searches - THAT A LOT OF WORK.

Pre-computing the bounding boxes makes this type of query much faster.

We have not currently decided if bounding boxes should default to
being inside the LWGEOM or not.  Currently, its set to not being
automatically there. This may change in the future.  If you have
an opinion, post it to the mailing list.


Space Saving
------------

LWGEOM indexes are approximately 40% smaller than PostGIS indexes.

A LWGEOM 'POINT(0 0)' takes up 21 bytes, a POSTGIS 'POINT(0 0)' takes
up 140 bytes.  This shows that LWGEOMs have a much smaller overhead.

LWGEOMs will store 2D points as 2 double precision numbers (16 bytes) -
PostGIS will store 2D points with 3 numbers (24 bytes).   This can be 
another big savings.


Future Development
-------------------

Testing Testing Testing
Native LWGEOM -> GEOS converter
Move most of the PostGIS functions so they run directly on LWGEOMs (with
out conversion)

Stay tuned to the PostGIS mailing lists.