📄 indexedshapefiledatastore.java
字号:
throw new DataSourceException("Error creating schema", se);
}
}
protected FeatureReader<SimpleFeatureType, SimpleFeature> createFeatureReader(String typeName,
IndexedShapefileAttributeReader r, SimpleFeatureType readerSchema)
throws SchemaException, IOException {
FIDReader fidReader;
if (!indexUseable(FIX)) {
fidReader = new ShapeFIDReader(getCurrentTypeName(), r);
} else {
fidReader = new IndexedFidReader(shpFiles, r);
}
return new org.geotools.data.FIDFeatureReader(r, fidReader,
readerSchema);
}
/**
* Forces the FID index to be regenerated
*
* @throws IOException
*/
public void generateFidIndex() throws IOException {
FidIndexer.generate(shpFiles);
}
/**
* Returns the attribute reader, allowing for a pure shape reader, or a
* combined dbf/shp reader.
*
* @param readDbf -
* if true, the dbf fill will be opened and read
* @param readGeometry
* DOCUMENT ME!
* @param filter -
* a Filter to use
*
*
* @throws IOException
*/
protected IndexedShapefileAttributeReader getAttributesReader(
boolean readDbf, boolean readGeometry, Filter filter)
throws IOException {
Envelope bbox = new ReferencedEnvelope(); // will be bbox.isNull() to
// start
CloseableCollection<Data> goodRecs = null;
if (filter instanceof Id && shpFiles.isLocal() && shpFiles.exists(FIX)) {
Id fidFilter = (Id) filter;
Set<?> fids = (Set<?>) fidFilter.getIDs();
goodRecs = queryFidIndex((Set<String>) fids);
} else {
if (filter != null) {
// Add additional bounds from the filter
// will be null for Filter.EXCLUDES
bbox = (Envelope) filter.accept(
ExtractBoundsFilterVisitor.BOUNDS_VISITOR, bbox);
if (bbox == null) {
bbox = new ReferencedEnvelope();
// 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(bbox);
} catch (TreeException e) {
throw new IOException("Error querying index: "
+ e.getMessage());
}
}
}
List<AttributeDescriptor> atts = (schema == null) ? readAttributes()
: schema.getAttributes();
IndexedDbaseFileReader dbfR = null;
if (!readDbf) {
LOGGER.fine("The DBF file won't be opened since no attributes "
+ "will be read from it");
atts = new ArrayList<AttributeDescriptor>(1);
atts.add(schema.getDefaultGeometry());
if (!readGeometry) {
atts = new ArrayList<AttributeDescriptor>(1);
}
} else {
dbfR = (IndexedDbaseFileReader) openDbfReader();
}
return new IndexedShapefileAttributeReader(atts, openShapeReader(),
dbfR, goodRecs);
}
/**
* 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.
* @return a list of Data objects
* @throws IOException
* @throws TreeException
*/
private CloseableCollection<Data> queryFidIndex(Set<String> idsSet) throws IOException {
if (!indexUseable(FIX)) {
return null;
}
String fids[] = (String[]) idsSet.toArray(new String[idsSet.size()]);
Arrays.sort(fids);
IndexedFidReader reader = new IndexedFidReader(shpFiles);
CloseableCollection<Data> records = new CloseableArrayList(fids.length);
try {
IndexFile shx = openIndexFile();
try {
DataDefinition def = new DataDefinition("US-ASCII");
def.addField(Integer.class);
def.addField(Long.class);
for (int i = 0; i < fids.length; i++) {
long recno = reader.findFid(fids[i]);
if (recno == -1)
continue;
try {
Data data = new Data(def);
data.addValue(new Integer((int) recno + 1));
data.addValue(new Long(shx
.getOffsetInBytes((int) recno)));
records.add(data);
} catch (Exception e) {
IOException exception = new IOException();
exception.initCause(e);
throw exception;
}
}
} finally {
shx.close();
}
} finally {
reader.close();
}
return records;
}
/**
* Returns true if the index for the given type exists and is useable.
*
* @param indexType
* the type of index to check
*
* @return true if the index for the given type exists and is useable.
*/
public boolean indexUseable(ShpFileType indexType) {
if (isLocal()) {
if (needsGeneration(indexType) || !shpFiles.exists(indexType)) {
return false;
}
} else {
ReadableByteChannel read = null;
try {
read = shpFiles.getReadChannel(indexType, this);
} catch (IOException e) {
return false;
} finally {
if (read != null) {
try {
read.close();
} catch (IOException e) {
ShapefileDataStoreFactory.LOGGER.log(Level.WARNING,
"could not close stream", e);
}
}
}
}
return true;
}
boolean needsGeneration(ShpFileType indexType) {
if (!isLocal())
throw new IllegalStateException(
"This method only applies if the files are local and the file can be created");
URL indexURL = shpFiles.acquireRead(indexType, this);
URL shpURL = shpFiles.acquireRead(SHP, this);
try {
if (indexURL == null) {
return true;
}
// indexes require both the SHP and SHX so if either or missing then
// you don't need to
// index
if (!shpFiles.exists(SHX) || !shpFiles.exists(SHP)) {
return false;
}
File indexFile = DataUtilities.urlToFile(indexURL);
File shpFile = DataUtilities.urlToFile(shpURL);
long indexLastModified = indexFile.lastModified();
long shpLastModified = shpFile.lastModified();
boolean shpChangedMoreRecently = indexLastModified < shpLastModified;
return !indexFile.exists() || shpChangedMoreRecently;
} finally {
if (shpURL != null) {
shpFiles.unlockRead(shpURL, this);
}
if (indexURL != null) {
shpFiles.unlockRead(indexURL, this);
}
}
}
/**
* Returns true if the indices already exist and do not need to be
* regenerated or cannot be generated (IE isn't local).
*
* @return true if the indices already exist and do not need to be
* regenerated.
*/
public boolean isIndexed() {
if (shpFiles.isLocal()) {
return true;
}
return !needsGeneration(FIX) && !needsGeneration(treeType.shpFileType);
}
// /**
// * RTree query
// *
// * @param bbox
// *
// *
// * @throws DataSourceException
// * @throws IOException
// */
// private List queryRTree(Envelope bbox) throws DataSourceException,
// IOException {
// List goodRecs = null;
// RTree rtree = this.openRTree();
//
// try {
// if ((rtree != null) && (rtree.getBounds() != null)
// && !bbox.contains(rtree.getBounds())) {
// goodRecs = rtree.search(bbox);
// }
// } catch (LockTimeoutException le) {
// throw new DataSourceException("Error querying RTree", le);
// } catch (TreeException re) {
// throw new DataSourceException("Error querying RTree", re);
// }
//
// return goodRecs;
// }
/**
* QuadTree Query
*
* @param bbox
*
*
* @throws DataSourceException
* @throws IOException
* @throws TreeException
* DOCUMENT ME!
*/
private CloseableCollection<Data> queryQuadTree(Envelope bbox)
throws DataSourceException, IOException, TreeException {
CloseableCollection<Data> tmp = null;
try {
QuadTree quadTree = openQuadTree();
if ((quadTree != null)
&& !bbox.contains(quadTree.getRoot().getBounds())) {
tmp = quadTree.search(bbox);
if (tmp == null || !tmp.isEmpty())
return tmp;
}
if (quadTree != null) {
quadTree.close();
}
} catch (Exception e) {
throw new DataSourceException("Error querying QuadTree", e);
}
return null;
}
/**
* Convenience method for opening a DbaseFileReader.
*
* @return A new DbaseFileReader
*
* @throws IOException
* If an error occurs during creation.
*/
protected DbaseFileReader openDbfReader() throws IOException {
if (shpFiles.get(DBF) == null) {
return null;
}
if (isLocal() && !shpFiles.exists(DBF)) {
return null;
}
return new IndexedDbaseFileReader(shpFiles, false, dbfCharset);
}
//
// /**
// * Convenience method for opening an RTree index.
// *
// * @return A new RTree.
// *
// * @throws IOException
// * If an error occurs during creation.
// * @throws DataSourceException
// * DOCUMENT ME!
// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -