addFeature(feature, register) {
    register = register !== undefined ? register : true;
    const feature_uid = getUid(feature);
    const geometry = feature.getGeometry();
    if (geometry) {
      const segmenter = this.segmenters_[geometry.getType()];
      if (segmenter) {
        this.indexedFeaturesExtents_[feature_uid] =
          geometry.getExtent(createEmpty());
        const segments = segmenter(
          geometry,
          this.getMap().getView().getProjection(),
        );
        let segmentCount = segments.length;
        for (let i = 0; i < segmentCount; ++i) {
          const segment = segments[i];
          tempExtents[i] = boundingExtent(segment);
          tempSegmentData[i] = {
            feature: feature,
            segment: segment,
          };
        }
        tempExtents.length = segmentCount;
        tempSegmentData.length = segmentCount;

        if (this.intersection_) {
          for (let j = 0, jj = segments.length; j < jj; ++j) {
            const segment = segments[j];
            if (segment.length === 1) {
              continue;
            }
            const extent = tempExtents[j];
            // Calculate intersections with own segments
            for (let k = 0, kk = segments.length; k < kk; ++k) {
              if (j === k || j - 1 === k || j + 1 === k) {
                // Exclude self and neighbours
                continue;
              }
              const otherSegment = segments[k];
              if (!intersectsExtent(extent, tempExtents[k])) {
                continue;
              }
              const intersection = getIntersectionPoint(segment, otherSegment);
              if (!intersection) {
                continue;
              }
              const intersectionSegment = [intersection];
              tempExtents[segmentCount] = boundingExtent(intersectionSegment);
              tempSegmentData[segmentCount++] = {
                feature,
                segment: intersectionSegment,
                isIntersection: true,
              };
            }
            // Calculate intersections with existing segments
            const otherSegments = this.rBush_.getInExtent(tempExtents[j]);
            for (const {segment: otherSegment} of otherSegments) {
              if (otherSegment.length === 1) {
                continue;
              }
              const intersection = getIntersectionPoint(segment, otherSegment);
              if (!intersection) {
                continue;
              }
              const intersectionSegment = [intersection];
              tempExtents[segmentCount] = boundingExtent(intersectionSegment);
              tempSegmentData[segmentCount++] = {
                feature,
                segment: intersectionSegment,
                isIntersection: true,
              };
            }
          }
        }

        if (segmentCount === 1) {
          this.rBush_.insert(tempExtents[0], tempSegmentData[0]);
        } else {
          this.rBush_.load(tempExtents, tempSegmentData);
        }
      }
    }

    if (register) {
      this.featureChangeListenerKeys_[feature_uid] = listen(
        feature,
        EventType.CHANGE,
        this.handleFeatureChange_,
        this,
      );
    }
  }
Add a feature to the collection of features that we may snap to.
@param {import("../Feature.js").default} feature Feature.
@param {boolean} [register] Whether to listen to the feature change or not
    Defaults to `true`.
@api