Add feature herald

The feature herald takes care of managing a single feature at
a time.
This commit is contained in:
Alexandre Dubé 2015-09-30 09:10:06 -04:00
parent 0c9b849c5d
commit 37f7e708fd
8 changed files with 186 additions and 45 deletions

View File

@ -14,7 +14,11 @@
<fieldset>
<legend>OpenLayers</legend>
<input id="add-point" type="button" value="Add a point"></input>
<label>Marker: </label>
<input id="add-point" type="button" value="Add (10)"></input>
<input id="clear-point" type="button" value="Clear"></input>
<label>Other: </label>
<input id="toggle-osm" type="button" value="Toogle OSM Layer"></input>
</fieldset>

View File

@ -35,22 +35,11 @@ gmap.data.setStyle({
*/
var olgmMain = new olgm.OLGoogleMaps({
ol3map: ol3map
});
var vector = new ol.layer.Vector({
source: new ol.source.Vector()
});
ol3map.addLayer(vector);
olgmMain.activate();
document.getElementById('add-point').onclick = function() {
vector.getSource().addFeature(generateFeature());
};
var generateFeature = function() {
var extent = [-9259955, 5467881, -6324773, 7424669];
var deltaX = extent[2] - extent[0];
@ -63,6 +52,27 @@ var generateFeature = function() {
return feature;
};
var addFeatures = function(len) {
for (var i = 0; i < len; i++) {
vector.getSource().addFeature(generateFeature());
}
};
addFeatures(10);
var olgmMain = new olgm.OLGoogleMaps({
ol3map: ol3map
});
olgmMain.activate();
document.getElementById('add-point').onclick = function() {
addFeatures(10);
};
document.getElementById('clear-point').onclick = function() {
vector.getSource().clear();
};
var toggleOsmLayer = function(opt_visible) {
var visible = opt_visible !== undefined ? opt_visible :

View File

@ -3,7 +3,6 @@ goog.provide('olgm.FeatureFactory');
goog.require('goog.asserts');
//goog.require('ol.geom.Point');
//goog.require('ol.proj');
goog.require('olgm.Abstract');
@ -12,37 +11,30 @@ goog.require('olgm.Abstract');
* and GoogleMaps ones.
*
* @constructor
* @param {!ol.Map} ol3map
* @param {!google.maps.Map} gmap
* @extends {olgm.Abstract}
* @api
*/
olgm.FeatureFactory = function(ol3map, gmap) {
/**
* @type {ol.proj.Projection}
* @private
*/
this.ol3Proj_ = ol3map.getView().getProjection();
goog.base(this, ol3map, gmap);
};
goog.inherits(olgm.FeatureFactory, olgm.Abstract);
olgm.FeatureFactory = function() {};
/**
* Create a Google Maps feature using an OpenLayers one.
* @param {ol.Feature} feature
* @param {ol.Map=} opt_ol3map For reprojection purpose. If undefined, then
* `EPSG:3857` is used.
* @return {google.maps.Data.Feature}
* @api
*/
olgm.FeatureFactory.prototype.createGoogleMapsFeature = function(feature) {
olgm.FeatureFactory.prototype.createGoogleMapsFeature = function(
feature, opt_ol3map) {
var inProj = (opt_ol3map !== undefined) ?
opt_ol3map.getView().getProjection() : 'EPSG:3857';
// FIXME - hardcoded, only points are currently supported
var geometry = feature.getGeometry();
goog.asserts.assertInstanceof(geometry, ol.geom.Point);
var coordinates = geometry.getCoordinates();
var lonLatCoords = ol.proj.transform(coordinates, this.ol3Proj_, 'EPSG:4326');
var lonLatCoords = ol.proj.transform(coordinates, inProj, 'EPSG:4326');
return new google.maps.Data.Feature({
geometry: new google.maps.LatLng(lonLatCoords[1], lonLatCoords[0])

View File

@ -0,0 +1,66 @@
goog.provide('olgm.herald.Feature');
goog.require('olgm.FeatureFactory');
goog.require('olgm.herald.Herald');
/**
* The Feature Herald is responsible of listening to any changes made to
* a single ol3 vector feature and apply those changes to a gmap vector
* feature sibling, which gets created here as well.
*
* @param {!ol.Map} ol3map
* @param {!google.maps.Map} gmap
* @param {ol.Feature} feature
* @constructor
* @extends {olgm.herald.Herald}
* @api
*/
olgm.herald.Feature = function(ol3map, gmap, feature) {
/**
* @type {ol.Feature}
* @private
*/
this.feature_ = feature;
goog.base(this, ol3map, gmap);
};
goog.inherits(olgm.herald.Feature, olgm.herald.Herald);
/**
* @type {google.maps.Data.Feature}
* @private
*/
olgm.herald.Feature.prototype.gmapFeature_ = null;
/**
* @inheritDoc
*/
olgm.herald.Feature.prototype.activate = function() {
goog.base(this, 'activate');
// create gmap feature
this.gmapFeature_ = new olgm.FeatureFactory().createGoogleMapsFeature(
this.feature_);
this.gmap.data.add(this.gmapFeature_);
// event listeners (todo)
};
/**
* @inheritDoc
*/
olgm.herald.Feature.prototype.deactivate = function() {
// remove gmap feature
this.gmap.data.remove(this.gmapFeature_);
this.gmapFeature = null;
goog.base(this, 'deactivate');
};

View File

@ -5,6 +5,8 @@ goog.require('goog.asserts');
//goog.require('ol.layer.Vector');
goog.require('olgm.herald.Herald');
goog.require('olgm.herald.VectorSource');
goog.require('olgm.herald.View');
goog.require('olgm.layer.Google');
@ -103,11 +105,10 @@ olgm.herald.Layers.prototype.googleMapsIsActive_ = false;
olgm.herald.Layers.prototype.activate = function() {
goog.base(this, 'activate');
// watch existing layers
var layers = this.ol3map.getLayers();
layers.forEach(function(layer) {
this.watchLayer_(layer);
}, this);
// watch existing layers
layers.forEach(this.watchLayer_, this);
// event listeners
var keys = this.listenerKeys;

View File

@ -3,6 +3,7 @@ goog.provide('olgm.herald.VectorSource');
goog.require('goog.asserts');
//goog.require('ol.Feature');
goog.require('olgm.FeatureFactory');
goog.require('olgm.herald.Feature');
goog.require('olgm.herald.Herald');
@ -25,10 +26,16 @@ goog.require('olgm.herald.Herald');
olgm.herald.VectorSource = function(ol3map, gmap, source) {
/**
* @type {olgm.FeatureFactory}
* @type {Array.<ol.Feature>}
* @private
*/
this.featureFactory_ = new olgm.FeatureFactory(ol3map, gmap);
this.features_ = [];
/**
* @type {Array.<olgm.herald.VectorSource.Cache>}
* @private
*/
this.cache_ = [];
/**
* @type {ol.source.Vector}
@ -48,10 +55,12 @@ olgm.herald.VectorSource.prototype.activate = function() {
goog.base(this, 'activate');
// watch existing features...
this.source_.getFeatures().forEach(this.watchFeature_, this);
// event listeners
var keys = this.listenerKeys;
keys.push(this.source_.on('addfeature', this.handleSourceAddFeature_, this));
keys.push(this.source_.on('addfeature', this.handleAddFeature_, this));
keys.push(this.source_.on('removefeature', this.handleRemoveFeature_, this));
};
@ -67,13 +76,66 @@ olgm.herald.VectorSource.prototype.deactivate = function() {
* @param {ol.source.VectorEvent} event
* @private
*/
olgm.herald.VectorSource.prototype.handleSourceAddFeature_ = function(event) {
olgm.herald.VectorSource.prototype.handleAddFeature_ = function(event) {
var feature = event.feature;
goog.asserts.assertInstanceof(feature, ol.Feature);
// FIXME - keep a reference between the two objects for future purpose,
// such as removal from the layer
var gmapFeature = this.featureFactory_.createGoogleMapsFeature(feature);
this.gmap.data.add(gmapFeature);
this.watchFeature_(feature);
};
/**
* @param {ol.source.VectorEvent} event
* @private
*/
olgm.herald.VectorSource.prototype.handleRemoveFeature_ = function(event) {
var feature = event.feature;
goog.asserts.assertInstanceof(feature, ol.Feature);
this.unwatchFeature_(feature);
};
/**
* @param {ol.Feature} feature
* @private
*/
olgm.herald.VectorSource.prototype.watchFeature_ = function(feature) {
// push to features (internal)
this.features_.push(feature);
// create and activate feature herald
var herald = new olgm.herald.Feature(this.ol3map, this.gmap, feature);
herald.activate();
// push to cache
this.cache_.push({
'feature': feature,
'herald': herald
});
};
/**
* @param {ol.Feature} feature
* @private
*/
olgm.herald.VectorSource.prototype.unwatchFeature_ = function(feature) {
var index = this.features_.indexOf(feature);
if (index !== -1) {
// remove from features (internal)
this.features_.splice(index, 1);
// deactivate feature herald
this.cache_[index].herald.deactivate();
// remove from cache
this.cache_.splice(index, 1);
}
};
/**
* @typedef {{
* feature: (ol.Feature),
* herald: (olgm.herald.Feature)
* }}
*/
olgm.herald.VectorSource.Cache;

View File

@ -1,6 +1,8 @@
goog.provide('olgm.herald.View');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
//goog.require('ol.proj');
goog.require('olgm.herald.Herald');
@ -41,7 +43,11 @@ olgm.herald.View.prototype.activate = function() {
var view = this.ol3map.getView();
var keys = this.listenerKeys;
// listen to center change
keys.push(view.on('change:center', this.setCenter, this));
// listen to resolution change
keys.push(view.on('change:resolution', this.setZoom, this));
// listen to browser window resize
@ -54,8 +60,6 @@ olgm.herald.View.prototype.activate = function() {
this.setCenter();
this.setZoom();
// FIXME - handle browser resize as well...
};

View File

@ -1,5 +1,7 @@
goog.provide('olgm');
goog.require('goog.events');
/**
* @param {Array.<goog.events.Key>} listenerKeys