ol3-google-maps
Version:
OpenLayers 3 Google Maps integration library
254 lines (202 loc) • 5.82 kB
JavaScript
goog.provide('olgm.herald.Feature');
goog.require('ol');
goog.require('ol.Observable');
goog.require('ol.style.Icon');
goog.require('olgm');
goog.require('olgm.asserts');
goog.require('olgm.gm');
goog.require('olgm.herald.Herald');
/**
* The Feature Herald is responsible of synchronizing a single ol3 vector
* feature to a gmap feature. Here's what synchronized within the feature:
*
* - its geometry
* - its style
*
* @param {!ol.Map} ol3map openlayers map
* @param {!google.maps.Map} gmap google maps map
* @param {olgmx.herald.FeatureOptions} options options
* @constructor
* @extends {olgm.herald.Herald}
*/
olgm.herald.Feature = function(ol3map, gmap, options) {
/**
* @type {ol.Feature}
* @private
*/
this.feature_ = options.feature;
/**
* @type {!google.maps.Data}
* @private
*/
this.data_ = options.data;
/**
* @type {number}
* @private
*/
this.index_ = options.index;
/**
* @type {olgmx.gm.MapIconOptions}
* @private
*/
this.mapIconOptions_ = options.mapIconOptions;
/**
* @type {boolean}
* @private
*/
this.visible_ = options.visible !== undefined ? options.visible : true;
olgm.herald.Herald.call(this, ol3map, gmap);
};
ol.inherits(olgm.herald.Feature, olgm.herald.Herald);
/**
* @type {google.maps.Data.Feature}
* @private
*/
olgm.herald.Feature.prototype.gmapFeature_ = null;
/**
* @type {olgm.gm.MapLabel}
* @private
*/
olgm.herald.Feature.prototype.label_ = null;
/**
* The marker object contains a marker to draw on a canvas instead of using
* the Google Maps API. If useCanvas_ is set to false, this variable won't
* be used.
* @type {olgm.gm.MapIcon}
* @private
*/
olgm.herald.Feature.prototype.marker_ = null;
/**
* @inheritDoc
*/
olgm.herald.Feature.prototype.activate = function() {
olgm.herald.Herald.prototype.activate.call(this);
var geometry = this.getGeometry_();
// create gmap feature
this.gmapFeature_ = olgm.gm.createFeature(this.feature_);
if (this.visible_) {
this.data_.add(this.gmapFeature_);
}
// override style if a style is defined at the feature level
var gmStyle = olgm.gm.createStyle(
this.feature_, this.mapIconOptions_, this.index_);
if (gmStyle) {
this.data_.overrideStyle(this.gmapFeature_, gmStyle);
}
// if the feature has text style, add a map label to gmap
var latLng = olgm.gm.createLatLng(olgm.getCenterOf(geometry));
var style = olgm.getStyleOf(this.feature_);
if (style) {
var zIndex = style.getZIndex();
var index = zIndex !== undefined ? zIndex : this.index_;
var image = style.getImage();
var useCanvas = this.mapIconOptions_.useCanvas !== undefined ?
this.mapIconOptions_.useCanvas : false;
if (image && image instanceof ol.style.Icon && useCanvas) {
this.marker_ = olgm.gm.createMapIcon(image, latLng, index);
if (this.visible_) {
this.marker_.setMap(this.gmap);
}
}
var text = style.getText();
if (text) {
this.label_ = olgm.gm.createLabel(text, latLng, index);
if (this.visible_) {
this.label_.setMap(this.gmap);
}
}
}
// event listeners (todo)
var keys = this.listenerKeys;
this.geometryChangeKey_ = geometry.on(
'change', this.handleGeometryChange_, this);
keys.push(this.geometryChangeKey_);
keys.push(this.feature_.on(
'change:' + this.feature_.getGeometryName(),
this.handleGeometryReplace_, this
));
};
/**
* @inheritDoc
*/
olgm.herald.Feature.prototype.deactivate = function() {
// remove gmap feature
this.data_.remove(this.gmapFeature_);
this.gmapFeature_ = null;
// remove feature
if (this.marker_) {
this.marker_.setMap(null);
this.marker_ = null;
}
// remove label
if (this.label_) {
this.label_.setMap(null);
this.label_ = null;
}
olgm.herald.Herald.prototype.deactivate.call(this);
};
/**
* Set visible or invisible, without deleting the feature object
* @param {boolean} value true to set visible, false to set invisible
*/
olgm.herald.Feature.prototype.setVisible = function(value) {
if (value && !this.visible_) {
this.data_.add(this.gmapFeature_);
if (this.marker_) {
this.marker_.setMap(this.gmap);
}
if (this.label_) {
this.label_.setMap(this.gmap);
}
this.visible_ = true;
} else if (!value && this.visible_) {
this.data_.remove(this.gmapFeature_);
if (this.marker_) {
this.marker_.setMap(null);
}
if (this.label_) {
this.label_.setMap(null);
}
this.visible_ = false;
}
};
/**
* @private
* @return {ol.geom.Geometry} the feature's geometry
*/
olgm.herald.Feature.prototype.getGeometry_ = function() {
var geometry = this.feature_.getGeometry();
olgm.asserts.assert(
geometry !== undefined, 'Expected feature to have geometry');
return /** @type {ol.geom.Geometry} */ (geometry);
};
/**
* @private
*/
olgm.herald.Feature.prototype.handleGeometryChange_ = function() {
var geometry = this.getGeometry_();
this.gmapFeature_.setGeometry(olgm.gm.createFeatureGeometry(geometry));
var latLng;
if (this.label_) {
latLng = olgm.gm.createLatLng(olgm.getCenterOf(geometry));
this.label_.set('position', latLng);
}
if (this.marker_) {
latLng = olgm.gm.createLatLng(olgm.getCenterOf(geometry));
this.marker_.set('position', latLng);
}
};
/**
* @private
*/
olgm.herald.Feature.prototype.handleGeometryReplace_ = function() {
var keys = this.listenerKeys;
ol.Observable.unByKey(this.geometryChangeKey_);
var index = keys.indexOf(this.geometryChangeKey_);
keys.splice(index, 1);
this.geometryChangeKey_ = this.feature_.getGeometry().on('change',
this.handleGeometryChange_,
this);
keys.push(this.geometryChangeKey_);
this.handleGeometryChange_();
};