Project

General

Profile

1
/*
2
Author:       Andreas Hocevar andreas.hocevarATgmail.com
3
License:      LGPL as per: http://www.gnu.org/copyleft/lesser.html
4

    
5
$Id: GmlRendererOL.js 3962 2008-04-01 13:21:42Z ahocevar $
6
*/
7

    
8
// Ensure this object's dependancies are loaded.
9
mapbuilder.loadScript(baseDir+"/widget/GmlRendererBase.js");
10

    
11
/**
12
 * Render GML into HTML.
13
 * this.targetModel references the context model for the map
14
 * where the content of this widget should be rendered to.
15
 * If the model doc is not wfs compliant, a stylesheet
16
 * property has to be set for this widget. The xsl file
17
 * referenced in this property transforms the model doc to
18
 * a wfs FeatureCollection.
19
 * @constructor
20
 * @base GmlRendererBase
21
 * @param widgetNode  The widget's XML object node from the configuration document.
22
 * @param model       The model object that this widget belongs to.
23
 */
24
function GmlRendererOL(widgetNode, model) {
25
  GmlRendererBase.apply(this,new Array(widgetNode, model));
26
  
27
  // create modified OpenLayers GML layer class, which
28
  // uses a gml doc directly instead of loading it from
29
  // an URL
30
  var OlLayer = OpenLayers.Class(OpenLayers.Layer.GML, {
31
  
32
    loadGML: function() {
33
      if (!this.loaded) {
34
        var gml = new OpenLayers.Format.GML();
35
        try {
36
          this.proj = this.projection;
37
          this.addFeatures(gml.read(this.mbWidget.renderDoc));
38
          this.loaded = true;
39
        } catch (e) {
40
          alert(mbGetMessage("documentParseError"),
41
              new XMLSerializer().serializeToString(this.mbWidget.renderDoc));
42
        }
43
      }
44
    },
45
    
46
    // let the layer always be visible, independent of the resolution
47
    calculateInRange: function() {
48
      return true;
49
    },
50
    
51
    // make destroyFeatures bullet-proof to work with undefined geometries
52
    destroyFeatures: function() {
53
      var features = this.features;
54
      var featuresToRemove = [];
55
      var feature;
56
      for (var i=0; i<features.length; i++) {
57
        feature = features[i];
58
        feature.mbWidgetConfig = null;
59
        if (!feature.geometry) {
60
          featuresToRemove.push(feature);
61
        }
62
      }
63
      this.removeFeatures(featuresToRemove);
64
      for (var i=0; i<featuresToRemove.length; i++) {
65
        featuresToRemove[i].destroy();
66
      }
67
      OpenLayers.Layer.GML.prototype.destroyFeatures.apply(this, arguments);
68
    },
69
  
70
    preFeatureInsert: function(feature) {
71
      if (feature.geometry) {
72
        // check if there is a source model linked with this feature
73
        var sourceNode = this.mbWidget.model.doc.selectSingleNode("//*[@fid='"+feature.fid+"']");
74
        var sourceModel = null;
75
        if (sourceNode) {
76
          sourceModel = sourceNode.getAttribute('sourceModel');
77
        }
78
        // if so, use the config from the source model
79
        var widgetConfig = null;
80
        if (sourceModel && config.objects[sourceModel].config && config.objects[sourceModel].config[this.mbWidget.id]) {
81
          widgetConfig = config.objects[sourceModel].config[this.mbWidget.id];
82
        } else {
83
          widgetConfig = this.mbWidget.config;
84
        }
85
        feature.mbWidgetConfig = widgetConfig;
86
        if (!widgetConfig.sourceSRS) {
87
          if (widgetConfig.featureSRS) {
88
            widgetConfig.sourceSRS = new OpenLayers.Projection(widgetConfig.featureSRS);
89
          } else {
90
            widgetConfig.sourceSRS = null;
91
          }
92
        }
93
        //in the future this will be handled internally to OpenLayers
94
        if (widgetConfig.sourceSRS) {
95
          this.convertPoints(feature.geometry, widgetConfig.sourceSRS);
96
        }  
97
      }
98
    },
99
    
100
    drawFeature: function(feature, style) {
101
      // set styles before rendering the feature
102
      var widgetConfig = feature.mbWidgetConfig;
103
      if (widgetConfig) {
104
        feature.style = null;
105
        if (widgetConfig.defaultStyle && style != "select") {
106
          feature.style = widgetConfig.defaultStyle.createSymbolizer ?
107
              widgetConfig.defaultStyle.createSymbolizer(feature) :
108
              widgetConfig.defaultStyle;
109
        }
110
        // set select styles
111
        if (widgetConfig && widgetConfig.selectStyle) {
112
          feature.mbSelectStyle = widgetConfig.selectStyle;
113
        }
114
      }
115
      OpenLayers.Layer.GML.prototype.drawFeature.apply(this, arguments);
116
    },
117
    
118
    convertPoints: function(component, sourceSRS) {
119
      if (component.CLASS_NAME == 'OpenLayers.Geometry.Point') {
120
        component.transform(sourceSRS, this.proj);
121
      } else {
122
        for (var i=0; i<component.components.length; ++i) {
123
          this.convertPoints(component.components[i], sourceSRS);
124
        }
125
      }
126
    },
127
    
128
    /**
129
     * gets a feature from the gmlRendererLayer by GML feature id.
130
     * @param fid GML feature id of the feature
131
     * @return feature OpenLayers feature matching fid
132
     */
133
    getFeatureByFid: function(fid) {
134
      if (!this.features) {
135
        return null;
136
      }
137
      for (var i = 0; i < this.features.length; ++i) {
138
        if (this.features[i].fid == fid) {
139
          return this.features[i];
140
        }
141
      }
142
    },
143
    
144
    destroy: function() {
145
      this.mbWidget = null;
146
      OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments);
147
    }
148
  });
