This article describes how you can configure the handle factory
handle factory
handle 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 HandleFactory
HandleFactory
HandleFactory
We must implement the FeatureHandlesProvider::IHandleFactory
FeatureHandlesProvider::IHandleFactory
FeatureHandlesProvider::IHandleFactory
. In the
createTranslateHandle
createTranslateHandle
createTranslateHandle
method, we must make sure that
the TranslateEditHandle
TranslateEditHandle
TranslateEditHandle
isn’t active.
You can do that in several ways:
-
Returning a
null
handle. This is fine for editing 2D shapes, but we lose the helper line when we’re editing 3D shapes. -
Returning a handle without an action, but with a
ShadowGeometryProvider
ShadowGeometryProvider
ShadowGeometryProvider
. This way, the helper line is still visible on the map during the editing of a 3D shape.
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 TranslateEditHandle
TranslateEditHandle
TranslateEditHandle
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:
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 HandleFactory
HandleFactory
HandleFactory
Now, we want to start using the handle factory. To do so, we need an implementation of IFeatureEditConfiguration
IFeatureEditConfiguration
IFeatureEditConfiguration
that uses
the factory in a feature handles provider. We are using the handle factory with the helper line.
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 FeatureEditConfiguration
FeatureEditConfiguration
FeatureEditConfiguration
in the Feature Layer
The final step is to use the edit configuration in the builder of the FeatureLayer
FeatureLayer
FeatureLayer
.
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();