| | 219 | /** |
|---|
| | 220 | * APIMethod: write |
|---|
| | 221 | * Accept Feature Collection, and return a string. |
|---|
| | 222 | * |
|---|
| | 223 | * Parameters: |
|---|
| | 224 | * features - An array of <OpenLayers.Feature.Vector> features. |
|---|
| | 225 | */ |
|---|
| | 226 | write: function(features) { |
|---|
| | 227 | var kml = this.createElementNS(this.kmlns, "kml"); |
|---|
| | 228 | var folder = this.createFolderXML(); |
|---|
| | 229 | for (var i=0; i < features.length; i++) { |
|---|
| | 230 | folder.appendChild(this.createPlacemarkXML(features[i])); |
|---|
| | 231 | } |
|---|
| | 232 | kml.appendChild(folder); |
|---|
| | 233 | return (new OpenLayers.Format.XML).write(kml); |
|---|
| | 234 | }, |
|---|
| | 235 | |
|---|
| | 236 | /** |
|---|
| | 237 | * Method: createFolderXML |
|---|
| | 238 | * Creates and returns a KML folder node |
|---|
| | 239 | * |
|---|
| | 240 | * Returns: |
|---|
| | 241 | * {<XMLNode>} |
|---|
| | 242 | */ |
|---|
| | 243 | createFolderXML: function() { |
|---|
| | 244 | // Folder name |
|---|
| | 245 | var folderName = this.createElementNS(this.kmlns, "name"); |
|---|
| | 246 | var folderNameText = this.createTextNode(this.foldersName); |
|---|
| | 247 | folderName.appendChild(folderNameText); |
|---|
| | 248 | |
|---|
| | 249 | // Folder description |
|---|
| | 250 | var folderDesc = this.createElementNS(this.kmlns, "description"); |
|---|
| | 251 | var folderDescText = this.createTextNode(this.foldersDesc); |
|---|
| | 252 | folderDesc.appendChild(folderDescText); |
|---|
| | 253 | |
|---|
| | 254 | // Folder |
|---|
| | 255 | var folder = this.createElementNS(this.kmlns, "Folder"); |
|---|
| | 256 | folder.appendChild(folderName); |
|---|
| | 257 | folder.appendChild(folderDesc); |
|---|
| | 258 | |
|---|
| | 259 | return folder; |
|---|
| | 260 | }, |
|---|
| | 261 | |
|---|
| | 262 | /** |
|---|
| | 263 | * Method: createPlacemarkXML |
|---|
| | 264 | * Creates and returns a KML placemark node representing the |
|---|
| | 265 | * given feature. |
|---|
| | 266 | * |
|---|
| | 267 | * Parameters: |
|---|
| | 268 | * feature - {<OpenLayers.Feature.Vector>} |
|---|
| | 269 | * |
|---|
| | 270 | * Returns: |
|---|
| | 271 | * {<XMLNode>} |
|---|
| | 272 | */ |
|---|
| | 273 | createPlacemarkXML: function(feature) { |
|---|
| | 274 | // Placemark name |
|---|
| | 275 | var placemarkName = this.createElementNS(this.kmlns, "name"); |
|---|
| | 276 | var placemarkNameText = this.createTextNode(feature.id); |
|---|
| | 277 | placemarkName.appendChild(placemarkNameText); |
|---|
| | 278 | |
|---|
| | 279 | // Placemark description |
|---|
| | 280 | var placemarkDesc = this.createElementNS(this.kmlns, "description"); |
|---|
| | 281 | var placemarkDescText = this.createTextNode(this.placemarksDesc); |
|---|
| | 282 | placemarkDesc.appendChild(placemarkDescText); |
|---|
| | 283 | |
|---|
| | 284 | // Placemark |
|---|
| | 285 | var placemarkNode = this.createElementNS(this.kmlns, "Placemark"); |
|---|
| | 286 | placemarkNode.appendChild(placemarkName); |
|---|
| | 287 | placemarkNode.appendChild(placemarkDesc); |
|---|
| | 288 | |
|---|
| | 289 | // Geometry node (Point, LineString, etc. nodes) |
|---|
| | 290 | var geometryNode = this.buildGeometryNode(feature.geometry); |
|---|
| | 291 | placemarkNode.appendChild(geometryNode); |
|---|
| | 292 | |
|---|
| | 293 | return placemarkNode; |
|---|
| | 294 | }, |
|---|
| | 295 | |
|---|
| | 296 | /** |
|---|
| | 297 | * Method: buildGeometryNode |
|---|
| | 298 | * Builds and returns a KML geometry node with the given geometry |
|---|
| | 299 | * |
|---|
| | 300 | * Parameters: |
|---|
| | 301 | * geometry - {<OpenLayers.Geometry>} |
|---|
| | 302 | * |
|---|
| | 303 | * Return: |
|---|
| | 304 | * {<XMLNode>} |
|---|
| | 305 | */ |
|---|
| | 306 | buildGeometryNode: function(geometry) { |
|---|
| | 307 | // TBD test if geoserver can be given a Multi-geometry for a simple-geometry data store |
|---|
| | 308 | // ie if multipolygon can be sent for a polygon feature type |
|---|
| | 309 | var kml = ""; |
|---|
| | 310 | // match MultiPolygon or Polygon |
|---|
| | 311 | if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon" |
|---|
| | 312 | || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") { |
|---|
| | 313 | kml = this.createElementNS(this.kmlns, 'Polygon'); |
|---|
| | 314 | |
|---|
| | 315 | var outerRing = this.createElementNS(this.kmlns, 'outerBoundaryIs'); |
|---|
| | 316 | var linearRing = this.createElementNS(this.kmlns, 'LinearRing'); |
|---|
| | 317 | |
|---|
| | 318 | // TBD manage polygons with holes |
|---|
| | 319 | linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0])); |
|---|
| | 320 | outerRing.appendChild(linearRing); |
|---|
| | 321 | |
|---|
| | 322 | kml.appendChild(outerRing); |
|---|
| | 323 | } |
|---|
| | 324 | // match MultiLineString or LineString |
|---|
| | 325 | else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString" |
|---|
| | 326 | || geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") { |
|---|
| | 327 | kml = this.createElementNS(this.kmlns, 'LineString'); |
|---|
| | 328 | |
|---|
| | 329 | kml.appendChild(this.buildCoordinatesNode(geometry)); |
|---|
| | 330 | } |
|---|
| | 331 | // match MultiPoint or Point |
|---|
| | 332 | else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" || |
|---|
| | 333 | geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") { |
|---|
| | 334 | kml = this.createElementNS(this.kmlns, 'Point'); |
|---|
| | 335 | |
|---|
| | 336 | // FIXME: There should be only one Point node per Placemark node |
|---|
| | 337 | var parts = ""; |
|---|
| | 338 | if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") { |
|---|
| | 339 | parts = geometry.components; |
|---|
| | 340 | } else { |
|---|
| | 341 | parts = [geometry]; |
|---|
| | 342 | } |
|---|
| | 343 | |
|---|
| | 344 | for (var i = 0; i < parts.length; i++) { |
|---|
| | 345 | kml.appendChild(this.buildCoordinatesNode(parts[i])); |
|---|
| | 346 | } |
|---|
| | 347 | } |
|---|
| | 348 | return kml; |
|---|
| | 349 | }, |
|---|
| | 350 | |
|---|
| | 351 | /** |
|---|
| | 352 | * Method: buildGeometryNode |
|---|
| | 353 | * Builds and returns the KML coordinates node with the given geometry |
|---|
| | 354 | * <coordinates>...</coordinates> |
|---|
| | 355 | * |
|---|
| | 356 | * Parameters: |
|---|
| | 357 | * geometry - {<OpenLayers.Geometry>} |
|---|
| | 358 | * |
|---|
| | 359 | * Return: |
|---|
| | 360 | * {<XMLNode>} |
|---|
| | 361 | */ |
|---|
| | 362 | buildCoordinatesNode: function(geometry) { |
|---|
| | 363 | var coordinatesNode = this.createElementNS(this.kmlns, "coordinates"); |
|---|
| | 364 | |
|---|
| | 365 | var points = null; |
|---|
| | 366 | if (geometry.components) { |
|---|
| | 367 | points = geometry.components; |
|---|
| | 368 | } |
|---|
| | 369 | |
|---|
| | 370 | var path = ""; |
|---|
| | 371 | if (points) { |
|---|
| | 372 | for (var i = 0; i < points.length; i++) { |
|---|
| | 373 | path += points[i].x + "," + points[i].y + " "; |
|---|
| | 374 | } |
|---|
| | 375 | } else { |
|---|
| | 376 | path += geometry.x + "," + geometry.y + " "; |
|---|
| | 377 | } |
|---|
| | 378 | |
|---|
| | 379 | var txtNode = this.createTextNode(path); |
|---|
| | 380 | coordinatesNode.appendChild(txtNode); |
|---|
| | 381 | |
|---|
| | 382 | return coordinatesNode; |
|---|
| | 383 | }, |
|---|
| | 384 | |
|---|
| | 385 | /** @final @type String */ |
|---|