This article describes what to do to change how the editing of a feature starts off. By default, to start editing a feature, users need to select it on the map. By selecting it, they set the selected feature state to true. The goal is to change that, and select a feature for editing when users hover over it with the mouse cursor instead, or when a feature is configured.

Solution 1 - Configure the default edit candidate provider to use another feature state

The easiest way to change the feature state used to select a feature for editing, is to create your own instance of FeatureStateEditCandidateProvider, and configure it accordingly.

Program (C++): Change a default FeatureStateEditCandidateProvider
auto easyCandidateProvider = std::make_shared<FeatureStateEditCandidateProvider>(map, FeatureState::Hover);
auto hoveredEditor = Editor::newBuilder().map(map).editCandidateProvider(easyCandidateProvider).build();

C#

var easyCandidateProvider = new FeatureStateEditCandidateProvider(map, FeatureState.Hover);
var hoveredEditor = Editor.NewBuilder().Map(map).EditCandidateProvider(easyCandidateProvider).Build();

Solution 2 - Create a custom IFeatureEditCandidateProvider to use a field

Your second, more complex option is to create your own implementation of IFeatureEditCandidateProvider.

In this implementation, we use a field to store which features can be edited.

Program (C++): Create custom IFeatureEditCandidateProvider
class FixedEditCandidateProvider : public IFeatureEditCandidateProvider {
public:
  std::vector<LayerFeatureId> getEditCandidates() override {
    std::vector<LayerFeatureId> returnedVector;
    if (_candidate) {
      returnedVector.emplace_back(_candidate.value());
    }
    return returnedVector;
  }

  void setEditCandidate(const LayerFeatureId& featureId) {
    if (_candidate != featureId) {
      _candidate = featureId;
      FeatureEditCandidateEvent editCandidateEvent;
      editCandidateEvent.editCandidateAdded(featureId);
      for (const auto& observer : _observers) {
        observer->onEditCandidatesChanged(editCandidateEvent);
      }
    }
  }
  void addObserver(std::shared_ptr<IFeatureEditCandidateObserver> observer) override {
    if (findObserver(observer)) {
      throw InvalidArgumentException("Cannot add observer more than once.");
    }
    _observers.push_back(std::move(observer));
  }
  void removeObserver(const std::shared_ptr<IFeatureEditCandidateObserver>& observer) override {
    auto index = findObserver(observer);
    if (!index) {
      throw InvalidArgumentException("Cannot remove unknown observer.");
    }
    _observers.erase(_observers.cbegin() + *index);
  }

private:
  // returns the index of the observer if found, nullopt otherwise
  std::optional<size_t> findObserver(const std::shared_ptr<IFeatureEditCandidateObserver>& candidate) {
    for (size_t i = 0, max = _observers.size(); i < max; ++i) {
      if (_observers[i].get() == candidate.get()) {
        return i;
      }
    }
    return std::nullopt;
  }

  std::vector<std::shared_ptr<IFeatureEditCandidateObserver>> _observers;
  std::optional<LayerFeatureId> _candidate;
};

C#

public class FixedEditCandidateProvider : IFeatureEditCandidateProvider
{
    private IList<IFeatureEditCandidateObserver> _observers = new List<IFeatureEditCandidateObserver>();
    private LayerFeatureId? _editCandidate;

    public IList<LayerFeatureId> GetEditCandidates()
    {
        if (_editCandidate != null)
        {
            return new List<LayerFeatureId>() {_editCandidate.Value};
        }

        return new List<LayerFeatureId>();
    }

    public void SetEditCandidate(LayerFeatureId featureId)
    {
        if (_editCandidate == featureId) return;
        _editCandidate = featureId;
        FeatureEditCandidateEvent editCandidateEvent = new FeatureEditCandidateEvent();
        editCandidateEvent.EditCandidateAdded(featureId);
        FireEvent(editCandidateEvent);
    }

    private void FireEvent(FeatureEditCandidateEvent editCandidateEvent)
    {
        lock (_observers)
        {
            foreach (var observer in _observers)
            {
                observer.OnEditCandidatesChanged(editCandidateEvent);
            }
        }
    }

    public void AddObserver(IFeatureEditCandidateObserver observer)
    {
        lock (_observers)
        {
            if (_observers.Contains(observer))
            {
                throw new Exception("Cannot add observer more than once.");
            }

            _observers.Add(observer);
        }
    }


    public void RemoveObserver(IFeatureEditCandidateObserver observer)
    {
        lock (_observers)
        {
            if (!_observers.Remove(observer))
            {
                throw new Exception("Cannot remove unknown observer.");
            }
        }
    }
}

We can then use it in the Editor builder:

Program (C++): Use the custom IFeatureEditCandidateProvider
auto myEditCandidateProvider = std::make_shared<FixedEditCandidateProvider>();

// only this feature will be editable.
myEditCandidateProvider->setEditCandidate({1, 10});
auto myEditor = Editor::newBuilder().map(map).editCandidateProvider(std::move(myEditCandidateProvider)).build();

C#

var myEditCandidateProvider = new FixedEditCandidateProvider();

// only this feature will be editable.
myEditCandidateProvider.SetEditCandidate(new LayerFeatureId(1, 10));
var myEditor = Editor.NewBuilder().Map(map).EditCandidateProvider(myEditCandidateProvider).Build();