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; }
/** * Handles the feature creation/update/deletion strategy. You may want to override this in a * subclass to handle workflow. * * @param feature the feature that is about to be split * @param geoms new geometries that are the result of splitting * @param filter filter to get at feature * @param localStore the store we're working against * @param localStrategy the strategy in use * @return A list of FeatureIds is returned, one for each feature in the order created. However, * these might not be assigned until after a commit has been performed. * @throws Exception if an error occurs modifying the data source, converting the geometry or an * illegal argument was given */ protected List<FeatureId> handleStrategy( SimpleFeature feature, List<? extends Geometry> geoms, Filter filter, SimpleFeatureStore localStore, String localStrategy) throws Exception { List<SimpleFeature> newFeats = new ArrayList(); GeometryTypeConverterFactory cf = new GeometryTypeConverterFactory(); Converter c = cf.createConverter( Geometry.class, localStore.getSchema().getGeometryDescriptor().getType().getBinding(), null); GeometryType type = localStore.getSchema().getGeometryDescriptor().getType(); String geomAttribute = localStore.getSchema().getGeometryDescriptor().getLocalName(); boolean firstFeature = true; for (Geometry newGeom : geoms) { if (firstFeature) { if (localStrategy.equalsIgnoreCase("replace")) { // use first/largest geom to update existing feature geom feature.setAttribute(geomAttribute, c.convert(newGeom, type.getBinding())); feature = this.handleExtraData(feature); Object[] attributevalues = feature.getAttributes().toArray(new Object[feature.getAttributeCount()]); AttributeDescriptor[] attributes = feature .getFeatureType() .getAttributeDescriptors() .toArray(new AttributeDescriptor[feature.getAttributeCount()]); localStore.modifyFeatures(attributes, attributevalues, filter); firstFeature = false; continue; } else if (localStrategy.equalsIgnoreCase("add")) { // delete the source feature, new ones will be created localStore.removeFeatures(filter); firstFeature = false; } else { throw new IllegalArgumentException( "Unknown strategy '" + localStrategy + "', cannot split"); } } // create + add new features SimpleFeature newFeat = DataUtilities.createFeature( feature.getType(), DataUtilities.encodeFeature(feature, false)); newFeat.setAttribute(geomAttribute, c.convert(newGeom, type.getBinding())); newFeats.add(newFeat); } newFeats = this.handleExtraData(newFeats); return localStore.addFeatures(DataUtilities.collection(newFeats)); }
@Test public void testWithNull() throws Exception { SimpleFeatureSource source = getFeatureSource(MockData.BASIC_POLYGONS); SimpleFeatureCollection fc = source.getFeatures(); SimpleFeatureIterator i = fc.features(); try { SimpleFeature f = (SimpleFeature) i.next(); FeatureTemplate template = new FeatureTemplate(); template.description(f); // set a value to null f.setAttribute(1, null); try { template.description(f); } catch (Exception e) { e.printStackTrace(); fail("template threw exception on null value"); } } finally { i.close(); } }
/** * 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; }
/** * Creates a new SimpleFeature for <code>targetType</code> that holds the common attributes from * <code>sourceFeature</code> and the buffered geometry. * * @param sourceFeature the original SimpleFeature from which to extract matching attributes for * the new SimpleFeature, or <code>null</code> if the new SimpleFeature has to have empty * attributes other than the default geometry. * @param targetType * @param bufferedGeometry the product geometry of running {@link BufferOp} over the default * geometry of <code>sourceFeature</code> with the parameters provided to this operation. * @return a new SimpleFeature of type <code>targetType</code> holding the common attributes with * <code>sourceFeature</code> and <code>bufferedGeometry</code> as the feature's default * geometry * @throws SOProcessException */ @SuppressWarnings("unchecked") private SimpleFeature createBufferedFeature( SimpleFeature sourceFeature, SimpleFeatureType targetType, Geometry bufferedGeometry) throws SOProcessException { SimpleFeature newFeature; try { newFeature = DataUtilities.template(targetType); final GeometryDescriptor targetGeometryType = targetType.getDefaultGeometry(); if (sourceFeature != null) { GeoToolsUtils.match(sourceFeature, newFeature); } final String attName = targetGeometryType.getLocalName(); final Class geomClass = targetGeometryType.getType().getBinding(); bufferedGeometry = GeometryUtil.adapt(bufferedGeometry, geomClass); newFeature.setAttribute(attName, bufferedGeometry); } catch (IllegalAttributeException e) { throw new SOProcessException(e.getMessage(), e); } return newFeature; }
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(); } }
@Override public SimpleFeature apply( ImportTask task, DataStore dataStore, SimpleFeature oldFeature, SimpleFeature feature) throws Exception { Object origDesc = feature.getAttribute("description"); if (origDesc == null) { return feature; } String newDesc = StringUtils.abbreviate(origDesc.toString(), 255); feature.setAttribute("description", newDesc); return feature; }
public void write() throws IOException { try { SimpleFeatureType target = getFeatureType(); for (int i = 0; i < target.getAttributeCount(); i++) { AttributeDescriptor at = target.getDescriptor(i); Object value = retyped.getAttribute(i); current.setAttribute(at.getLocalName(), value); } delegate.write(); } catch (IllegalAttributeException e) { throw (IOException) new IOException("Error occurred while retyping feature").initCause(e); } }
/** * Applies transform to all geometry attribute. * * @param feature Feature to be transformed * @param schema Schema for target transformation - transform( schema, crs ) * @param transform MathTransform used to transform coordinates - reproject( crs, crs ) * @return transformed Feature of type schema * @throws TransformException * @throws MismatchedDimensionException * @throws IllegalAttributeException */ public static SimpleFeature transform( SimpleFeature feature, SimpleFeatureType schema, MathTransform transform) throws MismatchedDimensionException, TransformException, IllegalAttributeException { feature = SimpleFeatureBuilder.copy(feature); GeometryDescriptor geomType = schema.getGeometryDescriptor(); Geometry geom = (Geometry) feature.getAttribute(geomType.getLocalName()); geom = JTS.transform(geom, transform); feature.setAttribute(geomType.getLocalName(), geom); return feature; }
public void XtestUpdate() throws Exception { TableViewer viewer = (TableViewer) table.getViewer(); TableItem topItem = viewer.getTable().getItem(0); SimpleFeature f = (SimpleFeature) topItem.getData(); f.setAttribute(0, "newName"); // $NON-NLS-1$ while (Display.getCurrent().readAndDispatch()) ; assertEquals("feature1", topItem.getText(1)); // $NON-NLS-1$ table.update(); while (Display.getCurrent().readAndDispatch()) ; assertEquals("newName", table.getViewer().getTable().getItem(0).getText(1)); // $NON-NLS-1$ }
private SimpleFeature createCrsBoundsFeature(Geometry geom, CoordinateReferenceSystem crs) { SimpleFeatureType featureType; SimpleFeatureTypeBuilder sftb = new SimpleFeatureTypeBuilder(); sftb.setName("Bounds"); try { sftb.add("the_geom", Geometry.class, CRS.decode("EPSG:4326", true)); } catch (Exception e) { throw new RuntimeException(e); } featureType = sftb.buildFeatureType(); SimpleFeature feature = SimpleFeatureBuilder.template(featureType, null); feature.setAttribute("the_geom", geom); return feature; }
/** * 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(); } }
@Override public void setProperties(SimpleFeature feature) { feature.setAttribute(this.getPropertyNames().get(0), this.crsCode); }
/** * Get the values from all of the columns based on their presence (or absense) in the rows * * <p>Potential cases: simple column join column non-matching join null value geometry * * @param file the file * @param row the row */ private void retrieveObject(VPFFile file, SimpleFeature row) throws IOException { VPFFile secondFile = null; VPFColumn column = null; Map rows = generateFileRowMap(file, row); List<AttributeDescriptor> attributes = featureType.getFeatureClass().getAttributeDescriptors(); Object[] values = new Object[featureType.getAttributeCount()]; Object value = null; String featureId = null; // Pass 1 - identify the feature identifier for (int inx = 0; inx < attributes.size(); inx++) { // I am thinking it is probably safer to look this up // by column name than by position, but if it breaks, // it is easy enough to change if (attributes.get(inx).getLocalName().equals("id")) { value = row.getAttribute(inx); if (value != null) { featureId = value.toString(); } break; } } try { currentFeature = SimpleFeatureBuilder.build(featureType, values, featureId); } catch (IllegalAttributeException exc) { // This shouldn't happen since everything should be nillable exc.printStackTrace(); } // Pass 2 - get the attributes, including the geometry for (int inx = 0; inx < attributes.size(); inx++) { try { if (attributes .get(inx) .getLocalName() .equals(AnnotationFeatureType.ANNOTATION_ATTRIBUTE_NAME)) { try { // TODO: are we sure this is the intended action? Hard-coding an attribute to "nam"? currentFeature.setAttribute(inx, "nam"); } catch (IllegalAttributeException exc) { exc.printStackTrace(); } continue; } column = (VPFColumn) attributes.get(inx); value = null; secondFile = getVPFFile(column); SimpleFeature tempRow = (SimpleFeature) rows.get(secondFile); if (tempRow != null) { value = tempRow.getAttribute(column.getName()); if (column.isAttemptLookup()) { try { // Attempt to perform a lookup and conversion String featureClassName = getVPFFile(column).getFileName(); String intVdtFileName = featureType .getFeatureClass() .getDirectoryName() .concat(File.separator) .concat("int.vdt"); VPFFile intVdtFile = VPFFileFactory.getInstance().getFile(intVdtFileName); Iterator intVdtIter = intVdtFile.readAllRows().iterator(); while (intVdtIter.hasNext()) { SimpleFeature intVdtRow = (SimpleFeature) intVdtIter.next(); if (intVdtRow.getAttribute("table").toString().trim().equals(featureClassName) && (Short.parseShort(intVdtRow.getAttribute("value").toString()) == Short.parseShort(value.toString()) && (intVdtRow .getAttribute("attribute") .toString() .trim() .equals(column.getName())))) { value = intVdtRow.getAttribute("description").toString().trim(); break; } } // If there is a problem, forget about mapping and continue } catch (IOException exc) { } catch (RuntimeException exc) { } } } try { currentFeature.setAttribute(inx, value); } catch (ArrayIndexOutOfBoundsException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } catch (IllegalAttributeException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } } catch (ClassCastException exc2) { try { // This is the area geometry case featureType .getFeatureClass() .getGeometryFactory() .createGeometry(featureType, currentFeature); } catch (IllegalAttributeException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } catch (SQLException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } } } }
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(); } }