149

    
150
  /** OpenLayers GML layer which renders the model doc */
151
  this.olLayer = null;
152
  
153
  /**
154
   * Style object for default renderer styling of features.
155
   * This holds one style for each OpenLayers feature class
156
   */
157
  this.defaultStyle = null;
158

    
159
  /**
160
   * Style object for default renderer styling of features.
161
   * This holds one style for each OpenLayers feature class
162
   */
163
  this.selectStyle = null;
164
    
165
  /**
166
   * Features that shall not be drawn
167
   */
168
  this.hiddenFeatures = new Array();
169
  
170
  // replacement for deprecated MapContainerBase
171
  this.containerNodeId = this.htmlTagId;
172
  model.containerModel = this.targetModel;
173
  
174
  // Set this.stylesheet. This is taken from WidgetBaseXSL.js
175
  if ( !this.stylesheet ) {
176
    var styleNode = widgetNode.selectSingleNode("mb:stylesheet");
177
    if (styleNode) {
178
      this.stylesheet = new XslProcessor(getNodeValue(styleNode), model.namespace);
179
      this.stylesheet.setParameter("proxyUrl", config.proxyUrl);
180
    }
181
  }
182

    
183
  // set the hover cursor.
184
  this.hoverCursor = this.getProperty('mb:hoverCursor', 'pointer');
