During today's bugstomp I picked up GEOT-5830
<https://osgeo-org.atlassian.net/projects/GEOT/issues/GEOT-5830>to look at
as it seemed a pretty easy bug to start with, looked like a simple case of
the FIDindex not being updated to allow for the fact a feature had been
deleted.

Boy, was I wrong there, this looks like a whole nasty can of worms instead.
To start with it looked like we already had a test covering this issue
<https://github.com/geotools/geotools/blob/master/modules/plugin/shapefile/src/test/java/org/geotools/data/shapefile/fid/FidQueryTest.java#L155>
(but then how could the user be seeing it?) - so I poked around a little
and scratched my head, I came up with the following test to see what was
happening:

/**
     * Attempt to test GEOT-5830 User reports that deleting a feature,
re-requesting the data gives
     * a duplicate FID and the subsequent attempt to delete fails due to
corrupt FIX
     *
     * @throws Exception
     */
    @Test
    public void testDeleteCloseAndRerequestFID() throws Exception {
        SimpleFeature feature;
        SimpleFeatureCollection allfeatures = featureStore.getFeatures();
        int size = allfeatures.size();
        try (SimpleFeatureIterator features = allfeatures.features()) {
            feature = features.next();
        }
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
        Id fidFilter = ff.id
(Collections.singleton(ff.featureId(feature.getID())));

        featureStore.removeFeatures(fidFilter);
        fids.remove(feature.getID());
        assertEquals((size - 1), featureStore.getCount(Query.ALL));
        assertEquals(fids.size(), featureStore.getCount(Query.ALL));

        featureStore.getDataStore().dispose();
        URL url = backshp.toURI().toURL();
        ds = new ShapefileDataStore(url);
        numFeatures = 0;
        featureStore = (SimpleFeatureStore) ds.getFeatureSource();
        assertEquals((size - 1), featureStore.getCount(Query.ALL));

        SimpleFeatureCollection features2 =
featureStore.getFeatures(fidFilter);
        assertEquals("wrong number of features", 0, features2.size());
        try (SimpleFeatureIterator features = features2.features()) {
            assertFalse("found fid", features.hasNext());
        }

        // when we fetch the features again the first feature is
archsites.1 again!
        // yet the IndexedShapeReader tries very hard to avoid this!
        try (SimpleFeatureIterator features = allfeatures.features()) {

            SimpleFeature f = (SimpleFeature) features.next();
            assertFalse(fidFilter.evaluate(f));
        }
        // but not if we use the fid filter
        features2 = featureStore.getFeatures(fidFilter);
        assertEquals("wrong number of features", 0, features2.size());
        try (SimpleFeatureIterator features = features2.features()) {
            assertFalse("found fid", features.hasNext());
        }
        this.assertFidsMatch();
    }

And this one fails "nicely" in exactly the way the user reports. Unless we
also make our request using a FIDFilter again in which case it does work
(actually this test is the reverse of the users use case but you see what I
mean) - so it seems that a Shapefile IndexedFidWriter and a
IndexedFIDReader keeps track of deleted features and doesn't reuse the FID
(which seems like a good thing) while a "normal" ShapefileFeatureReader
doesn't know anything about the missing FID and returns a new list of fids
which include the deleted ones (pointing to the next feature).

So, now I'm stuck trying to work out which is the "correct" behaviour -
should deleted FIDs be discarded? and if so for how long? just until the
next time the .fix is created? or forever? Or should deleting a feature
renumber all the features immediately?

Still reading? cool feel free to chip in here, on the PR
<https://github.com/geotools/geotools/pull/2338> or the issue
<https://osgeo-org.atlassian.net/projects/GEOT/issues/GEOT-5830>.

Thanks

Ian



-- 
Ian Turton
_______________________________________________
GeoTools-Devel mailing list
GeoTools-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to