Created
September 23, 2013 03:05
-
-
Save jericks/6666105 to your computer and use it in GitHub Desktop.
Write batches of Feature to a Layer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import geoscript.layer.* | |
import geoscript.feature.* | |
import geoscript.workspace.* | |
import org.geotools.data.Transaction | |
import org.geotools.data.DefaultTransaction | |
import org.geotools.data.FeatureStore | |
import org.geotools.data.DataUtilities | |
/** | |
* Write batches of Features to a FeatureStore. | |
* @author Jared Erickson | |
*/ | |
class BatchWriter { | |
/** | |
* The number of features to write at one time | |
*/ | |
private int batch | |
/** | |
* The FeatureStore to write to | |
*/ | |
private FeatureStore store | |
/** | |
* The Transaction used during writing | |
*/ | |
private Transaction transaction | |
/** | |
* The internal cache of Features | |
*/ | |
private List features = [] | |
/** | |
* Create a new BatchWriter for a Layer. | |
* @param options The named parameters | |
* <ul> | |
* <li>batch: The number of features to write at one time (defaults to 1000)</li> | |
* <li>autoCommit: Whether to use an auto commit transaction or not (defaults to false unless the Layer comes from a Shapefile)</li> | |
* </ul> | |
* @param layer The Layer to write to | |
*/ | |
BatchWriter(Map options = [:], Layer layer) { | |
this.batch = options.get("batch", 1000) | |
boolean autoCommit = options.get("autoCommit", | |
layer.fs instanceof org.geotools.data.directory.DirectoryFeatureStore ? true : false) | |
this.store = layer.fs as FeatureStore | |
transaction = autoCommit ? Transaction.AUTO_COMMIT : new DefaultTransaction("${layer.name}Transaction") | |
this.store.transaction = transaction | |
} | |
/** | |
* Add a Feature | |
* @param feature The Feature to add | |
*/ | |
void add(Feature feature) { | |
// Add the feature to the internal cache | |
features.add(feature.f) | |
// If there are more features in the cache than the batch | |
// size, write it | |
if (features.size() >= batch) { | |
// Write to the store | |
store.addFeatures(DataUtilities.collection(features)) | |
// Commit and transaction | |
transaction.commit() | |
// And the clear the interal cache | |
features = [] | |
} | |
} | |
/** | |
* Closes the writing session. If there are unwritten Features in the cache, they | |
* are written before the Transaction is finally closed. | |
*/ | |
void close() { | |
// Make sure to add any left over cached features | |
if (!features.isEmpty()) { | |
store.addFeatures(DataUtilities.collection(features)) | |
transaction.commit() | |
features = [] | |
} | |
// Close the transaction | |
transaction.close() | |
// Reset the store's transaction to auto commit | |
store.transaction = Transaction.AUTO_COMMIT | |
} | |
} | |
/** | |
* Add Layer.withBatchWriter(Closure c) method | |
*/ | |
Layer.metaClass.withBatchWriter << {closure -> | |
def writer = new BatchWriter(delegate) | |
try { | |
closure.call(writer) | |
} finally { | |
writer.close() | |
} | |
} | |
def dir = new Directory(new File("/Users/jericks/Projects/GeoScript/scripts/")) | |
def inLayer = dir.get("states") | |
def outLayer = dir.create(inLayer.schema.changeGeometryType("point","state_points")) | |
outLayer.withBatchWriter{w -> | |
inLayer.eachFeature{f -> | |
def newF = outLayer.schema.feature(f.attributes, f.id) | |
newF.geom = f.geom.centroid | |
w.add(newF) | |
} | |
} | |
outLayer = dir.get("state_points") | |
println outLayer.count |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment