This article describes how you can configure the handle factoryhandle factoryhandle factory of the feature handles provider to deactivate the translate handle.

Other customizations

For more information about customizing an existing handles provider, see this article.

Step 1 - Create a custom HandleFactoryHandleFactoryHandleFactory

You can do that in several ways:

Returning a null handle

We return a nullptr handle in our Handlefactory.

class NullFeatureHandleFactory : public FeatureHandlesProvider::IHandleFactory {
public:
  std::shared_ptr<IEditHandle> createTranslateHandle(const std::shared_ptr<Observable<Feature>>& /*feature*/,
                                                     const std::shared_ptr<Observable<std::shared_ptr<Geometry>>>& /*geometry*/,
                                                     const std::shared_ptr<ITranslateEditAction>& /*editAction*/,
                                                     const std::shared_ptr<FeatureEditContext>& /*context*/) override {
    return nullptr;
  }

  bool isTranslateHandleValid(const std::shared_ptr<IEditHandle>& /*translateHandle*/,
                              const std::shared_ptr<Observable<Feature>>& /*feature*/,
                              const std::shared_ptr<Observable<std::shared_ptr<Geometry>>>& /*geometry*/,
                              const std::shared_ptr<FeatureEditContext>& /*context*/) override {
    return true;
  }
};
class NullFeatureHandleFactory : FeatureHandlesProvider.IHandleFactory
{
    public IEditHandle CreateTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
        FeatureEditContext context)
    {
        return null;
    }

    public bool IsTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
        FeatureEditContext context)
    {
        return true;
    }
}
public static class NullFeatureHandleFactory implements FeatureHandlesProvider.IHandleFactory {
  @Override
  public IEditHandle createTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
                                           FeatureEditContext context) {
    return null;
  }

  @Override
  public boolean isTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
                                        FeatureEditContext context) {
    return true;
  }
}

Returning a handle without an action

We return a TranslateEditHandleTranslateEditHandleTranslateEditHandle without an action, but with a shadow geometry provider. We use this provider to draw a draped version of our geometry if the shape is a 3D one. The CreateTranslateHandle method for this factory becomes:

Program: Returning a handle without an action
std::shared_ptr<IEditHandle> createTranslateHandle(const std::shared_ptr<Observable<Feature>>& /*feature*/,
                                                   const std::shared_ptr<Observable<std::shared_ptr<Geometry>>>& geometry,
                                                   const std::shared_ptr<ITranslateEditAction>& /*editAction*/,
                                                   const std::shared_ptr<FeatureEditContext>& context) override {
  auto handle = std::make_shared<TranslateEditHandle>(geometry->getValue()->getReference(), context);
  handle->setShadowGeometryProvider(geometry); // To let the handle paint the helper lines in case of a 3D Polyline
  return handle;
}
public IEditHandle CreateTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
    FeatureEditContext context)
{
    var handle = new TranslateEditHandle(geometry.Value.Reference, context);
    // To let the handle paint the helper lines in case of a 3D Polyline
    handle.ShadowGeometryProvider = geometry;
    return handle;
}
@Override
public IEditHandle createTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
                                         FeatureEditContext context) {
  TranslateEditHandle handle = new TranslateEditHandle(geometry.getValue().getReference(), context);
  // To let the handle paint the helper lines in case of a 3D Polyline
  handle.setShadowGeometryProvider(geometry);
  return handle;
}

Step 2 - Use the HandleFactoryHandleFactoryHandleFactory

Now, we want to start using the handle factory. To do so, we need an implementation of IFeatureEditConfigurationIFeatureEditConfigurationIFeatureEditConfiguration that uses the factory in a feature handles provider. We are using the handle factory with the helper line.

Program: Use handle factory
class NoTranslateEditConfiguration final : public IFeatureEditConfiguration {
public:
  NoTranslateEditConfiguration() {
    auto featuresHandlesProvider = std::make_shared<FeatureHandlesProvider>();
    auto customFeatureHandleFactory = std::make_shared<StillVisibleFeatureHandleFactory>();
    featuresHandlesProvider->setHandleFactory(std::move(customFeatureHandleFactory));

    _featureHandlesProvider = featuresHandlesProvider;
  }

