We are building a service for uploading zip-files containing an ESRI-shapefile. The service should be able to read the shapefile and do stuff with its content. So I've built a class that unzips the zip-file to temporary folder (subfolder of System.getProperty("java.io.tmpdir")).
Another class calls the unzip method from the Unzip-class and it then tries to read the unpacked shapefile using Geotools. It uses the Geotools DataStoreFinder.getDataStore(Map params) method to create a datastore from the unzipped shapefile. Here the problem occurs: the getDataStore-method returns null. I tested the URL, it looks allright. The file from which the URL derives exists, is a file and can be read by the application (tested using shapefile.exists(), shapefile.isFile(), shapefile.canRead()). So , what could be wrong? Why do I get null returned?
Here's the (relevant) code:
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.geodan.equus.entity.dataset.BasicFeature;
import com.geodan.equus.exception.EquusException;
import com.geodan.equus.processor.EquusProcessor;
import com.geodan.util.io.UnzipUtils;
import com.vividsolutions.jts.geom.Geometry;
public class ShapefileProcessor implements EquusProcessor
{
private static final File TEMP_UNZIP_DIR = new File(
System.getProperty("java.io.tmpdir") + File.separator
+ "atlas_temp_unzip_dir");
public static Set<BasicFeature> importFeatures(final File zipFile)
throws EquusException
{
// Check if the input file has the zipfile extension
if (!zipFile.getName().endsWith(".zip"))
{
throw new EquusException(
"The file is not a zipfile. It cannot be processed.");
}
// Unzip the file
try
{
UnzipUtils.unzip(zipFile, TEMP_UNZIP_DIR);
}
catch (IOException error)
{
throw new EquusException("The zipfile cannot be unzipped.", error);
}
// Validate whether the unzipped folder contains a shapefile and return it
File shapefile = new File("");
try
{
shapefile = findShapefile(TEMP_UNZIP_DIR);
}
catch (IOException error)
{
throw new EquusException(
"The zipfile does not contain a shapefile. Cannot process its contents.",
error);
}
// Collect the features from the shapefile and put them into an iterator
FeatureIterator<SimpleFeature> featureIterator;
try
{
featureIterator = readShapefile(shapefile);
}
catch (EquusException e)
{
throw new EquusException(e.getMessage(), e);
}
// Create a Set filled with the features in the FeatureIterator
Set<BasicFeature> features = createFeatureSet(featureIterator);
return features;
}
private static File findShapefile(File unzipPath) throws IOException
{
File shapefile = new File("");
// Find first .shp file in the unzip folder
File[] unzippedFiles = unzipPath.listFiles();
for (int i = 0; i < unzippedFiles.length; i++)
{
if (unzippedFiles[i].getName().endsWith(".shp"))
{
shapefile = new File(unzipPath + File.separator
+ unzippedFiles[i].getName());
break;
}
}
if (shapefile.toString() == "")
{
throw new IOException("No shapefile present in '" + unzipPath
+ "'.");
}
return shapefile;
}
private static FeatureIterator<SimpleFeature> readShapefile(File shapefile)
throws EquusException
{
// Collects the features from a shapefile and puts them into an iterator
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection;
try
{
Map<String, URL> connectParameters = new HashMap<String, URL>();
connectParameters.put("url", shapefile.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(connectParameters);
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = dataStore.getFeatureSource(typeName);
featureCollection = featureSource.getFeatures();
}
catch (Exception e)
{
throw new EquusException(
"Features cannot be retrieved from the shapefile.", e);
}
return featureCollection.features();
}
private static Set<BasicFeature> createFeatureSet(
FeatureIterator<SimpleFeature> featureIterator)
{
SimpleFeature simpleFeature = null;
Set<BasicFeature> features = new HashSet<BasicFeature>();
while (featureIterator.hasNext())
{
simpleFeature = featureIterator.next();
BasicFeature feature = new BasicFeature();
feature.setGeometry((Geometry) simpleFeature.getDefaultGeometry());
features.add(feature);
}
return features;
}
}
Just use the constructor of ShapefileDataStore
like this:
// URL url = file.toURI().toURL();
DataStore shapefileStore = new ShapefileDataStore(url)
Though your code seems correct, I have found a slightly different implementation of the crucial lines in our codebase:
Map<String, Object> map = new HashMap<>();
map.put(ShapefileDataStoreFactory.URLP.key, url);
map.put(ShapefileDataStoreFactory.CREATE_SPATIAL_INDEX.key, Boolean.TRUE);
DataStore shapefileStore = DataStoreFinder.getDataStore(map);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With