# Source: bemap-ol/bemap-map-ol-circle.js

    /**
     * Add a bemap.Circle to the layer
     * @public
     * @param {bemap.Circle} bemap.Circle.
     * @param {object} options
     * @return {bemap.OlMap}
     */
    bemap.OlMap.prototype.addCircle = function(circle, options) {
      if (circle && bemap.inheritsof(circle, bemap.Circle)) {
        circle.native = new ol.Feature({
          geometry: new ol.geom.Polygon.circular(new ol.Sphere(6378137), circle.getCoordinate().getLonLatArray(), circle.getRadius() * ol.proj.METERS_PER_UNIT.m, 128),
        });

        if (circle.map === null) {
          circle.map = this;
        }

        if (circle.id) {
          circle.native.setId(circle.id);
        }

        bemap.OlMap.prototype._addOwnToProperties(circle);

        circle.native.getGeometry().transform(bemap.Map.PROJ.EPSG_WGS84, this.native.getView().getProjection());

        if (circle.style) {
          if (circle.style.native === null) {
            this.buildCircleStyle(circle.style);
          }
          circle.native.setStyle(circle.style.native);
        }

        var opts = options || {};
        var l = null;

        if (opts.layer && bemap.inheritsof(opts.layer, bemap.VectorLayer)) {
          l = opts.layer;
        } else {
          l = this.getLayerByName(bemap.Map.DEFAULT_LAYER.CIRCLE);
          if (l === null) {
            l = new bemap.VectorLayer({
              name: bemap.Map.DEFAULT_LAYER.CIRCLE
            });
            this.addLayer(l);
          }
        }

        if (circle.layer === null) {
          circle.layer = l;
        }

        l.native.getSource().addFeature(circle.native);
      }
      return this;
    };

    /**
     * Set the coordinates of the circle.
     * @protected
     * @param {bemap.Circle} circle the circle object to remove.
     * @return {bemap.OlMap} this
     */
    bemap.OlMap.prototype.setCoordinateCircle = function(circle) {
      var c = circle.getCenter();
      circle.native.getGeometry().setCoordinates(this._fromLonLat(c.getLon(), c.getLat()));
      return this;
    };

    /**
     * Set the radius of the circle.
     * @protected
     * @param {bemap.Circle} circle the circle object to remove.
     * @return {bemap.OlMap} this
     */
    bemap.OlMap.prototype.setRadiusCircle = function(circle) {
      var c = circle.getCenter();
      circle.native.getGeometry().setCoordinates(this._fromLonLat(c.getLon(), c.getLat()));
      return this;
    };

    /**
     * Remove a circle from his layer.
     * @public
     * @param {bemap.Circle} circle the circle object to remove.
     */
    bemap.OlMap.prototype.removeCircle = function(circle) {
      if (circle && circle.layer && circle.layer.native && bemap.inheritsof(circle, bemap.Circle)) {
        circle.layer.native.getSource().removeFeature(circle.native);
        circle.layer = null;
        circle.map = null;
      }
      return this;
    };

    /**
     * Set the listner when an specified eventType occur on bemap.Circle.
     * @public
     * @param {bemap.Circle} circle
     * @param {bemap.Map.EventType} eventType Event type.
     * @param {function} callback Function will be called when the specified eventType is occur.
     * @param {object} options options.
     * @return {bemap.Listener} this.
     */
    bemap.OlMap.prototype.onCircle = function(circle, eventType, callback, options) {
      return this._onFeature(circle, eventType, callback, options, {
        singleFeature: true
      });
    };

    /**
     * Define the draggable capability for bemap.Circle.
     * @protected
     * @param {bemap.Circle} circle bemap object.
     * @param {function} callback Function will be called when the specified eventType is occur.
     * @param {object} options Options.
     * @param {bemap.Layer} options.layerFilter set the bemap layer used as filter.
     * @return {bemap.Listener} bemap.listener.
     */
    bemap.OlMap.prototype.draggableCircle = function(circle, callback, options) {
      return this._draggableFeature(circle, callback, options, {
        singleFeature: true
      });
    };

    /**
     * Define the draggable capability for all bemap.Circle.
     * @protected
     * @param {function} callback Function will be called when the specified eventType is occur.
     * @param {object} options Options.
     * @param {bemap.Layer} options.layerFilter set the bemap layer used as filter.
     * @return {bemap.Listener} bemap.listener.
     */
    bemap.OlMap.prototype.draggableCircles = function(callback, options) {
      return this._draggableFeature(null, callback, options, {
        circles: true
      });
    };

    /**
     * Update the coordinate from the native map browser.
     * @public
     */
    bemap.OlMap.prototype.updateCircleCenter = function(circle) {
      var cir = circle.native.getGeometry().getExtent();
      var oo = ol.extent.getCenter(cir);
      var circ = ol.proj.transform(oo, this.native.getView().getProjection(), bemap.Map.PROJ.EPSG_WGS84);

      var coord = circle.coordinate;

      if (coord && coord !== null && bemap.inheritsof(coord, bemap.Coordinate)) {
        coord.setLon(circ[0]);
        coord.setLat(circ[1]);
      } else {
        circle.coordinate = new bemap.Coordinate(circ[0], circ[1]);
      }

      if (circle.coordinate.length > cir.length) {
        for (var j = cir.length; j < circle.coordinate.length; j++) {
          circle.coordinate.pop();
        }
      }
    };