Skip to content

Instantly share code, notes, and snippets.

@jericks
Created September 23, 2013 03:05
Show Gist options
  • Save jericks/6666105 to your computer and use it in GitHub Desktop.
Save jericks/6666105 to your computer and use it in GitHub Desktop.
Write batches of Feature to a Layer.
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