Using an IFeatureGeometryProviderIFeatureGeometryProviderIFeatureGeometryProvider, 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, DefaultFeatureGeometryProviderDefaultFeatureGeometryProviderDefaultFeatureGeometryProvider 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 layerconfigured on the layerconfigured on the layer.

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

Program: 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 point = GeometryFactory::createPoint(circle->getReference(), circle->getCenter());

    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;
};
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);

        var builder = originalFeature.AsBuilder();
        builder.Value(_pointPropertyPath, point);
        builder.Value(_radiusPropertyPath, circle.Radius);
        return builder.Build();
    }
};
public static final class CircleGeometryProvider implements IFeatureGeometryProvider {
  private final DataPropertyPath _pointPropertyPath;
  private final DataPropertyPath _radiusPropertyPath;

  public CircleGeometryProvider(DataType featureType) {
    _pointPropertyPath = DataPropertyPath.newBuilder().originType(featureType).property("point").build();
    _radiusPropertyPath = DataPropertyPath.newBuilder().originType(featureType).property("radius").build();
  }

  @Override
  public Geometry getGeometry(Feature feature) {
    Geometry pointGeometry = feature.getValue(_pointPropertyPath);
    Point point = (Point) pointGeometry;
    double radius = feature.<Double>getValue(_radiusPropertyPath);
    return GeometryFactory.createCircleByCenterPoint(point.getReference(), point.getLocation(), radius);
  }

  @Override
  public Feature applyGeometry(Feature originalFeature, Geometry newGeometry) {
    CircleByCenterPoint circle = (CircleByCenterPoint) newGeometry;
    Coordinate center = circle.getCenter();
    Point point = GeometryFactory.createPoint(circle.getReference(), center);

    Feature.Builder builder = originalFeature.asBuilder();
    builder.value(_pointPropertyPath, point);
    builder.value(_radiusPropertyPath, circle.getRadius());
    return builder.build();
  }
}