Jody,

I looked more into the featurewriting stuff that we talked about last night -- here's what I found.

I think there's a problem in how "Feature" implements "equals". Here's where it came up.

I wrote a tiny program that updates a table in my database:

/**
*   similiar to:
* update <table name> set <destination geometry> = generalize(<source geometry name>,<tolerance>);
*
* but the generalize() function in here is much "smarter" than the one in postgis
...
*/

Here's my main loop (taken from the documentation page "http://docs.codehaus.org/display/GEOTOOLS/Data+Writing";):

private void process() throws Exception
{
     FeatureWriter aWriter = ds.getFeatureWriter(table_name,
               ((FeatureStore) ds.getFeatureSource(table_name))
                       .getTransaction());
while (aWriter.hasNext())
       {
           Feature f = aWriter.next();  // get a feature
           Geometry g = (Geometry) f.getAttribute(source_column);
Geometry g_gen = generalize(g,tolerance); // less point!!
           f.setAttribute(dest_colum,g_gen);  // modify it
           aWriter.write();  // write it to DB
       }
       aWriter.close();
}

Here's my problems.

1. This isnt happening in a transaction - it put my database into an invalid state :(

2. DOCUMENTATION: its really weird seeing your writer acting as a reader. Might want to emphasis that in the documentation. I put a note at the top so others wouldnt be confused. You should also include a brief summary of FeatureStore/FeatureSource/FeatureXYZ since that is also confusing (ie. you ask for a FeatureSource, but you really get a FeatureStore!).

3. Unfortunately, my program doesnt work! As I mentioned, this has to do with Feature.equals(). When the "aWriter.write();" occurs it gets passed off to the JDBCFeatureWriter class which quickly does a:
       live.equals(current)   on line 193 (2.2.x)
       in DefaultFeature (line 480) we see this:
NOTE: THIS CODE IS DUPLICATED IN DataUtilities#attributesEqual()

                       if (!((Geometry) attributes[i]).equals(
                                   (Geometry) otherAtt)) {
                           return false;
                       }

      I dont think this is the correct behavior.

     a) this takes a *long time* to compute
b) if your geometries are invalid, it will likely throw an exception and you're screwed (thats what happened to me) c) Geometry.equals(Geometry) probably doesnt do what you think/want it to do.
         For example, these 3 geometries are all equal:
         LINESTRING(0 0, 10 10)
LINESTRING(0 0, 5 5, 10 10) // extra point that coincident with the segment
         LINESTRING(10 10,0 0) // backwards
NOTE: this means you cannot "flip" the direction of lines in Geotools -- it'll never get written out.

The alternative is to use Geometry.equalsExact(Geometry). This is a "relatively" quick method that checks to see if 2 geometries are the same type, have the same number of points, and all the points are equal and in the same order. Basically, what most people mean when they say two geometries are equal.

So, how about changing all occurances of Geometry.equals(Geometry) with Geometry.equalsExact(Geometry)? Is this going to cause problems?
I found these two places where it happens, but I'm sure there are others.


dave




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Geotools-devel mailing list
Geotools-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to