185

    
186
  this.paint = function(objRef) {
187
    if (objRef.targetModel.map) {
188
      // remove features from layer
189
      if (objRef.olLayer) {
190
        objRef.model.setParam('gmlRendererLayer', null);
191
      }
192
      // transform the model using the xsl stylesheet if there is one,
193
      // otherwise just take the model doc.
194
      objRef.renderDoc = objRef.stylesheet ? objRef.stylesheet.transformNodeToObject(objRef.model.doc) : objRef.model.doc;
195
      // nothing to do here if there is no model doc
196
      if (!objRef.renderDoc) {
197
        return;
198
      }
199

    
200
      // keep a reference to the map we created the layer for
201
      objRef.map = objRef.targetModel.map;
202
      
203
      // add own model to array of configurations
204
      var models = [objRef.model];
205
      // get configurations from source models, if any
206
      if (objRef.model.mergeModels) {
207
        for (var i=0; i<objRef.model.mergeModels.length; i++) {
208
          models.push(objRef.model.mergeModels[i]);
209
        }
210
      }
211
      // store configurations for each source model
212
      for (var i = 0; i < models.length; i++) {
213
        var widgetConfig = config.objects[models[i].id].config ? config.objects[models[i].id].config[objRef.id] : null;
214
        if (!widgetConfig) {
215
          widgetConfig = objRef.config;
216
        }
217
        if (widgetConfig.sldModelNode) {
218
          var sldModel = config.objects[getNodeValue(widgetConfig.sldModelNode)];
219
          if (sldModel) {
220
            sldModel.addListener("loadModel", objRef.paint, objRef);
221
            if (!sldModel.doc) {
222
              return;
223
            }
224
            var sldNode = sldModel.getSldNode();
225
            if (sldModel.sld) {
226
              var namedLayer = sldModel.sld.namedLayers[objRef.id].userStyles;
227
              for (var j=0; j<namedLayer.length; ++j) {
228
              	namedLayer[j].propertyStyles = namedLayer[j].findPropertyStyles();
229
              	if (namedLayer[j].name == widgetConfig.defaultStyleName) {
230
              	  widgetConfig.defaultStyle = namedLayer[j];
231
              	}
232
              	if (namedLayer[j].name == widgetConfig.selectStyleName) {
233
              	  widgetConfig.selectStyle = namedLayer[j];
234
              	}
235
              }
236
              if (widgetConfig.selectStyle) {
237
                widgetConfig.selectStyle.defaultStyle.cursor = objRef.hoverCursor;
238
              }
239
            } else if (sldNode) {
240
              widgetConfig.defaultStyle =
241
                  sld2OlStyle(sldNode.selectSingleNode("//*[wmc:Name='"+widgetConfig.defaultStyleName+"']"));
242
              widgetConfig.selectStyle =
243
                  sld2OlStyle(sldNode.selectSingleNode("//*[wmc:Name='"+widgetConfig.selectStyleName+"']"));
244
              if (widgetConfig.selectStyle) {
245
                widgetConfig.selectStyle.cursor = objRef.hoverCursor;
246
              }
247
            }
248
          }
249
        }
250
      }
251
      
252
      if (!objRef.olLayer || !objRef.olLayer.mbWidget) {
253
        objRef.olLayer = new OlLayer(objRef.id, null, {mbWidget: objRef});
254
        objRef.targetModel.map.addLayer(objRef.olLayer);
255
      } else {
256
        objRef.olLayer.loaded = false;
257
        objRef.olLayer.destroyFeatures();
258
        objRef.olLayer.loadGML();
259
      }
260
      objRef.removeHiddenFeatures(objRef);
261
      
262
      objRef.model.setParam('gmlRendererLayer', objRef.olLayer);
263
    }
264
    // We add a refresh listener to the targetModel. This way we
265
    // can be sure that the gml renderer is reloaded when the
266
    // map is refreshed, and also if the map did not exist yet
267
    // when paint was called for the first time.
268
    objRef.targetModel.addListener('refresh', objRef.paint, objRef);
269
  }
270
  this.model.addListener("refresh",this.paint, this);
271
  
272
  /**
273
   * Called when the context's hidden attribute changes.
274
   * @param objRef This object.
275
   * @param layerName  The name of the layer that was toggled.
276
   */
277
  this.hiddenListener=function(objRef, layerName){
278
    //TBD not yet implemented
279
    alert('hide/unhide '+layerName);
280
  }
281
  this.model.addListener("hidden",this.hiddenListener,this);
282
  
