use of org.geotoolkit.data.shapefile.indexed.IndexDataReader.ShpData in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method queryQuadTree.
/**
* QuadTree Query
*/
private CloseableCollection<ShpData> queryQuadTree(final AccessManager locker, final Envelope bbox) throws DataStoreException, IOException, TreeException {
CloseableCollection<ShpData> tmp = null;
try {
final QuadTree quadTree = openQuadTree();
final DataReader dr = new IndexDataReader(locker.getSHXReader(useMemoryMappedBuffer));
if ((quadTree != null) && !bbox.contains(quadTree.getRoot().getBounds(new Envelope()))) {
tmp = quadTree.search(dr, bbox);
if (tmp == null || !tmp.isEmpty())
return tmp;
}
if (quadTree != null) {
quadTree.close();
}
} catch (Exception e) {
throw new DataStoreException("Error querying QuadTree", e);
}
return null;
}
use of org.geotoolkit.data.shapefile.indexed.IndexDataReader.ShpData in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method getBBoxAttributesReader.
protected IndexedShapefileAttributeReader getBBoxAttributesReader(final List<AttributeType> properties, final Envelope bbox, final boolean loose, final Hints hints, final boolean read3D, final double[] res) throws DataStoreException {
final AccessManager locker = shpFiles.createLocker();
final double[] minRes = (double[]) hints.get(Hints.KEY_IGNORE_SMALL_FEATURES);
CloseableCollection<ShpData> goodCollec = null;
try {
final QuadTree quadTree = openQuadTree();
if (quadTree != null) {
final ShxReader shx;
try {
shx = locker.getSHXReader(useMemoryMappedBuffer);
} catch (IOException ex) {
throw new DataStoreException("Error opening Shx file: " + ex.getMessage(), ex);
}
final DataReader<ShpData> dr = new IndexDataReader(shx);
goodCollec = quadTree.search(dr, bbox, minRes);
}
} catch (Exception e) {
throw new DataStoreException("Error querying index: " + e.getMessage());
}
final LazySearchCollection<ShpData> col = (LazySearchCollection) goodCollec;
final LazyTyleSearchIterator.Buffered<ShpData> ite = (col != null) ? col.bboxIterator() : null;
// check if we need to open the dbf reader, no need when only geometry
final boolean readDBF = !(properties.size() == 1 && Geometry.class.isAssignableFrom(properties.get(0).getValueClass()));
final AttributeType[] atts = properties.toArray(new AttributeType[properties.size()]);
try {
return new IndexedBBoxShapefileAttributeReader(locker, atts, read3D, useMemoryMappedBuffer, res, readDBF, dbfCharset, minRes, col, ite, bbox, loose, minRes);
} catch (IOException ex) {
throw new DataStoreException(ex);
}
}
use of org.geotoolkit.data.shapefile.indexed.IndexDataReader.ShpData in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method getEnvelope.
@Override
public org.opengis.geometry.Envelope getEnvelope(final Query query) throws DataStoreException {
if (!(query instanceof org.geotoolkit.storage.feature.query.Query))
throw new UnsupportedQueryException();
final org.geotoolkit.storage.feature.query.Query gquery = (org.geotoolkit.storage.feature.query.Query) query;
final Filter filter = gquery.getSelection();
if (filter == Filter.include() || QueryUtilities.queryAll(gquery)) {
// use the generic envelope calculation
return super.getEnvelope(gquery);
}
final Set<String> fids = new TreeSet<>();
IdCollectorFilterVisitor.ID_COLLECTOR.visit(filter, fids);
final Set records = new HashSet();
if (!fids.isEmpty()) {
Collection<ShpData> recordsFound = null;
try {
recordsFound = queryFidIndex(fids);
} catch (IOException ex) {
throw new DataStoreException(ex);
}
if (recordsFound != null) {
records.addAll(recordsFound);
}
}
if (records.isEmpty())
return null;
final AccessManager locker = shpFiles.createLocker();
ShapefileReader reader = null;
try {
reader = locker.getSHPReader(false, false, false, null);
final JTSEnvelope2D ret = new JTSEnvelope2D(FeatureExt.getCRS(getFeatureType(getNames().iterator().next().toString())));
for (final Iterator iter = records.iterator(); iter.hasNext(); ) {
final Data data = (Data) iter.next();
reader.goTo(((Long) data.getValue(1)).intValue());
final Record record = reader.nextRecord();
ret.expandToInclude(record.minX, record.minY);
ret.expandToInclude(record.maxX, record.maxY);
}
return ret;
} catch (IOException ex) {
throw new DataStoreException(ex);
} finally {
// todo replace by ARM in JDK 1.7
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
throw new DataStoreException(ex);
}
}
}
}
use of org.geotoolkit.data.shapefile.indexed.IndexDataReader.ShpData in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method getAttributesReader.
private IndexedShapefileAttributeReader getAttributesReader(final List<? extends AttributeType> properties, final Filter filter, final boolean read3D, final double[] resample) throws DataStoreException {
final AccessManager locker = shpFiles.createLocker();
CloseableCollection<ShpData> goodRecs = null;
if (filter instanceof ResourceId && shpFiles.isWritable() && shpFiles.exists(FIX)) {
final ResourceId fidFilter = (ResourceId) filter;
final TreeSet<String> idsSet = new TreeSet<>();
idsSet.add(fidFilter.getIdentifier());
try {
goodRecs = queryFidIndex(idsSet);
} catch (IOException ex) {
throw new DataStoreException(ex);
}
} else {
// will be bbox.isNull() to start
Envelope bbox = new JTSEnvelope2D();
if (filter != null) {
// Add additional bounds from the filter
// will be null for Filter.EXCLUDES
bbox = ExtractBoundsFilterVisitor.bbox(filter, null);
if (bbox == null) {
bbox = new JTSEnvelope2D();
// we hit Filter.EXCLUDES consider returning an empty
// reader?
// (however should simplify the filter to detect ff.not(
// fitler.EXCLUDE )
}
}
if (!bbox.isNull() && this.useIndex) {
try {
goodRecs = this.queryQuadTree(locker, bbox);
} catch (TreeException e) {
throw new DataStoreException("Error querying index: " + e.getMessage());
} catch (IOException e) {
throw new DataStoreException("Error querying index: " + e.getMessage());
}
}
}
final boolean readDBF = !(properties.size() == 1 && Geometry.class.isAssignableFrom(properties.get(0).getValueClass()));
final AttributeType[] atts = properties.toArray(new AttributeType[properties.size()]);
try {
return new IndexedShapefileAttributeReader(locker, atts, read3D, useMemoryMappedBuffer, resample, readDBF, dbfCharset, resample, goodRecs, ((goodRecs != null) ? goodRecs.iterator() : null));
} catch (IOException ex) {
throw new DataStoreException(ex);
}
}
use of org.geotoolkit.data.shapefile.indexed.IndexDataReader.ShpData in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method queryFidIndex.
/**
* Uses the Fid index to quickly lookup the shp offset and the record number
* for the list of fids
*
* @param fids
* the fids of the features to find. If the set is sorted by alphabet the performance is likely to be better.
* @return a list of Data objects
*/
private CloseableCollection<ShpData> queryFidIndex(final Set<String> idsSet) throws IOException {
if (!indexUseable(FIX)) {
return null;
}
final AccessManager locker = shpFiles.createLocker();
final IndexedFidReader reader = locker.getFIXReader(null);
final CloseableCollection<ShpData> records = new CloseableArrayList(idsSet.size());
try {
final ShxReader shx = locker.getSHXReader(useMemoryMappedBuffer);
try {
for (String fid : idsSet) {
long recno = reader.findFid(fid);
if (recno == -1) {
if (getLogger().isLoggable(Level.FINEST)) {
getLogger().finest("fid " + fid + " not found in index, continuing with next queried fid...");
}
continue;
}
try {
ShpData data = new ShpData((int) (recno + 1), (long) shx.getOffsetInBytes((int) recno));
if (getLogger().isLoggable(Level.FINEST)) {
getLogger().finest("fid " + fid + " found for record #" + data.getValue(0) + " at index file offset " + data.getValue(1));
}
records.add(data);
} catch (Exception e) {
throw new IOException(e);
}
}
} finally {
shx.close();
}
} finally {
reader.close();
}
return records;
}
Aggregations