[76] | 1 | /* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
---|
| 2 | * full list of contributors). Published under the Clear BSD license. |
---|
| 3 | * See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
---|
| 4 | * full text of the license. */ |
---|
| 5 | |
---|
| 6 | /** |
---|
| 7 | * @requires OpenLayers/Format/XML.js |
---|
| 8 | * @requires OpenLayers/Format/GML/v3.js |
---|
| 9 | * @requires OpenLayers/Feature/Vector.js |
---|
| 10 | */ |
---|
| 11 | |
---|
| 12 | /** |
---|
| 13 | * Class: OpenLayers.Format.Atom |
---|
| 14 | * Read/write Atom feeds. Create a new instance with the |
---|
| 15 | * <OpenLayers.Format.AtomFeed> constructor. |
---|
| 16 | * |
---|
| 17 | * Inherits from: |
---|
| 18 | * - <OpenLayers.Format.XML> |
---|
| 19 | */ |
---|
| 20 | OpenLayers.Format.Atom = OpenLayers.Class(OpenLayers.Format.XML, { |
---|
| 21 | |
---|
| 22 | /** |
---|
| 23 | * Property: namespaces |
---|
| 24 | * {Object} Mapping of namespace aliases to namespace URIs. Properties |
---|
| 25 | * of this object should not be set individually. Read-only. All |
---|
| 26 | * XML subclasses should have their own namespaces object. Use |
---|
| 27 | * <setNamespace> to add or set a namespace alias after construction. |
---|
| 28 | */ |
---|
| 29 | namespaces: { |
---|
| 30 | atom: "http://www.w3.org/2005/Atom", |
---|
| 31 | georss: "http://www.georss.org/georss" |
---|
| 32 | }, |
---|
| 33 | |
---|
| 34 | /** |
---|
| 35 | * APIProperty: feedTitle |
---|
| 36 | * {String} Atom feed elements require a title. Default is "untitled". |
---|
| 37 | */ |
---|
| 38 | feedTitle: "untitled", |
---|
| 39 | |
---|
| 40 | /** |
---|
| 41 | * APIProperty: defaultEntryTitle |
---|
| 42 | * {String} Atom entry elements require a title. In cases where one is |
---|
| 43 | * not provided in the feature attributes, this will be used. Default |
---|
| 44 | * is "untitled". |
---|
| 45 | */ |
---|
| 46 | defaultEntryTitle: "untitled", |
---|
| 47 | |
---|
| 48 | /** |
---|
| 49 | * Property: gmlParse |
---|
| 50 | * {Object} GML Format object for parsing features |
---|
| 51 | * Non-API and only created if necessary |
---|
| 52 | */ |
---|
| 53 | gmlParser: null, |
---|
| 54 | |
---|
| 55 | /** |
---|
| 56 | * APIProperty: xy |
---|
| 57 | * {Boolean} Order of the GML coordinate: true:(x,y) or false:(y,x) |
---|
| 58 | * For GeoRSS the default is (y,x), therefore: false |
---|
| 59 | */ |
---|
| 60 | xy: false, |
---|
| 61 | |
---|
| 62 | /** |
---|
| 63 | * Constructor: OpenLayers.Format.AtomEntry |
---|
| 64 | * Create a new parser for Atom. |
---|
| 65 | * |
---|
| 66 | * Parameters: |
---|
| 67 | * options - {Object} An optional object whose properties will be set on |
---|
| 68 | * this instance. |
---|
| 69 | */ |
---|
| 70 | initialize: function(options) { |
---|
| 71 | OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); |
---|
| 72 | }, |
---|
| 73 | |
---|
| 74 | /** |
---|
| 75 | * APIMethod: read |
---|
| 76 | * Return a list of features from an Atom feed or entry document. |
---|
| 77 | |
---|
| 78 | * Parameters: |
---|
| 79 | * doc - {Element} or {String} |
---|
| 80 | * |
---|
| 81 | * Returns: |
---|
| 82 | * An Array of <OpenLayers.Feature.Vector>s |
---|
| 83 | */ |
---|
| 84 | read: function(doc) { |
---|
| 85 | if (typeof doc == "string") { |
---|
| 86 | doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]); |
---|
| 87 | } |
---|
| 88 | return this.parseFeatures(doc); |
---|
| 89 | }, |
---|
| 90 | |
---|
| 91 | /** |
---|
| 92 | * APIMethod: write |
---|
| 93 | * Serialize or more feature nodes to Atom documents. |
---|
| 94 | * |
---|
| 95 | * Parameters: |
---|
| 96 | * features - a single {<OpenLayers.Feature.Vector>} or an |
---|
| 97 | * Array({<OpenLayers.Feature.Vector>}). |
---|
| 98 | * |
---|
| 99 | * Returns: |
---|
| 100 | * {String} an Atom entry document if passed one feature node, or a feed |
---|
| 101 | * document if passed an array of feature nodes. |
---|
| 102 | */ |
---|
| 103 | write: function(features) { |
---|
| 104 | var doc; |
---|
| 105 | if (features instanceof Array) { |
---|
| 106 | doc = this.createElementNSPlus("atom:feed"); |
---|
| 107 | doc.appendChild( |
---|
| 108 | this.createElementNSPlus("atom:title", { |
---|
| 109 | value: this.feedTitle |
---|
| 110 | }) |
---|
| 111 | ); |
---|
| 112 | for (var i=0, ii=features.length; i<ii; i++) { |
---|
| 113 | doc.appendChild(this.buildEntryNode(features[i])); |
---|
| 114 | } |
---|
| 115 | } |
---|
| 116 | else { |
---|
| 117 | doc = this.buildEntryNode(features); |
---|
| 118 | } |
---|
| 119 | return OpenLayers.Format.XML.prototype.write.apply(this, [doc]); |
---|
| 120 | }, |
---|
| 121 | |
---|
| 122 | /** |
---|
| 123 | * Method: buildContentNode |
---|
| 124 | * |
---|
| 125 | * Parameters: |
---|
| 126 | * content - {Object} |
---|
| 127 | * |
---|
| 128 | * Returns: |
---|
| 129 | * {DOMElement} an Atom content node. |
---|
| 130 | * |
---|
| 131 | * TODO: types other than text. |
---|
| 132 | */ |
---|
| 133 | buildContentNode: function(content) { |
---|
| 134 | var node = this.createElementNSPlus("atom:content", { |
---|
| 135 | attributes: { |
---|
| 136 | type: content.type || null |
---|
| 137 | } |
---|
| 138 | }); |
---|
| 139 | if (content.src) { |
---|
| 140 | node.setAttribute("src", content.src); |
---|
| 141 | } else { |
---|
| 142 | if (content.type == "text" || content.type == null) { |
---|
| 143 | node.appendChild( |
---|
| 144 | this.createTextNode(content.value) |
---|
| 145 | ); |
---|
| 146 | } else if (content.type == "html") { |
---|
| 147 | if (typeof content.value != "string") { |
---|
| 148 | throw "HTML content must be in form of an escaped string"; |
---|
| 149 | } |
---|
| 150 | node.appendChild( |
---|
| 151 | this.createTextNode(content.value) |
---|
| 152 | ); |
---|
| 153 | } else if (content.type == "xhtml") { |
---|
| 154 | node.appendChild(content.value); |
---|
| 155 | } else if (content.type == "xhtml" || |
---|
| 156 | content.type.match(/(\+|\/)xml$/)) { |
---|
| 157 | node.appendChild(content.value); |
---|
| 158 | } |
---|
| 159 | else { // MUST be a valid Base64 encoding |
---|
| 160 | node.appendChild( |
---|
| 161 | this.createTextNode(content.value) |
---|
| 162 | ); |
---|
| 163 | } |
---|
| 164 | } |
---|
| 165 | return node; |
---|
| 166 | }, |
---|
| 167 | |
---|
| 168 | /** |
---|
| 169 | * Method: buildEntryNode |
---|
| 170 | * Build an Atom entry node from a feature object. |
---|
| 171 | * |
---|
| 172 | * Parameters: |
---|
| 173 | * feature - {<OpenLayers.Feature.Vector>} |
---|
| 174 | * |
---|
| 175 | * Returns: |
---|
| 176 | * {DOMElement} an Atom entry node. |
---|
| 177 | * |
---|
| 178 | * These entries are geared for publication using AtomPub. |
---|
| 179 | * |
---|
| 180 | * TODO: support extension elements |
---|
| 181 | */ |
---|
| 182 | buildEntryNode: function(feature) { |
---|
| 183 | var attrib = feature.attributes; |
---|
| 184 | var atomAttrib = attrib.atom || {}; |
---|
| 185 | var entryNode = this.createElementNSPlus("atom:entry"); |
---|
| 186 | |
---|
| 187 | // atom:author |
---|
| 188 | if (atomAttrib.authors) { |
---|
| 189 | var authors = atomAttrib.authors instanceof Array ? |
---|
| 190 | atomAttrib.authors : [atomAttrib.authors]; |
---|
| 191 | for (var i=0, ii=authors.length; i<ii; i++) { |
---|
| 192 | entryNode.appendChild( |
---|
| 193 | this.buildPersonConstructNode( |
---|
| 194 | "author", authors[i] |
---|
| 195 | ) |
---|
| 196 | ); |
---|
| 197 | } |
---|
| 198 | } |
---|
| 199 | |
---|
| 200 | // atom:category |
---|
| 201 | if (atomAttrib.categories) { |
---|
| 202 | var categories = atomAttrib.categories instanceof Array ? |
---|
| 203 | atomAttrib.categories : [atomAttrib.categories]; |
---|
| 204 | var category; |
---|
| 205 | for (var i=0, ii=categories.length; i<ii; i++) { |
---|
| 206 | category = categories[i]; |
---|
| 207 | entryNode.appendChild( |
---|
| 208 | this.createElementNSPlus("atom:category", { |
---|
| 209 | attributes: { |
---|
| 210 | term: category.term, |
---|
| 211 | scheme: category.scheme || null, |
---|
| 212 | label: category.label || null |
---|
| 213 | } |
---|
| 214 | }) |
---|
| 215 | ); |
---|
| 216 | } |
---|
| 217 | } |
---|
| 218 | |
---|
| 219 | // atom:content |
---|
| 220 | if (atomAttrib.content) { |
---|
| 221 | entryNode.appendChild(this.buildContentNode(atomAttrib.content)); |
---|
| 222 | } |
---|
| 223 | |
---|
| 224 | // atom:contributor |
---|
| 225 | if (atomAttrib.contributors) { |
---|
| 226 | var contributors = atomAttrib.contributors instanceof Array ? |
---|
| 227 | atomAttrib.contributors : [atomAttrib.contributors]; |
---|
| 228 | for (var i=0, ii=contributors.length; i<ii; i++) { |
---|
| 229 | entryNode.appendChild( |
---|
| 230 | this.buildPersonConstructNode( |
---|
| 231 | "contributor", |
---|
| 232 | contributors[i] |
---|
| 233 | ) |
---|
| 234 | ); |
---|
| 235 | } |
---|
| 236 | } |
---|
| 237 | |
---|
| 238 | // atom:id |
---|
| 239 | if (feature.fid) { |
---|
| 240 | entryNode.appendChild( |
---|
| 241 | this.createElementNSPlus("atom:id", { |
---|
| 242 | value: feature.fid |
---|
| 243 | }) |
---|
| 244 | ); |
---|
| 245 | } |
---|
| 246 | |
---|
| 247 | // atom:link |
---|
| 248 | if (atomAttrib.links) { |
---|
| 249 | var links = atomAttrib.links instanceof Array ? |
---|
| 250 | atomAttrib.links : [atomAttrib.links]; |
---|
| 251 | var link; |
---|
| 252 | for (var i=0, ii=links.length; i<ii; i++) { |
---|
| 253 | link = links[i]; |
---|
| 254 | entryNode.appendChild( |
---|
| 255 | this.createElementNSPlus("atom:link", { |
---|
| 256 | attributes: { |
---|
| 257 | href: link.href, |
---|
| 258 | rel: link.rel || null, |
---|
| 259 | type: link.type || null, |
---|
| 260 | hreflang: link.hreflang || null, |
---|
| 261 | title: link.title || null, |
---|
| 262 | length: link.length || null |
---|
| 263 | } |
---|
| 264 | }) |
---|
| 265 | ); |
---|
| 266 | } |
---|
| 267 | } |
---|
| 268 | |
---|
| 269 | // atom:published |
---|
| 270 | if (atomAttrib.published) { |
---|
| 271 | entryNode.appendChild( |
---|
| 272 | this.createElementNSPlus("atom:published", { |
---|
| 273 | value: atomAttrib.published |
---|
| 274 | }) |
---|
| 275 | ); |
---|
| 276 | } |
---|
| 277 | |
---|
| 278 | // atom:rights |
---|
| 279 | if (atomAttrib.rights) { |
---|
| 280 | entryNode.appendChild( |
---|
| 281 | this.createElementNSPlus("atom:rights", { |
---|
| 282 | value: atomAttrib.rights |
---|
| 283 | }) |
---|
| 284 | ); |
---|
| 285 | } |
---|
| 286 | |
---|
| 287 | // atom:source not implemented |
---|
| 288 | |
---|
| 289 | // atom:summary |
---|
| 290 | if (atomAttrib.summary || attrib.description) { |
---|
| 291 | entryNode.appendChild( |
---|
| 292 | this.createElementNSPlus("atom:summary", { |
---|
| 293 | value: atomAttrib.summary || attrib.description |
---|
| 294 | }) |
---|
| 295 | ); |
---|
| 296 | } |
---|
| 297 | |
---|
| 298 | // atom:title |
---|
| 299 | entryNode.appendChild( |
---|
| 300 | this.createElementNSPlus("atom:title", { |
---|
| 301 | value: atomAttrib.title || attrib.title || this.defaultEntryTitle |
---|
| 302 | }) |
---|
| 303 | ); |
---|
| 304 | |
---|
| 305 | // atom:updated |
---|
| 306 | if (atomAttrib.updated) { |
---|
| 307 | entryNode.appendChild( |
---|
| 308 | this.createElementNSPlus("atom:updated", { |
---|
| 309 | value: atomAttrib.updated |
---|
| 310 | }) |
---|
| 311 | ); |
---|
| 312 | } |
---|
| 313 | |
---|
| 314 | // georss:where |
---|
| 315 | if (feature.geometry) { |
---|
| 316 | var whereNode = this.createElementNSPlus("georss:where"); |
---|
| 317 | whereNode.appendChild( |
---|
| 318 | this.buildGeometryNode(feature.geometry) |
---|
| 319 | ); |
---|
| 320 | entryNode.appendChild(whereNode); |
---|
| 321 | } |
---|
| 322 | |
---|
| 323 | return entryNode; |
---|
| 324 | }, |
---|
| 325 | |
---|
| 326 | /** |
---|
| 327 | * Method: initGmlParser |
---|
| 328 | * Creates a GML parser. |
---|
| 329 | */ |
---|
| 330 | initGmlParser: function() { |
---|
| 331 | this.gmlParser = new OpenLayers.Format.GML.v3({ |
---|
| 332 | xy: this.xy, |
---|
| 333 | featureNS: "http://example.com#feature", |
---|
| 334 | internalProjection: this.internalProjection, |
---|
| 335 | externalProjection: this.externalProjection |
---|
| 336 | }); |
---|
| 337 | }, |
---|
| 338 | |
---|
| 339 | /** |
---|
| 340 | * Method: buildGeometryNode |
---|
| 341 | * builds a GeoRSS node with a given geometry |
---|
| 342 | * |
---|
| 343 | * Parameters: |
---|
| 344 | * geometry - {<OpenLayers.Geometry>} |
---|
| 345 | * |
---|
| 346 | * Returns: |
---|
| 347 | * {DOMElement} A gml node. |
---|
| 348 | */ |
---|
| 349 | buildGeometryNode: function(geometry) { |
---|
| 350 | if (!this.gmlParser) { |
---|
| 351 | this.initGmlParser(); |
---|
| 352 | } |
---|
| 353 | var node = this.gmlParser.writeNode("feature:_geometry", geometry); |
---|
| 354 | return node.firstChild; |
---|
| 355 | }, |
---|
| 356 | |
---|
| 357 | /** |
---|
| 358 | * Method: buildPersonConstructNode |
---|
| 359 | * |
---|
| 360 | * Parameters: |
---|
| 361 | * name - {String} |
---|
| 362 | * value - {Object} |
---|
| 363 | * |
---|
| 364 | * Returns: |
---|
| 365 | * {DOMElement} an Atom person construct node. |
---|
| 366 | * |
---|
| 367 | * Example: |
---|
| 368 | * >>> buildPersonConstructNode("author", {name: "John Smith"}) |
---|
| 369 | * {<author><name>John Smith</name></author>} |
---|
| 370 | * |
---|
| 371 | * TODO: how to specify extension elements? Add to the oNames array? |
---|
| 372 | */ |
---|
| 373 | buildPersonConstructNode: function(name, value) { |
---|
| 374 | var oNames = ["uri", "email"]; |
---|
| 375 | var personNode = this.createElementNSPlus("atom:" + name); |
---|
| 376 | personNode.appendChild( |
---|
| 377 | this.createElementNSPlus("atom:name", { |
---|
| 378 | value: value.name |
---|
| 379 | }) |
---|
| 380 | ); |
---|
| 381 | for (var i=0, ii=oNames.length; i<ii; i++) { |
---|
| 382 | if (value[oNames[i]]) { |
---|
| 383 | personNode.appendChild( |
---|
| 384 | this.createElementNSPlus("atom:" + oNames[i], { |
---|
| 385 | value: value[oNames[i]] |
---|
| 386 | }) |
---|
| 387 | ); |
---|
| 388 | } |
---|
| 389 | } |
---|
| 390 | return personNode; |
---|
| 391 | }, |
---|
| 392 | |
---|
| 393 | /** |
---|
| 394 | * Method: getFirstChildValue |
---|
| 395 | * |
---|
| 396 | * Parameters: |
---|
| 397 | * node - {DOMElement} |
---|
| 398 | * nsuri - {String} Child node namespace uri ("*" for any). |
---|
| 399 | * name - {String} Child node name. |
---|
| 400 | * def - {String} Optional string default to return if no child found. |
---|
| 401 | * |
---|
| 402 | * Returns: |
---|
| 403 | * {String} The value of the first child with the given tag name. Returns |
---|
| 404 | * default value or empty string if none found. |
---|
| 405 | */ |
---|
| 406 | getFirstChildValue: function(node, nsuri, name, def) { |
---|
| 407 | var value; |
---|
| 408 | var nodes = this.getElementsByTagNameNS(node, nsuri, name); |
---|
| 409 | if (nodes && nodes.length > 0) { |
---|
| 410 | value = this.getChildValue(nodes[0], def); |
---|
| 411 | } else { |
---|
| 412 | value = def; |
---|
| 413 | } |
---|
| 414 | return value; |
---|
| 415 | }, |
---|
| 416 | |
---|
| 417 | /** |
---|
| 418 | * Method: parseFeature |
---|
| 419 | * Parse feature from an Atom entry node.. |
---|
| 420 | * |
---|
| 421 | * Parameters: |
---|
| 422 | * node - {DOMElement} An Atom entry or feed node. |
---|
| 423 | * |
---|
| 424 | * Returns: |
---|
| 425 | * An <OpenLayers.Feature.Vector>. |
---|
| 426 | */ |
---|
| 427 | parseFeature: function(node) { |
---|
| 428 | var atomAttrib = {}; |
---|
| 429 | var value = null; |
---|
| 430 | var nodes = null; |
---|
| 431 | var attval = null; |
---|
| 432 | var atomns = this.namespaces.atom; |
---|
| 433 | |
---|
| 434 | // atomAuthor* |
---|
| 435 | this.parsePersonConstructs(node, "author", atomAttrib); |
---|
| 436 | |
---|
| 437 | // atomCategory* |
---|
| 438 | nodes = this.getElementsByTagNameNS(node, atomns, "category"); |
---|
| 439 | if (nodes.length > 0) { |
---|
| 440 | atomAttrib.categories = []; |
---|
| 441 | } |
---|
| 442 | for (var i=0, ii=nodes.length; i<ii; i++) { |
---|
| 443 | value = {}; |
---|
| 444 | value.term = nodes[i].getAttribute("term"); |
---|
| 445 | attval = nodes[i].getAttribute("scheme"); |
---|
| 446 | if (attval) { value.scheme = attval; } |
---|
| 447 | attval = nodes[i].getAttribute("label"); |
---|
| 448 | if (attval) { value.label = attval; } |
---|
| 449 | atomAttrib.categories.push(value); |
---|
| 450 | } |
---|
| 451 | |
---|
| 452 | // atomContent? |
---|
| 453 | nodes = this.getElementsByTagNameNS(node, atomns, "content"); |
---|
| 454 | if (nodes.length > 0) { |
---|
| 455 | value = {}; |
---|
| 456 | attval = nodes[0].getAttribute("type"); |
---|
| 457 | if (attval) { |
---|
| 458 | value.type = attval; |
---|
| 459 | } |
---|
| 460 | attval = nodes[0].getAttribute("src"); |
---|
| 461 | if (attval) { |
---|
| 462 | value.src = attval; |
---|
| 463 | } else { |
---|
| 464 | if (value.type == "text" || |
---|
| 465 | value.type == "html" || |
---|
| 466 | value.type == null ) { |
---|
| 467 | value.value = this.getFirstChildValue( |
---|
| 468 | node, |
---|
| 469 | atomns, |
---|
| 470 | "content", |
---|
| 471 | null |
---|
| 472 | ); |
---|
| 473 | } else if (value.type == "xhtml" || |
---|
| 474 | value.type.match(/(\+|\/)xml$/)) { |
---|
| 475 | value.value = this.getChildEl(nodes[0]); |
---|
| 476 | } else { // MUST be base64 encoded |
---|
| 477 | value.value = this.getFirstChildValue( |
---|
| 478 | node, |
---|
| 479 | atomns, |
---|
| 480 | "content", |
---|
| 481 | null |
---|
| 482 | ); |
---|
| 483 | } |
---|
| 484 | atomAttrib.content = value; |
---|
| 485 | } |
---|
| 486 | } |
---|
| 487 | |
---|
| 488 | // atomContributor* |
---|
| 489 | this.parsePersonConstructs(node, "contributor", atomAttrib); |
---|
| 490 | |
---|
| 491 | // atomId |
---|
| 492 | atomAttrib.id = this.getFirstChildValue(node, atomns, "id", null); |
---|
| 493 | |
---|
| 494 | // atomLink* |
---|
| 495 | nodes = this.getElementsByTagNameNS(node, atomns, "link"); |
---|
| 496 | if (nodes.length > 0) { |
---|
| 497 | atomAttrib.links = new Array(nodes.length); |
---|
| 498 | } |
---|
| 499 | var oAtts = ["rel", "type", "hreflang", "title", "length"]; |
---|
| 500 | for (var i=0, ii=nodes.length; i<ii; i++) { |
---|
| 501 | value = {}; |
---|
| 502 | value.href = nodes[i].getAttribute("href"); |
---|
| 503 | for (var j=0, jj=oAtts.length; j<jj; j++) { |
---|
| 504 | attval = nodes[i].getAttribute(oAtts[j]); |
---|
| 505 | if (attval) { |
---|
| 506 | value[oAtts[j]] = attval; |
---|
| 507 | } |
---|
| 508 | } |
---|
| 509 | atomAttrib.links[i] = value; |
---|
| 510 | } |
---|
| 511 | |
---|
| 512 | // atomPublished? |
---|
| 513 | value = this.getFirstChildValue(node, atomns, "published", null); |
---|
| 514 | if (value) { |
---|
| 515 | atomAttrib.published = value; |
---|
| 516 | } |
---|
| 517 | |
---|
| 518 | // atomRights? |
---|
| 519 | value = this.getFirstChildValue(node, atomns, "rights", null); |
---|
| 520 | if (value) { |
---|
| 521 | atomAttrib.rights = value; |
---|
| 522 | } |
---|
| 523 | |
---|
| 524 | // atomSource? -- not implemented |
---|
| 525 | |
---|
| 526 | // atomSummary? |
---|
| 527 | value = this.getFirstChildValue(node, atomns, "summary", null); |
---|
| 528 | if (value) { |
---|
| 529 | atomAttrib.summary = value; |
---|
| 530 | } |
---|
| 531 | |
---|
| 532 | // atomTitle |
---|
| 533 | atomAttrib.title = this.getFirstChildValue( |
---|
| 534 | node, atomns, "title", null |
---|
| 535 | ); |
---|
| 536 | |
---|
| 537 | // atomUpdated |
---|
| 538 | atomAttrib.updated = this.getFirstChildValue( |
---|
| 539 | node, atomns, "updated", null |
---|
| 540 | ); |
---|
| 541 | |
---|
| 542 | var featureAttrib = { |
---|
| 543 | title: atomAttrib.title, |
---|
| 544 | description: atomAttrib.summary, |
---|
| 545 | atom: atomAttrib |
---|
| 546 | }; |
---|
| 547 | var geometry = this.parseLocations(node)[0]; |
---|
| 548 | var feature = new OpenLayers.Feature.Vector(geometry, featureAttrib); |
---|
| 549 | feature.fid = atomAttrib.id; |
---|
| 550 | return feature; |
---|
| 551 | }, |
---|
| 552 | |
---|
| 553 | /** |
---|
| 554 | * Method: parseFeatures |
---|
| 555 | * Return features from an Atom entry or feed. |
---|
| 556 | * |
---|
| 557 | * Parameters: |
---|
| 558 | * node - {DOMElement} An Atom entry or feed node. |
---|
| 559 | * |
---|
| 560 | * Returns: |
---|
| 561 | * An Array of <OpenLayers.Feature.Vector>s. |
---|
| 562 | */ |
---|
| 563 | parseFeatures: function(node) { |
---|
| 564 | var features = []; |
---|
| 565 | var entries = this.getElementsByTagNameNS( |
---|
| 566 | node, this.namespaces.atom, "entry" |
---|
| 567 | ); |
---|
| 568 | if (entries.length == 0) { |
---|
| 569 | entries = [node]; |
---|
| 570 | } |
---|
| 571 | for (var i=0, ii=entries.length; i<ii; i++) { |
---|
| 572 | features.push(this.parseFeature(entries[i])); |
---|
| 573 | } |
---|
| 574 | return features; |
---|
| 575 | }, |
---|
| 576 | |
---|
| 577 | /** |
---|
| 578 | * Method: parseLocations |
---|
| 579 | * Parse the locations from an Atom entry or feed. |
---|
| 580 | * |
---|
| 581 | * Parameters: |
---|
| 582 | * node - {DOMElement} An Atom entry or feed node. |
---|
| 583 | * |
---|
| 584 | * Returns: |
---|
| 585 | * An Array of <OpenLayers.Geometry>s. |
---|
| 586 | */ |
---|
| 587 | parseLocations: function(node) { |
---|
| 588 | var georssns = this.namespaces.georss; |
---|
| 589 | |
---|
| 590 | var locations = {components: []}; |
---|
| 591 | var where = this.getElementsByTagNameNS(node, georssns, "where"); |
---|
| 592 | if (where && where.length > 0) { |
---|
| 593 | if (!this.gmlParser) { |
---|
| 594 | this.initGmlParser(); |
---|
| 595 | } |
---|
| 596 | for (var i=0, ii=where.length; i<ii; i++) { |
---|
| 597 | this.gmlParser.readChildNodes(where[i], locations); |
---|
| 598 | } |
---|
| 599 | } |
---|
| 600 | |
---|
| 601 | var components = locations.components; |
---|
| 602 | var point = this.getElementsByTagNameNS(node, georssns, "point"); |
---|
| 603 | if (point && point.length > 0) { |
---|
| 604 | for (var i=0, ii=point.length; i<ii; i++) { |
---|
| 605 | var xy = OpenLayers.String.trim( |
---|
| 606 | point[i].firstChild.nodeValue |
---|
| 607 | ).split(/\s+/); |
---|
| 608 | if (xy.length !=2) { |
---|
| 609 | xy = OpenLayers.String.trim( |
---|
| 610 | point[i].firstChild.nodeValue |
---|
| 611 | ).split(/\s*,\s*/); |
---|
| 612 | } |
---|
| 613 | components.push( |
---|
| 614 | new OpenLayers.Geometry.Point( |
---|
| 615 | parseFloat(xy[1]), |
---|
| 616 | parseFloat(xy[0]) |
---|
| 617 | ) |
---|
| 618 | ); |
---|
| 619 | } |
---|
| 620 | } |
---|
| 621 | |
---|
| 622 | var line = this.getElementsByTagNameNS(node, georssns, "line"); |
---|
| 623 | if (line && line.length > 0) { |
---|
| 624 | var coords; |
---|
| 625 | var p; |
---|
| 626 | var points; |
---|
| 627 | for (var i=0, ii=line.length; i<ii; i++) { |
---|
| 628 | coords = OpenLayers.String.trim( |
---|
| 629 | line[i].firstChild.nodeValue |
---|
| 630 | ).split(/\s+/); |
---|
| 631 | points = []; |
---|
| 632 | for (var j=0, jj=coords.length; j<jj; j+=2) { |
---|
| 633 | p = new OpenLayers.Geometry.Point( |
---|
| 634 | parseFloat(coords[j+1]), |
---|
| 635 | parseFloat(coords[j]) |
---|
| 636 | ); |
---|
| 637 | points.push(p); |
---|
| 638 | } |
---|
| 639 | components.push( |
---|
| 640 | new OpenLayers.Geometry.LineString(points) |
---|
| 641 | ); |
---|
| 642 | } |
---|
| 643 | } |
---|
| 644 | |
---|
| 645 | var polygon = this.getElementsByTagNameNS(node, georssns, "polygon"); |
---|
| 646 | if (polygon && polygon.length > 0) { |
---|
| 647 | var coords; |
---|
| 648 | var p; |
---|
| 649 | var points; |
---|
| 650 | for (var i=0, ii=polygon.length; i<ii; i++) { |
---|
| 651 | coords = OpenLayers.String.trim( |
---|
| 652 | polygon[i].firstChild.nodeValue |
---|
| 653 | ).split(/\s+/); |
---|
| 654 | points = []; |
---|
| 655 | for (var j=0, jj=coords.length; j<jj; j+=2) { |
---|
| 656 | p = new OpenLayers.Geometry.Point( |
---|
| 657 | parseFloat(coords[j+1]), |
---|
| 658 | parseFloat(coords[j]) |
---|
| 659 | ); |
---|
| 660 | points.push(p); |
---|
| 661 | } |
---|
| 662 | components.push( |
---|
| 663 | new OpenLayers.Geometry.Polygon( |
---|
| 664 | [new OpenLayers.Geometry.LinearRing(components)] |
---|
| 665 | ) |
---|
| 666 | ); |
---|
| 667 | } |
---|
| 668 | } |
---|
| 669 | |
---|
| 670 | if (this.internalProjection && this.externalProjection) { |
---|
| 671 | for (var i=0, ii=components.length; i<ii; i++) { |
---|
| 672 | if (components[i]) { |
---|
| 673 | components[i].transform( |
---|
| 674 | this.externalProjection, |
---|
| 675 | this.internalProjection |
---|
| 676 | ); |
---|
| 677 | } |
---|
| 678 | } |
---|
| 679 | } |
---|
| 680 | |
---|
| 681 | return components; |
---|
| 682 | }, |
---|
| 683 | |
---|
| 684 | /** |
---|
| 685 | * Method: parsePersonConstruct |
---|
| 686 | * Parse Atom person constructs from an Atom entry node. |
---|
| 687 | * |
---|
| 688 | * Parameters: |
---|
| 689 | * node - {DOMElement} An Atom entry or feed node. |
---|
| 690 | * name - {String} Construcy name ("author" or "contributor") |
---|
| 691 | * data = {Object} Object in which to put parsed persons. |
---|
| 692 | * |
---|
| 693 | * Returns: |
---|
| 694 | * An {Object}. |
---|
| 695 | */ |
---|
| 696 | parsePersonConstructs: function(node, name, data) { |
---|
| 697 | var persons = []; |
---|
| 698 | var atomns = this.namespaces.atom; |
---|
| 699 | var nodes = this.getElementsByTagNameNS(node, atomns, name); |
---|
| 700 | var oAtts = ["uri", "email"]; |
---|
| 701 | for (var i=0, ii=nodes.length; i<ii; i++) { |
---|
| 702 | var value = {}; |
---|
| 703 | value.name = this.getFirstChildValue( |
---|
| 704 | nodes[i], |
---|
| 705 | atomns, |
---|
| 706 | "name", |
---|
| 707 | null |
---|
| 708 | ); |
---|
| 709 | for (var j=0, jj=oAtts.length; j<jj; j++) { |
---|
| 710 | var attval = this.getFirstChildValue( |
---|
| 711 | nodes[i], |
---|
| 712 | atomns, |
---|
| 713 | oAtts[j], |
---|
| 714 | null); |
---|
| 715 | if (attval) { |
---|
| 716 | value[oAtts[j]] = attval; |
---|
| 717 | } |
---|
| 718 | } |
---|
| 719 | persons.push(value); |
---|
| 720 | } |
---|
| 721 | if (persons.length > 0) { |
---|
| 722 | data[name + "s"] = persons; |
---|
| 723 | } |
---|
| 724 | }, |
---|
| 725 | |
---|
| 726 | CLASS_NAME: "OpenLayers.Format.Atom" |
---|
| 727 | }); |
---|