A WFS service provides read access to features, while a Transactional WFS (WFS-T) service adds insert, update, delete, and
locking operations.
A LuciadRIA WFSFeatureStore supports both: see Visualize WFS data for the read-only side of the store.
Prerequisites
WFS-T requires:
-
A store created with
WFSFeatureStore.createFromCapabilities()orcreateFromURL(). These methods read the server’s advertised capabilities, so the store knows upfront which WFS-T operations are supported. -
A WFS 2.0 server that advertises the operation you’re calling:
Transactionforadd/put/remove,LockFeatureorGetFeatureWithLockfor locking.
If either condition isn’t met, the corresponding method throws a ProgrammingError immediately, without sending a request.
Insert, update, and delete features
The add(), put(), and remove() methods each send a single <wfs:Transaction> request with one action: to insert, update, or delete features respectively.
The add(feature) method inserts a new feature and returns the ID assigned by the server:
const id = await store.add(feature);
The put(feature) method updates an existing feature. Its feature.id must be set.
The defined properties and the geometry are sent to the server.
Set a property to null to clear it. If a property is undefined, it is omitted and the server-side value remains unchanged.
The same applies to feature.shape.
// Setting a property to null clears it server-side; leaving it undefined keeps the current value.
feature.properties.name = "Updated name";
await store.put(feature);
The remove(id) method deletes a feature by ID:
await store.remove(id);
Lock features for exclusive editing
If you lock features, you reserve them so that no other client can change them while you’re editing.
It’s optional: some servers lock automatically as soon as an edit starts, in which case you don’t need to call lockFeatures() yourself. To find out about possible automatic locking, check the AutomaticDataLocking OWS constraint on the server’s Transaction operation.
There are two ways to acquire a lock:
-
lockFeatures(filter)locks features matching an OGC condition, without retrieving them. -
queryWithLock(query)queries and locks the matching features in a single round-trip. UnlikelockFeatures(), it can’t report which features it failed to lock — there’s nonotLockedFeatureIdson its result.
const {lock, lockedFeatureIds} = await store.lockFeatures(identifiers(["road-42"]));
const {lock, cursor} = await store.queryWithLock({filter: identifiers(["road-42"])});
Both locking methods return a lock that you can pass as an options.lock transaction option to put() or remove() to authorize the change:
await store.put(feature, {lock});
A successful put() or remove() releases only the feature it touched from the lock, as determined by the default releaseAction: "SOME" property on the transaction option.
To release every feature still covered by the lock instead, pass releaseAction: "ALL".
Tracking which lock covers which feature IDs is your responsibility — the store doesn’t track this for you.
A lock expires automatically after its expiry (in seconds), or you can release it explicitly:
await lock.release();