1 /***************************************
  2  * Copyright 2011, 2012 GlobWeb contributors.
  3  *
  4  * This file is part of GlobWeb.
  5  *
  6  * GlobWeb is free software: you can redistribute it and/or modify
  7  * it under the terms of the GNU Lesser General Public License as published by
  8  * the Free Software Foundation, version 3 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * GlobWeb is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14  * GNU Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with GlobWeb. If not, see <http://www.gnu.org/licenses/>.
 18  ***************************************/
 19  
 20 define(['./Utils', './BaseLayer', './FeatureStyle'], 
 21 	function(Utils, BaseLayer, FeatureStyle) {
 22 
 23 /**************************************************************************************************************/
 24 
 25 /** @name VectorLayer
 26 	@class
 27 	Create a layer to display vector data in GeoJSON format.
 28 	@augments BaseLayer
 29 	@param options Configuration properties for VectorLayer. See {@link BaseLayer} for base properties :
 30 		<ul>
 31 			<li>style : the style to use. See {@link FeatureStyle}</li>
 32 		</ul>
 33  */
 34 var VectorLayer = function( options )
 35 {
 36 	BaseLayer.prototype.constructor.call( this, options );
 37 	
 38 	// Set style
 39 	if ( options && options['style'] )
 40 		this.style = options['style'];
 41 	else
 42 		this.style = new FeatureStyle();
 43 	
 44 	this.features = [];
 45 }
 46 
 47 /**************************************************************************************************************/
 48 
 49 Utils.inherits( BaseLayer,VectorLayer );
 50 
 51 /**************************************************************************************************************/
 52 
 53 /** 
 54   Attach the vector layer to the globe
 55  */
 56 VectorLayer.prototype._attach = function( g )
 57 {
 58 	BaseLayer.prototype._attach.call( this, g );
 59 	
 60 	// Add the feature to renderers
 61 	for ( var i=0; i < this.features.length; i++ )
 62 	{
 63 		this._addFeatureToRenderers( this.features[i] );
 64 	}
 65 }
 66 
 67 /**************************************************************************************************************/
 68 
 69 /** 
 70   Detach the vector layer from the globe
 71  */
 72 VectorLayer.prototype._detach = function()
 73 {
 74 	// Remove feature from renderers
 75 	for ( var i=0; i < this.features.length; i++ )
 76 	{
 77 		this._removeFeatureFromRenderers( this.features[i] );
 78 	}
 79 	
 80 	BaseLayer.prototype._detach.call(this);
 81 }
 82 
 83 /**************************************************************************************************************/
 84 
 85 /** @export
 86   Adds a feature collection, in GeoJSON format
 87  */
 88 VectorLayer.prototype.addFeatureCollection = function( featureCollection )
 89 {
 90 	// Note : use property defined as ['']  to avoid renaming when compiled in advanced mode with the closure compiler
 91 	var features = featureCollection['features'];
 92 	if ( features )
 93 	{
 94 		for ( var i = 0; i < features.length; i++)
 95 		{
 96 			this.addFeature( features[i] );
 97 		}
 98 	}
 99 }
100 
101 /**************************************************************************************************************/
102 
103 /** @export
104   Removes a feature collection, in GeoJSON format
105 */
106 VectorLayer.prototype.removeFeatureCollection = function( featureCollection )
107 {
108 	// Note : use property defined as ['']  to avoid renaming when compiled in advanced mode with the closure compiler
109 	var features = featureCollection['features'];
110 	if ( features )
111 	{
112 		for ( var i = 0; i < features.length; i++)
113 		{
114 			this.removeFeature( features[i] );
115 		}
116 	}
117 }
118 
119 /**************************************************************************************************************/
120 
121 /** 
122   Add a feature to renderers
123 */
124 VectorLayer.prototype._addFeatureToRenderers = function( feature )
125 {
126 	var geometry = feature['geometry']
127 	
128 	// Manage style, if undefined try with properties, otherwise use defaultStyle
129 	var style = this.style;
130 	var props = feature['properties'];
131 	if ( props && props['style'] )
132 	{
133 		style = props['style'];
134 	}
135 
136 	// Manage geometry collection
137 	if ( geometry.type == "GeometryCollection" )
138 	{
139 		var geoms = geometry["geometries"];
140 		for ( var i = 0; i < geoms.length; i++ )
141 		{
142 			this.globe.vectorRendererManager.addGeometry( geoms[i], this, style );
143 		}
144 	}
145 	else
146 	{
147 		// Add geometry to renderers
148 		this.globe.vectorRendererManager.addGeometry( geometry, this, style );
149 	}
150 }
151 
152 /**************************************************************************************************************/
153 
154 /** 
155   Remove a feature from renderers
156 */
157 VectorLayer.prototype._removeFeatureFromRenderers = function( feature )
158 {
159 	var geometry = feature['geometry']
160 	
161 	// Manage geometry collection
162 	if ( geometry.type == "GeometryCollection" )
163 	{
164 		var geoms = geometry["geometries"];
165 		for ( var i = 0; i < geoms.length; i++ )
166 		{
167 			this.globe.vectorRendererManager.removeGeometry( geoms[i], this );
168 		}
169 	}
170 	else
171 	{
172 		this.globe.vectorRendererManager.removeGeometry( geometry, this );
173 	}
174 }
175 
176 /**************************************************************************************************************/
177 
178 /** @export
179   Add a feature to the layer
180 */
181 VectorLayer.prototype.addFeature = function( feature )
182 {
183 	// Check feature geometry : only add valid feature
184 	var geometry = feature['geometry'];
185 	if ( !geometry || !geometry.type )
186 		return;
187 	this.features.push( feature );
188 	
189 	// Add features to renderer if layer is attached to globe
190 	if ( this.globe )
191 	{			
192 		this._addFeatureToRenderers(feature);
193 		if (this._visible) this.globe.renderContext.requestFrame();
194 	}
195 }
196 
197 /**************************************************************************************************************/
198 
199 /** @export
200   Remove a feature from the layer
201 */
202 VectorLayer.prototype.removeFeature = function( feature )
203 {
204 	var index = this.features.indexOf( feature );
205 	this.features.splice( index, 1 );
206 	if ( this.globe )
207 	{
208 		this._removeFeatureFromRenderers( feature );
209 		if (this._visible) this.globe.renderContext.requestFrame();
210 	}
211 }
212 
213 /**************************************************************************************************************/
214 
215 /** @export
216   Remove all feature from the layer
217 */
218 VectorLayer.prototype.removeAllFeatures = function()
219 {
220 	// Remove feature from renderers
221 	if ( this.globe )
222 	{
223 		for ( var i = 0; i < this.features.length; i++ )
224 		{
225 			this._removeFeatureFromRenderers( feature );
226 		}
227 	}
228 	this.features.length = 0;
229 	
230 	// Refresh rendering if needed
231 	if ( this.globe && this._visible )
232 	{
233 		this.globe.renderContext.requestFrame();
234 	}
235 }
236 
237 /**************************************************************************************************************/
238 
239 /** @export
240   Modify feature style
241 */
242 VectorLayer.prototype.modifyFeatureStyle = function( feature, style )
243 {
244 	this._removeFeatureFromRenderers( feature );
245 	feature['properties']['style'] = style;
246 	this._addFeatureToRenderers( feature );
247 }
248 
249 /**************************************************************************************************************/
250 
251 /** @export
252   Modify the vector layer style
253 */
254 VectorLayer.prototype.modifyStyle = function(style)
255 {
256 	for ( var i=0; i<this.features.length; i++ )
257 	{
258 		this._removeFeatureFromRenderers( this.features[i] );
259 	}
260 	
261 	this.style = style;
262 	
263 	for ( var i=0; i<this.features.length; i++ )
264 	{
265 		this._addFeatureToRenderers( this.features[i] );
266 	}
267 }
268 
269 return VectorLayer;
270 
271 });
272 
273