283
  /**
284
   * Hides the feature specified by its fid from the map
285
   * @param objRef this widget
286
   * @param fid feature id of the feature to hide. If it is null,
287
   * the hideFeature param of the model will be used.
288
   */
289
  this.hideFeature = function(objRef, fid) {
290
    if (!fid) {
291
      fid = objRef.model.getParam('hideFeature');
292
    }
293
    var feature = objRef.olLayer.getFeatureByFid(fid);
294
    if (feature) {
295
      objRef.hiddenFeatures.push(fid);
296
      // mark the feature as hidden - this will be checked by other widgets
297
      feature.mbHidden = true;
298
      objRef.olLayer.renderer.eraseGeometry(feature.geometry);      
299
    }
300
  }
301
  this.model.addListener("hideFeature", this.hideFeature, this);
302
  
303
  /**
304
   * Shows the feature specified by its fid in the map
305
   * @param objRef this widget
306
   * @param fid feature id of the feature to show. If it is null,
307
   * the showFeature param of the model will be used.
308
   */
309
  this.showFeature = function(objRef, fid) {
310
    if (!fid) {
311
      fid = objRef.model.getParam('showFeature');
312
    }
313
    var feature = objRef.olLayer.getFeatureByFid(fid);
314
    if (feature) {
315
      OpenLayers.Util.removeItem(objRef.hiddenFeatures, fid);
316
      // mark the feature as visible - this will be checked by other widgets
317
      feature.mbHidden = false;
318
      objRef.olLayer.drawFeature(feature);
319
    }
320
  }
321
  this.model.addListener("showFeature", this.showFeature, this);
322
  
323
  this.removeHiddenFeatures = function(objRef) {
324
    if (objRef.olLayer) {
325
      // remove hidden features
326
      var hiddenFeatures = objRef.hiddenFeatures.toString().split(/,/);
327
      objRef.hiddenFeatures = new Array();
328
      for (var i=0; i<hiddenFeatures.length; i++) {
329
        if (hiddenFeatures[i]) {
330
          objRef.hideFeature(objRef, hiddenFeatures[i]);
331
        }
332
      }
333
    }
334
  }
335
  
336
  
337
  /**
338
   * Initializes this widget
339
   * @param objRef This object
340
   */
341
  this.init = function(objRef) {
342
    var clickWidgetNode =  widgetNode.selectSingleNode("mb:featureOnClick");
343
    if (clickWidgetNode) {
344
      var clickWidget = config.objects[getNodeValue(clickWidgetNode)];
345
      objRef.model.addListener("olFeatureSelect", clickWidget.onClick, clickWidget);
346
    }
347
    var hoverWidgetNode =  widgetNode.selectSingleNode("mb:featureOnHover");
348
    if (hoverWidgetNode) {
349
      var hoverWidget = config.objects[getNodeValue(hoverWidgetNode)];
350
      objRef.model.addListener("olFeatureHover", hoverWidget.onMouseover, hoverWidget);
351
      objRef.model.addListener("olFeatureOut", hoverWidget.onMouseout, hoverWidget);
352
    }
353
    objRef.targetModel.addListener("aoi", objRef.removeHiddenFeatures, objRef);
354
  }
355
  this.model.addListener("init", this.init, this);
356
  
357
  this.model.removeListener("newModel", this.clearWidget, this);
358
  this.clearWidget = function(objRef) {
359
    if (objRef.olLayer) {
360
      objRef.olLayer.loaded = false;
361
      for (var i=0; i<objRef.olLayer.map.controls.length; i++) {
362
        if (objRef.olLayer.map.controls[i].layer == objRef.olLayer) {
363
          objRef.olLayer.map.controls[i].destroy();
364
        }
365
      }
366
      objRef.olLayer.destroy();
367
      objRef.olLayer = null;
368
    }
369
  }
370
  this.model.addListener("newModel", this.clearWidget, this);
371
}
(49-49/145)