Using an IFeatureGeometryProvider, you can specify which geometry to use for editing a feature, and how to apply changes to that feature. This class has a default implementation, DefaultFeatureGeometryProvider that you can use for simple cases. Have a look at the class documentation for more information. A geometry provider can be configured on the layer.

This sample shows how you can implement an IFeatureGeometryProvider that provides a circle edit geometry for a Feature with location and radius properties.

Program (C++): Provide circle edit geometry
class CircleGeometryProvider final : public IFeatureGeometryProvider {
public:
  explicit CircleGeometryProvider(const DataType& featureType)
      : _pointPropertyPath(DataPropertyPath::newBuilder().originType(featureType).property("point").build()),
        _radiusPropertyPath(DataPropertyPath::newBuilder().originType(featureType).property("radius").build()) {
  }

  std::shared_ptr<Geometry> getGeometry(const Feature& feature) override {
    auto pointGeometry = feature.getValue<std::shared_ptr<Geometry>>(_pointPropertyPath);
    auto point = std::dynamic_pointer_cast<Point>(*pointGeometry);
    auto radius = feature.getValue<double>(_radiusPropertyPath);
    return GeometryFactory::createCircleByCenterPoint(point->getReference(), point->getLocation(), *radius);
  }

  std::optional<Feature> applyGeometry(Feature originalFeature, std::shared_ptr<Geometry> newGeometry) override {
    auto circle = std::dynamic_pointer_cast<CircleByCenterPoint>(newGeometry);
    auto center = circle->getCenter();
    auto point = GeometryFactory::createPoint(circle->getReference(), center.x, center.y, center.z);

    auto builder = originalFeature.asBuilder();
    builder.value(_pointPropertyPath, std::dynamic_pointer_cast<Geometry>(point));
    builder.value(_radiusPropertyPath, circle->getRadius());
    return builder.build();
  }

private:
  DataPropertyPath _pointPropertyPath;
  DataPropertyPath _radiusPropertyPath;
};

C#

public sealed class CircleGeometryProvider : IFeatureGeometryProvider
{
    private DataPropertyPath _pointPropertyPath;
    private DataPropertyPath _radiusPropertyPath;

    public CircleGeometryProvider(DataType featureType)
    {
        _pointPropertyPath = DataPropertyPath.NewBuilder().OriginType(featureType).Property("point").Build();
        _radiusPropertyPath = DataPropertyPath.NewBuilder().OriginType(featureType).Property("radius").Build();
    }

    public Geometry GetGeometry(Feature feature)
    {
        var pointGeometry = feature.GetValue<Geometry>(_pointPropertyPath);
        var point = pointGeometry as Point;
        var radius = feature.GetValue<double?>(_radiusPropertyPath).Value;
        return GeometryFactory.CreateCircleByCenterPoint(point.Reference, point.Location, radius);
    }

    public Feature ApplyGeometry(Feature originalFeature, Geometry newGeometry)
    {
        var circle = newGeometry as CircleByCenterPoint;
        var center = circle.Center;
        var point = GeometryFactory.CreatePoint(circle.Reference, center.X, center.Y, center.Z);

        var builder = originalFeature.AsBuilder();
        builder.Value(_pointPropertyPath, point);
        builder.Value(_radiusPropertyPath, circle.Radius);
        return builder.Build();
    }
};