private DataStore createLatLonDataStore() throws Exception { SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); tb.setName("latlon"); tb.add("the_geom", LineString.class, CRS.decode("EPSG:4326", true)); tb.add("level", Integer.class); SimpleFeatureType type = tb.buildFeatureType(); MemoryDataStore ds = new MemoryDataStore(); ds.createSchema(type); FeatureWriter<SimpleFeatureType, SimpleFeature> writer; writer = ds.getFeatureWriterAppend("latlon", Transaction.AUTO_COMMIT); for (int lon = -180; lon < 180; lon += 5) { for (int lat = -90; lat < 90; lat += 5) { LineString geom; int level; geom = gf.createLineString( new Coordinate[] {new Coordinate(lon, lat), new Coordinate(lon, lat + 5)}); level = 1; if (lon % 10 == 0) { level = 10; } if (lon % 30 == 0) { level = 30; } SimpleFeature f; f = writer.next(); f.setAttribute(0, geom); f.setAttribute(1, Integer.valueOf(level)); writer.write(); geom = gf.createLineString( new Coordinate[] {new Coordinate(lon, lat), new Coordinate(lon + 5, lat)}); level = 1; if (lat % 10 == 0) { level = 10; } if (lat % 30 == 0) { level = 30; } f = writer.next(); f.setAttribute(0, geom); f.setAttribute(1, Integer.valueOf(level)); writer.write(); } } writer.close(); return ds; }
/** * Sets the feature of the source. * * <p>This method operates by first clearing the contents of the feature store ({@link * #removeFeatures(Filter)}), and then obtaining an appending feature writer and writing all * features from <tt>reader</tt> to it. */ public final void setFeatures(FeatureReader<SimpleFeatureType, SimpleFeature> reader) throws IOException { // remove features removeFeatures(Filter.INCLUDE); // grab a feature writer for insert FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getWriter(Filter.INCLUDE, WRITER_ADD); try { while (reader.hasNext()) { SimpleFeature feature = reader.next(); // grab next feature and populate it // JD: worth a note on how we do this... we take a "pull" approach // because the raw schema we are inserting into may not match the // schema of the features we are inserting SimpleFeature toWrite = writer.next(); for (int i = 0; i < toWrite.getType().getAttributeCount(); i++) { String name = toWrite.getType().getDescriptor(i).getLocalName(); toWrite.setAttribute(name, feature.getAttribute(name)); } // perform the write writer.write(); } } finally { writer.close(); } }
FeatureId addFeature( SimpleFeature feature, FeatureWriter<SimpleFeatureType, SimpleFeature> writer) throws IOException { // grab next feature and populate it // JD: worth a note on how we do this... we take a "pull" approach // because the raw schema we are inserting into may not match the // schema of the features we are inserting SimpleFeature toWrite = writer.next(); for (int i = 0; i < toWrite.getType().getAttributeCount(); i++) { String name = toWrite.getType().getDescriptor(i).getLocalName(); toWrite.setAttribute(name, feature.getAttribute(name)); } // copy over the user data if (feature.getUserData().size() > 0) { toWrite.getUserData().putAll(feature.getUserData()); } // pass through the fid if the user asked so boolean useExisting = Boolean.TRUE.equals(feature.getUserData().get(Hints.USE_PROVIDED_FID)); if (getQueryCapabilities().isUseProvidedFIDSupported() && useExisting) { ((FeatureIdImpl) toWrite.getIdentifier()).setID(feature.getID()); } // perform the write writer.write(); // copy any metadata from the feature that was actually written feature.getUserData().putAll(toWrite.getUserData()); // add the id to the set of inserted FeatureId id = toWrite.getIdentifier(); return id; }
/** * Utility method that ensures we are going to write only in append mode * * @return * @throws IOException */ private FeatureWriter<SimpleFeatureType, SimpleFeature> getWriterAppend() throws IOException { FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getWriter(Filter.INCLUDE, WRITER_ADD); while (writer.hasNext()) { writer.next(); } return writer; }
protected void modifyFeatures( AttributeDescriptor[] type, Object[] value, FeatureWriter<SimpleFeatureType, SimpleFeature> writer) throws DataSourceException, IOException { SimpleFeature feature; try { while (writer.hasNext()) { feature = writer.next(); for (int i = 0; i < type.length; i++) { try { feature.setAttribute(type[i].getLocalName(), value[i]); } catch (IllegalAttributeException e) { throw new DataSourceException( "Could not update feature " + feature.getID() + " with " + type[i].getLocalName() + "=" + value[i], e); } } writer.write(); } } finally { writer.close(); } }
public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> collection) throws IOException { List<FeatureId> addedFids = new LinkedList<FeatureId>(); String typeName = getSchema().getTypeName(); SimpleFeature feature = null; SimpleFeature newFeature; FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriterAppend(typeName, getTransaction()); Iterator iterator = collection.iterator(); try { while (iterator.hasNext()) { feature = (SimpleFeature) iterator.next(); newFeature = (SimpleFeature) writer.next(); try { newFeature.setAttributes(feature.getAttributes()); } catch (Exception writeProblem) { throw new DataSourceException( "Could not create " + typeName + " out of provided feature: " + feature.getID(), writeProblem); } // preserve the FID, it could come from another node ((MutableFIDFeature) newFeature).setID(feature.getID()); writer.write(); addedFids.add(newFeature.getIdentifier()); } } finally { collection.close(iterator); writer.close(); } return addedFids; }
public SimpleFeature next() throws IOException { try { current = delegate.next(); retyped = RetypingFeatureCollection.retype(current, builder); return retyped; } catch (IllegalAttributeException e) { throw (IOException) new IOException("Error occurred while retyping feature").initCause(e); } }
/** * Replace with contents of reader. * * <p>Equivelent to: * * <pre><code> * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, false, transaction ); * Feature feature, newFeature; * while( writer.hasNext() ){ * feature = writer.next(); * writer.remove(); * } * while( reader.hasNext() ){ * newFeature = reader.next(); * feature = writer.next(); * newFeature.setAttributes( feature.getAttributes( null ) ); * writer.write(); * } * reader.close(); * writer.close(); * </code> * </pre> * * <p>Subclasses may override this method to perform the appropriate optimization for this result. * * @param reader Contents to replace with * @throws IOException */ public void setFeatures(FeatureReader<SimpleFeatureType, SimpleFeature> reader) throws IOException { String typeName = getSchema().getTypeName(); FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriter(typeName, getTransaction()); SimpleFeature feature; SimpleFeature newFeature; try { while (writer.hasNext()) { feature = writer.next(); LOGGER.finer("removing feature " + feature); writer.remove(); } while (reader.hasNext()) { try { feature = reader.next(); } catch (Exception readProblem) { throw new DataSourceException( "Could not add Features, problem with provided reader", readProblem); } newFeature = (SimpleFeature) writer.next(); try { newFeature.setAttributes(feature.getAttributes()); } catch (IllegalAttributeException writeProblem) { throw new DataSourceException( "Could not create " + typeName + " out of provided feature: " + feature.getID(), writeProblem); } LOGGER.finer("writing feature " + newFeature); writer.write(); } } finally { reader.close(); writer.close(); } }
public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> collection) throws IOException { List<FeatureId> addedFids = new LinkedList<FeatureId>(); String typeName = getSchema().getTypeName(); SimpleFeature feature = null; SimpleFeature newFeature; FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriterAppend(typeName, getTransaction()); Iterator iterator = collection.iterator(); try { while (iterator.hasNext()) { try { feature = (SimpleFeature) iterator.next(); } catch (Exception e) { throw new DataSourceException("Could not add Features, problem with provided reader", e); } newFeature = (SimpleFeature) writer.next(); try { // JD: we may have a case that the source feature type does not // match exactly the target feature type, so build attributes // based oin target // newFeature.setAttributes(feature.getAttributes(null)); Object[] attributes = new Object[newFeature.getAttributeCount()]; for (int i = 0; i < attributes.length; i++) { AttributeDescriptor type = newFeature.getFeatureType().getDescriptor(i); attributes[i] = feature.getAttribute(type.getLocalName()); } newFeature.setAttributes(attributes); } catch (IllegalAttributeException writeProblem) { throw new DataSourceException( "Could not create " + typeName + " out of provided feature: " + feature.getID(), writeProblem); } writer.write(); addedFids.add(newFeature.getIdentifier()); } } finally { collection.close(iterator); writer.close(); } return addedFids; }
/** * Removes features indicated by provided filter. * * <p>Equivelent to: * * <pre><code> * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, filter, transaction ); * Feature feature; * while( writer.hasNext() ){ * feature = writer.next(); * writer.remove(); * } * writer.close(); * </code> * </pre> * * <p>Subclasses may override this method to perform the appropriate optimization for this result. * * @param filter Identifies features to remove * @throws IOException */ public void removeFeatures(Filter filter) throws IOException { String typeName = getSchema().getTypeName(); FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriter(typeName, filter, getTransaction()); SimpleFeature feature; try { while (writer.hasNext()) { feature = writer.next(); writer.remove(); } } finally { writer.close(); } }
/** * Removes the features from the store which match the specified filter. * * <p>This method operates by obtaining an updating feature writer based on the specified * <tt>filter</tt> and removing every feature from it. * * <p>The <tt>filter</tt> must not be <code>null</code>, in this case this method will throw an * {@link IllegalArgumentException}. */ public void removeFeatures(Filter filter) throws IOException { if (filter == null) { String msg = "Must specify a filter, must not be null."; throw new IllegalArgumentException(msg); } filter = resolvePropertyNames(filter); // grab a feature writer FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getWriter(filter, WRITER_UPDATE); try { // remove everything while (writer.hasNext()) { writer.next(); writer.remove(); } } finally { writer.close(); } }
@Override protected FeatureWriter<SimpleFeatureType, SimpleFeature> getWriterInternal( Query query, int flags) throws IOException { if (flags == 0) { throw new IllegalArgumentException("no write flags set"); } ShapefileFeatureReader reader = (ShapefileFeatureReader) delegate.getReaderInternal(Query.ALL); FeatureWriter<SimpleFeatureType, SimpleFeature> writer; ShapefileDataStore ds = getDataStore(); if (ds.indexManager.hasFidIndex(false) || ds.isFidIndexed() && ds.indexManager.hasFidIndex(true)) { writer = new IndexedShapefileFeatureWriter( ds.indexManager, reader, ds.getCharset(), ds.getTimeZone()); } else { writer = new ShapefileFeatureWriter(delegate.shpFiles, reader, ds.getCharset(), ds.getTimeZone()); } // if we only have to add move to the end. // TODO: just make the code transfer the bytes in bulk instead and start actual writing at // the end if ((flags | WRITER_ADD) == WRITER_ADD) { while (writer.hasNext()) { writer.next(); } } // if we are filtering wrap the writer so that it returns only the selected features // but writes down the mall Filter filter = query.getFilter(); if (filter != null && !Filter.INCLUDE.equals(filter)) { writer = new FilteringFeatureWriter(writer, filter); } return writer; }
/** * Modifies/updates the features of the store which match the specified filter. * * <p>This method operates by obtaining an updating feature writer based on the specified * <tt>filter</tt> and writing the updated values to it. * * <p>The <tt>filter</tt> must not be <code>null</code>, in this case this method will throw an * {@link IllegalArgumentException}. */ public void modifyFeatures(Name[] type, Object[] value, Filter filter) throws IOException { if (filter == null) { String msg = "Must specify a filter, must not be null."; throw new IllegalArgumentException(msg); } filter = resolvePropertyNames(filter); // grab a feature writer FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getWriter(filter, WRITER_UPDATE); try { while (writer.hasNext()) { SimpleFeature toWrite = writer.next(); for (int i = 0; i < type.length; i++) { toWrite.setAttribute(type[i], value[i]); } writer.write(); } } finally { writer.close(); } }
/** * Add Features from reader to this FeatureStore. * * <p>Equivelent to: * * <pre><code> * Set set = new HashSet(); * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, true, transaction ); * Featrue feature, newFeature; * while( reader.hasNext() ){ * feature = reader.next(); * newFeature = writer.next(); * newFeature.setAttributes( feature.getAttribtues( null ) ); * writer.write(); * set.add( newfeature.getID() ); * } * reader.close(); * writer.close(); * * return set; * </code> * </pre> * * <p>(If you don't have a FeatureReader<SimpleFeatureType, SimpleFeature> handy * DataUtilities.reader() may be able to help out) * * <p>Subclasses may override this method to perform the appropriate optimization for this result. * * @param reader * @return The Set of FeatureIDs added * @throws IOException * @see org.geotools.data.FeatureStore#addFeatures(org.geotools.data.FeatureReader) */ public Set addFeatures(FeatureReader<SimpleFeatureType, SimpleFeature> reader) throws IOException { Set addedFids = new HashSet(); String typeName = getSchema().getTypeName(); SimpleFeature feature = null; SimpleFeature newFeature; FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriterAppend(typeName, getTransaction()); try { while (reader.hasNext()) { try { feature = reader.next(); } catch (Exception e) { throw new DataSourceException("Could not add Features, problem with provided reader", e); } newFeature = (SimpleFeature) writer.next(); try { newFeature.setAttributes(feature.getAttributes()); } catch (IllegalAttributeException writeProblem) { throw new DataSourceException( "Could not create " + typeName + " out of provided feature: " + feature.getID(), writeProblem); } writer.write(); addedFids.add(newFeature.getID()); } } finally { reader.close(); writer.close(); } return addedFids; }
public void rollback(String toVersion, Filter filter, String[] userIds) throws IOException { // TODO: build an optimized version of this that can do the same work with a couple // of queries assuming the filter is fully encodable Transaction t = getTransaction(); boolean autoCommit = false; if (Transaction.AUTO_COMMIT.equals(t)) { t = new DefaultTransaction(); autoCommit = true; } // Gather feature modified after toVersion ModifiedFeatureIds mfids = store.getModifiedFeatureFIDs(schema.getTypeName(), toVersion, null, filter, userIds, t); FilterFactory ff = CommonFactoryFinder.getFilterFactory(null); // grab the state, we need to mark as dirty all the features we are going to modify/re-insert VersionedJdbcTransactionState state = store.wrapped.getVersionedJdbcTransactionState(t); // remove all features that have been created and not deleted Set fidsToRemove = new HashSet(mfids.getCreated()); fidsToRemove.removeAll(mfids.getDeleted()); if (!fidsToRemove.isEmpty()) { removeFeatures(store.buildFidFilter(fidsToRemove)); state.setTypeNameDirty(getSchema().getTypeName()); } // reinstate all features that were there before toVersion and that // have been deleted after it. Notice this is an insertion, so to preserve // the fids I have to use low level writers where I can set all attributes manually // (we work on the assumption the wrapped data store maps all attributes of the primary // key in the feature itself) Set fidsToRecreate = new HashSet(mfids.getDeleted()); fidsToRecreate.removeAll(mfids.getCreated()); if (!fidsToRecreate.isEmpty()) { state.setTypeNameDirty(getSchema().getTypeName()); state.setFidsDirty(getSchema().getTypeName(), fidsToRecreate); long revision = store.wrapped.getVersionedJdbcTransactionState(t).getRevision(); Filter recreateFilter = store.buildVersionedFilter( schema.getTypeName(), store.buildFidFilter(fidsToRecreate), mfids.fromRevision); FeatureReader<SimpleFeatureType, SimpleFeature> fr = null; FeatureWriter<SimpleFeatureType, SimpleFeature> fw = null; try { DefaultQuery q = new DefaultQuery(schema.getTypeName(), recreateFilter); fr = store.wrapped.getFeatureReader(q, t); fw = store.wrapped.getFeatureWriterAppend(schema.getTypeName(), t); while (fr.hasNext()) { SimpleFeature original = fr.next(); SimpleFeature restored = fw.next(); for (int i = 0; i < original.getFeatureType().getAttributeCount(); i++) { restored.setAttribute(i, original.getAttribute(i)); } restored.setAttribute("revision", new Long(revision)); restored.setAttribute("expired", new Long(Long.MAX_VALUE)); fw.write(); } } catch (IllegalAttributeException iae) { throw new DataSourceException( "Unexpected error occurred while " + "restoring deleted featues", iae); } finally { if (fr != null) fr.close(); if (fw != null) fw.close(); } } // Now onto the modified features, that were there, and still are there. // Since we cannot get a sorted writer we have to do a kind of inner loop scan // (note, a parellel scan of similarly sorted reader and writer would be more // efficient, but writer sorting is not there...) // Here it's possible to work against the external API, thought it would be more // efficient (but more complex) to work against the wrapped one. if (!mfids.getModified().isEmpty()) { state.setTypeNameDirty(getSchema().getTypeName()); state.setFidsDirty(getSchema().getTypeName(), mfids.getModified()); Filter modifiedIdFilter = store.buildFidFilter(mfids.getModified()); Filter mifCurrent = store.buildVersionedFilter(schema.getTypeName(), modifiedIdFilter, new RevisionInfo()); FeatureReader<SimpleFeatureType, SimpleFeature> fr = null; FeatureWriter<SimpleFeatureType, SimpleFeature> fw = null; try { fw = store.getFeatureWriter(schema.getTypeName(), mifCurrent, t); while (fw.hasNext()) { SimpleFeature current = fw.next(); Filter currIdFilter = ff.id(Collections.singleton(ff.featureId(current.getID()))); Filter cidToVersion = store.buildVersionedFilter(schema.getTypeName(), currIdFilter, mfids.fromRevision); DefaultQuery q = new DefaultQuery(schema.getTypeName(), cidToVersion); q.setVersion(mfids.fromRevision.toString()); fr = store.getFeatureReader(q, t); SimpleFeature original = fr.next(); for (int i = 0; i < original.getFeatureType().getAttributeCount(); i++) { current.setAttribute(i, original.getAttribute(i)); } fr.close(); fw.write(); } } catch (IllegalAttributeException iae) { throw new DataSourceException( "Unexpected error occurred while " + "restoring deleted featues", iae); } finally { if (fr != null) fr.close(); if (fw != null) fw.close(); } } // if it's auto commit, don't forget to actually commit if (autoCommit) { t.commit(); t.close(); } }