Details
Description
The first field value asked in a DenseFeature is always returning a null value, the next calls on the same feature are successful.
Loading a sample shapefile from here
http://export.openstreetmap.fr/contours-administratifs/communes/92-Hauts-de-Seine.shp.tar.gz
If I attempt to query the values of a Feature this way : "REF_INSEE", "COMMUNE", "CODE_POSTA",
I will receive : null, “a city name”, “a zip code”.
If I try to query this way : "CODE_POSTA", "REF_INSEE", "COMMUNE",
I will receive : null, “an INSEE code”, “a city name”.
Involved method :
@Override public Property getProperty(final String name) throws IllegalArgumentException { ArgumentChecks.ensureNonNull("name", name); final int index = getIndex(name); if (properties instanceof Property[]) { final Property property = ((Property[]) properties)[index]; if (property != null) { return property; } } else { wrapValuesInProperties(); } final Property property = createProperty(name); properties[index] = property; return property; }
hypothesis :
after the init call of
wrapValuesInProperties();
the method assumes that it has done the same work it would have done with
final Property property = ((Property[]) properties)[index];
but it’s not the case.
The following unit test will show the problem :
package org.apache.sis.storage.shapefile; import static org.junit.Assert.*; import java.io.*; import org.apache.sis.storage.*; import org.junit.*; import org.opengis.feature.*; import org.opengis.test.*; /** * Issues with features. */ public class IssuesWithFeaturesTest extends TestCase { /** * Issue : the first property red by DenseFeature is null. * @throws DataStoreException if unable to find or read the shapefile. * @throws IOException if unable to find or read the shapefile. */ @Test public void issueFirstPropertyNull() throws IOException, DataStoreException { ShapeFile shapefile = new ShapeFile("src/test/resources/org/apache/sis/storage/shapefile/92-Hauts-de-Seine.shp"); Feature feature = shapefile.FeatureMap.values().iterator().next(); // The shapefile has 36 features, take the first one. String city = (String)feature.getProperty("COMMUNE\0\0\0\0").getValue(); String refInsee = (String)feature.getProperty("REF_INSEE\0\0").getValue(); String zipCode = (String)feature.getProperty("CODE_POSTA\0").getValue(); // The first feature property you read (city here) will return a null value. assertNotNull("The city should have an INSEE reference.", refInsee); assertNotNull("The city should have a zip code.", zipCode); assertNotNull("The city should have a name.", city); } }