  void edit(const Feature& /*feature*/, LayerId /*layerId*/, const std::shared_ptr<Map>& /*map*/, FeatureEditConfigurationBuilder& builder) const override {
    // Use a custom handles provider for all features
    builder.handlesProvider(_featureHandlesProvider).submit();
  }

private:
  std::shared_ptr<IFeatureHandlesProvider> _featureHandlesProvider;
};
class NullFeatureHandleFactory : FeatureHandlesProvider.IHandleFactory
{
    public IEditHandle CreateTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
        FeatureEditContext context)
    {
        return null;
    }

    public bool IsTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
        FeatureEditContext context)
    {
        return true;
    }
}

class StillVisibleFeatureHandleFactory : FeatureHandlesProvider.IHandleFactory
{
    public IEditHandle CreateTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
        FeatureEditContext context)
    {
        var handle = new TranslateEditHandle(geometry.Value.Reference, context);
        // To let the handle paint the helper lines in case of a 3D Polyline
        handle.ShadowGeometryProvider = geometry;
        return handle;
    }

    public bool IsTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
        FeatureEditContext context)
    {
        return true;
    }
}

class NoTranslateEditConfiguration : IFeatureEditConfiguration
{
    private readonly IFeatureHandlesProvider _featureHandlesProvider;

    public NoTranslateEditConfiguration()
    {
        var featuresHandlesProvider = new FeatureHandlesProvider();
        var customFeatureHandleFactory = new StillVisibleFeatureHandleFactory();
        featuresHandlesProvider.HandleFactory = customFeatureHandleFactory;

        _featureHandlesProvider = featuresHandlesProvider;
    }

    public void Edit(Feature feature, ulong layerId, Map map, FeatureEditConfigurationBuilder builder)
    {
        builder.HandlesProvider(_featureHandlesProvider).Submit();
    }
}
public static class NullFeatureHandleFactory implements FeatureHandlesProvider.IHandleFactory {
  @Override
  public IEditHandle createTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
                                           FeatureEditContext context) {
    return null;
  }

  @Override
  public boolean isTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
                                        FeatureEditContext context) {
    return true;
  }
}


public static class StillVisibleFeatureHandleFactory implements
                                                     FeatureHandlesProvider.IHandleFactory {
  @Override
  public IEditHandle createTranslateHandle(Observable<Feature> feature, Observable<Geometry> geometry, ITranslateEditAction action,
                                           FeatureEditContext context) {
    TranslateEditHandle handle = new TranslateEditHandle(geometry.getValue().getReference(), context);
    // To let the handle paint the helper lines in case of a 3D Polyline
    handle.setShadowGeometryProvider(geometry);
    return handle;
  }

  @Override
  public boolean isTranslateHandleValid(IEditHandle translateHandle, Observable<Feature> feature, Observable<Geometry> geometry,
                                        FeatureEditContext context) {
    return true;
  }
}

public static class NoTranslateEditConfiguration implements IFeatureEditConfiguration {
  private final IFeatureHandlesProvider _featureHandlesProvider;

  public NoTranslateEditConfiguration() {
    FeatureHandlesProvider featuresHandlesProvider = new FeatureHandlesProvider();
    StillVisibleFeatureHandleFactory customFeatureHandleFactory = new StillVisibleFeatureHandleFactory();
    featuresHandlesProvider.setHandleFactory(customFeatureHandleFactory);

    _featureHandlesProvider = featuresHandlesProvider;
  }

  @Override
  public void edit(Feature feature, long layerId, Map map, FeatureEditConfigurationBuilder builder) {
    builder.handlesProvider(_featureHandlesProvider).submit();
  }
}

Step 3 - Use the FeatureEditConfigurationFeatureEditConfigurationFeatureEditConfiguration in the Feature Layer

The final step is to use the edit configuration in the builder of the FeatureLayerFeatureLayerFeatureLayer.

Program: Use edit configuration
auto editConfiguration = std::make_shared<NoTranslateEditConfiguration>();
return FeatureLayer::newBuilder().model(model).editable(true).editConfiguration(std::move(editConfiguration)).build();
var editConfiguration = new NoTranslateEditConfiguration();
return FeatureLayer.NewBuilder().Model(model).Editable(true).EditConfiguration(editConfiguration).Build();
NoTranslateEditConfiguration editConfiguration = new NoTranslateEditConfiguration();
return FeatureLayer.newBuilder().model(model).editable(true).editConfiguration(editConfiguration).build();