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

    /**
     * Add a marker to the layer
     * @public
     * @param {bemap.Marker} marker
     * @param {object} options
     * @return {bemap.OlMap} this
     */
    bemap.OlMap.prototype.addMarker = function(marker, options) {
      if (marker !== null && bemap.inheritsof(marker, bemap.Marker)) {
        marker.native = new ol.Feature({
          geometry: new ol.geom.Point(marker.getCoordinate().getLonLatArray()),
        });

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

        if (marker.id !== undefined && marker.id !== null) {
          marker.native.setId(marker.id);
        }

        bemap.OlMap.prototype._addOwnToProperties(marker);

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

        if (marker.icon !== null && marker.icon.native === null) {
          this.buildIcon(marker.icon);
        }

        var styleParams = {};
        if (marker.icon && marker.icon.native) {
          styleParams.image = marker.icon.native;
        }
        if (marker.name && marker.textStyle) {
          this.buildTextStyle(marker.textStyle, marker.name);
          styleParams.text = marker.textStyle.native;
        }
        marker.native.setStyle(new ol.style.Style(styleParams));

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

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

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

        if (bemap.inheritsof(l, bemap.VectorLayer)) {
          l.native.getSource().addFeature(marker.native);
        } else {
          l.native.getSource().getSource().addFeature(marker.native);
        }
      }
      return this;
    };

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

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

    /**
     * Set the listner when an specified eventType occur on bemap.Marker.
     * @public
     * @param {bemap.Marker} marker
     * @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.onMarker = function(marker, eventType, callback, options) {
      return this._onFeature(marker, eventType, callback, options, {
        singleFeature: true
      });
    };

    /**
     * Set the listner when an specified eventType occur on all bemap.Marker.
     * @public
     * @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.onMarkers = function(eventType, callback, options) {
      return this._onFeature(null, eventType, callback, options, {
        markers: true
      });
    };

    /**
     * Define the draggable capability for bemap.Marker.
     * @protected
     * @param {bemap.Marker} marker 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.draggableMarker = function(marker, callback, options) {
      return this._draggableFeature(marker, callback, options, {
        singleFeature: true
      });
    };

    /**
     * Define the draggable capability for all bemap.Marker.
     * @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.draggableMarkers = function(callback, options) {
      return this._draggableFeature(null, callback, options, {
        markers: true
      });
    };

    /**
     * Add a multimarker to the layer
     * @public
     * @param {bemap.Marker} multimarker
     * @param {object} options
     * @return {bemap.OlMap} this
     */
    bemap.OlMap.prototype.addMultiMarker = function(multimarker, options) {
      if (multimarker !== null && bemap.inheritsof(multimarker, bemap.MultiMarker)) {
        multimarker.native = new ol.Feature({
          geometry: new ol.geom.MultiPoint(multimarker.getLonLatArrays())
        });

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

        if (multimarker.id !== undefined && multimarker.id !== null) {
          multimarker.native.setId(multimarker.id);
        }

        bemap.OlMap.prototype._addOwnToProperties(multimarker);

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

        if (multimarker.icon.native === null) {
          this.buildIcon(multimarker.icon);
        }

        var styleParams = {};
        if (multimarker.icon && multimarker.icon.native) {
          styleParams.image = multimarker.icon.native;
        }
        if (multimarker.name && multimarker.textStyle) {
          this.buildTextStyle(multimarker.textStyle, multimarker.name);
          styleParams.text = multimarker.textStyle.native;
        }
        multimarker.native.setStyle(new ol.style.Style(styleParams));

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

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

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

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

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

    /**
     * Set the listner when an specified eventType occur on all bemap.MultiMarker.
     * @public
     * @param {bemap.Map.EventType} eventType Event type.
     * @param {function} listener Function will be called when the specified eventType is occur.
     * @param {object} options options.
     * @return {bemap.Listener} bemap.Listener.
     */
    bemap.OlMap.prototype.onMultiMarkers = function(eventType, listener, options) {
      return this._onFeature(null, eventType, listener, options, {
        multiMarkers: true
      });
    };

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

    /**
     * Define the draggable capability for all bemap.MultiMarkers.
     * @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.draggableMultiMarkers = function(callback, options) {
      return this._draggableFeature(null, callback, options, {
        multiMarkers: true
      });
    };