📄 shapefiledatastore.java
字号:
prj.close();
}
} catch (IOException ioe) {
// do nothing
}
try {
if (dbf != null) {
dbf.close();
}
} catch (IOException ioe) {
// do nothing
}
try {
if (shp != null) {
shp.close();
}
} catch (IOException ioe) {
// do nothing
}
}
}
/**
* This method is used to force the creation of a .prj file.
* <p>
* The internally cached FeatureType will be removed, so the next call to
* getSchema() will read in the created file. This method is not thread safe
* and will have dire consequences for any other thread making use of the
* shapefile.
* <p>
*
* @param crs
*/
public void forceSchemaCRS(CoordinateReferenceSystem crs)
throws IOException {
if (crs == null)
throw new NullPointerException("CRS required for .prj file");
String s = crs.toWKT();
s = s.replaceAll("\n", "").replaceAll(" ", "");
StorageFile storageFile = shpFiles.getStorageFile(PRJ);
FileWriter out = new FileWriter(storageFile.getFile());
try {
out.write(s);
} finally {
out.close();
}
storageFile.replaceOriginal();
schema = null;
}
/**
* Set the FeatureType of this DataStore. This method will delete any
* existing local resources or throw an IOException if the DataStore is
* remote.
*
* @param featureType
* The desired FeatureType.
*
* @throws IOException
* If the DataStore is remote.
*/
public void createSchema(SimpleFeatureType featureType) throws IOException {
if (!isLocal()) {
throw new IOException(
"Cannot create FeatureType on remote shapefile");
}
shpFiles.delete();
schema = featureType;
CoordinateReferenceSystem cs = featureType.getDefaultGeometry()
.getCRS();
Class geomType = featureType.getDefaultGeometry().getType()
.getBinding();
ShapeType shapeType;
if (Point.class.isAssignableFrom(geomType)) {
shapeType = ShapeType.POINT;
} else if (MultiPoint.class.isAssignableFrom(geomType)) {
shapeType = ShapeType.MULTIPOINT;
} else if (LineString.class.isAssignableFrom(geomType)
|| MultiLineString.class.isAssignableFrom(geomType)) {
shapeType = ShapeType.ARC;
} else if (Polygon.class.isAssignableFrom(geomType)
|| MultiPolygon.class.isAssignableFrom(geomType)) {
shapeType = ShapeType.POLYGON;
} else {
throw new DataSourceException(
"Cannot create a shapefile whose geometry type is "
+ geomType);
}
StorageFile shpStoragefile = shpFiles.getStorageFile(SHP);
StorageFile shxStoragefile = shpFiles.getStorageFile(SHX);
StorageFile dbfStoragefile = shpFiles.getStorageFile(DBF);
StorageFile prjStoragefile = shpFiles.getStorageFile(PRJ);
FileChannel shpChannel = shpStoragefile.getWriteChannel();
FileChannel shxChannel = shxStoragefile.getWriteChannel();
ShapefileWriter writer = new ShapefileWriter(shpChannel, shxChannel);
try {
ReferencedEnvelope env = new ReferencedEnvelope(new Envelope(-179,
179, -89, 89), DefaultGeographicCRS.WGS84);
ReferencedEnvelope transformedBounds;
if (cs != null) {
try {
transformedBounds = env.transform(cs, true);
} catch (Exception e) {
cs = null;
transformedBounds = env;
}
} else {
transformedBounds = env;
}
writer.writeHeaders(transformedBounds, shapeType, 0, 100);
} finally {
writer.close();
assert !shpChannel.isOpen();
assert !shxChannel.isOpen();
}
DbaseFileHeader dbfheader = createDbaseHeader(featureType);
dbfheader.setNumRecords(0);
WritableByteChannel dbfChannel = dbfStoragefile.getWriteChannel();
try {
dbfheader.writeHeader(dbfChannel);
} finally {
dbfChannel.close();
}
if (cs != null) {
String s = cs.toWKT();
// .prj files should have no carriage returns in them, this
// messes up
// ESRI's ArcXXX software, so we'll be compatible
s = s.replaceAll("\n", "").replaceAll(" ", "");
FileWriter prjWriter = new FileWriter(prjStoragefile.getFile());
try {
prjWriter.write(s);
} finally {
prjWriter.close();
}
}
else {
LOGGER.warning("PRJ file not generated for null CoordinateReferenceSystem");
}
StorageFile.replaceOriginals(shpStoragefile, shxStoragefile,
dbfStoragefile, prjStoragefile);
}
/**
* Gets the bounding box of the file represented by this data store as a
* whole (that is, off all of the features in the shapefile)
*
* @return The bounding box of the datasource or null if unknown and too
* expensive for the method to calculate.
*
* @throws DataSourceException
* DOCUMENT ME!
*/
protected ReferencedEnvelope getBounds() throws DataSourceException {
// This is way quick!!!
ReadableByteChannel in = null;
try {
ByteBuffer buffer = ByteBuffer.allocate(100);
FileReader reader = new FileReader() {
public String id() {
return "Shapefile Datastore's getBounds Method";
}
};
in = shpFiles.getReadChannel(SHP, reader);
try {
in.read(buffer);
buffer.flip();
ShapefileHeader header = new ShapefileHeader();
header.read(buffer, true);
ReferencedEnvelope bounds = new ReferencedEnvelope(schema
.getCRS());
bounds.include(header.minX(), header.minY());
bounds.include(header.minX(), header.minY());
Envelope env = new Envelope(header.minX(), header.maxX(),
header.minY(), header.maxY());
if (schema != null) {
return new ReferencedEnvelope(env, schema.getCRS());
}
return new ReferencedEnvelope(env, null);
} finally {
in.close();
}
} catch (IOException ioe) {
// What now? This seems arbitrarily appropriate !
throw new DataSourceException("Problem getting Bbox", ioe);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ioe) {
// do nothing
}
}
}
protected ReferencedEnvelope getBounds(Query query) throws IOException {
if (query.getFilter().equals(Filter.INCLUDE)) {
return getBounds();
}
return null; // too expensive
// TODO should we just return the layer? matches the javadocs
}
/**
* @see org.geotools.data.DataStore#getFeatureSource(java.lang.String)
*/
public FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource(final String typeName)
throws IOException {
final SimpleFeatureType featureType = getSchema(typeName);
if (isWriteable) {
if (getLockingManager() != null) {
return new ShapefileFeatureLocking(this, HINTS, featureType);
}
else {
return new ShapefileFeatureStore(this, HINTS, featureType);
}
}
return new ShapefileFeatureSource(this, HINTS, featureType);
}
/**
* @see org.geotools.data.AbstractDataStore#getCount(org.geotools.data.Query)
*/
public int getCount(Query query) throws IOException {
if (query.getFilter() == Filter.INCLUDE) {
IndexFile file = openIndexFile();
if (file != null) {
try {
return file.getRecordCount();
} finally {
file.close();
}
}
// no Index file so use the number of shapefile records
ShapefileReader reader = openShapeReader();
int count = -1;
try {
count = reader.getCount(count);
} catch (IOException e) {
throw e;
} finally {
reader.close();
}
return count;
}
return super.getCount(query);
}
/**
* Attempt to create a DbaseFileHeader for the FeatureType. Note, we cannot
* set the number of records until the write has completed.
*
* @param featureType
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws IOException
* DOCUMENT ME!
* @throws DbaseFileException
* DOCUMENT ME!
*/
protected static DbaseFileHeader createDbaseHeader(
SimpleFeatureType featureType) throws IOException,
DbaseFileException {
DbaseFileHeader header = new DbaseFileHeader();
for (int i = 0, ii = featureType.getAttributeCount(); i < ii; i++) {
AttributeDescriptor type = featureType.getAttribute(i);
Class<?> colType = type.getType().getBinding();
String colName = type.getLocalName();
int fieldLen = FeatureTypes.getFieldLength(type);
if (fieldLen == FeatureTypes.ANY_LENGTH)
fieldLen = 255;
if ((colType == Integer.class) || (colType == Short.class)
|| (colType == Byte.class)) {
header.addColumn(colName, 'N', Math.min(fieldLen, 9), 0);
} else if (colType == Long.class) {
header.addColumn(colName, 'N', Math.min(fieldLen, 19), 0);
} else if (colType == BigInteger.class) {
header.addColumn(colName, 'N', Math.min(fieldLen, 33), 0);
} else if (Number.class.isAssignableFrom(colType)) {
int l = Math.min(fieldLen, 33);
int d = Math.max(l - 2, 0);
header.addColumn(colName, 'N', l, d);
} else if (java.util.Date.class.isAssignableFrom(colType)) {
header.addColumn(colName, 'D', fieldLen, 0);
} else if (colType == Boolean.class) {
header.addColumn(colName, 'L', 1, 0);
} else if (CharSequence.class.isAssignableFrom(colType)) {
// Possible fix for GEOT-42 : ArcExplorer doesn't like 0 length
// ensure that maxLength is at least 1
header.addColumn(colName, 'C', Math.min(254, fieldLen), 0);
} else if (Geometry.class.isAssignableFrom(colType)) {
continue;
} else {
throw new IOException("Unable to write : " + colType.getName());
}
}
return header;
}
@Override
public String toString() {
return "Shapefile datastore for :" + shpFiles.get(SHP);
}
@Override
public void dispose() {
super.dispose();
shpFiles.dispose();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -