OpenLayers OpenLayers

Ticket #973: georss.patch

File georss.patch, 19.1 kB (added by crschmidt, 10 months ago)
  • tests/Format/test_GeoRSS.html

    old new  
    1818    function test_Format_GeoRSS_serializeline(t) {  
    1919        t.plan(1); 
    2020 
    21         if (OpenLayers.Util.getBrowserName() == "msie") { 
    22             //serialization currently not supported in IE 
    23             t.ok(true, "GeoRSS serialization not currently supported in IE"); 
    24         } else { 
    25             var parser = new OpenLayers.Format.GeoRSS(); 
    26             var point = new OpenLayers.Geometry.Point(-111.04, 45.68);   
    27             var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);  
    28             var l = new OpenLayers.Geometry.LineString([point, point2]); 
    29             var f = new OpenLayers.Feature.Vector(l); 
    30             var data = parser.write([f]); 
    31             t.eq(data.firstChild.childNodes[2].firstChild.nodeValue, '45.68 -111.04 45.68 -112.04 ', 'GeoRSS serializes a line correctly'); 
     21        var parser = new OpenLayers.Format.GeoRSS(); 
     22        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);   
     23        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);  
     24        var l = new OpenLayers.Geometry.LineString([point, point2]); 
     25        var f = new OpenLayers.Feature.Vector(l); 
     26        var data = parser.write([f]); 
     27        t.eq(data, '<rss xmlns="http://backend.userland.com/rss2"><item><title></title><description></description><georss:line xmlns:georss="http://www.georss.org/georss">45.68 -111.04 45.68 -112.04 </georss:line></item></rss>', 'GeoRSS serializes a line correctly'); 
     28    } 
     29    function test_Format_GeoRSS_roundtrip(t) { 
     30        t.plan(input.length); 
     31        var parser = new OpenLayers.Format.GeoRSS(); 
     32        for(var i=0; i < input.length; i++) { 
     33            var feed = shell_start+input[i]+shell_end; 
     34            var data = parser.read(feed); 
     35            var out = parser.write(data); 
     36            t.eq(out, output[i], "Output gave expected value"); 
    3237        } 
    3338    } 
     39              
     40    var shell_start = '<feed xmlns="http://www.w3.org/2005/Atom" \n              xmlns:georss="http://www.georss.org/georss">\n              <title>scribble</title>\n              <id>http://featureserver.org/featureserver.cgi/scribble?format=atom</id>\n              <author><name>FeatureServer</name></author>\n';              
     41    var shell_end = '</feed>';  
     42    var input = ['<entry><id>http://featureserver.org/featureserver.cgi/scribble/562.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/562.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:polygon>-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375</georss:polygon></entry>', 
     43    '<entry><id>http://featureserver.org/featureserver.cgi/scribble/796.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/796.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:point>75.5859375 15.46875</georss:point></entry>', 
     44    '<entry><id>http://featureserver.org/featureserver.cgi/scribble/794.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/794.atom"/><title>Feature 5</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:line>28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125</georss:line></entry>'  
     45    ]; 
     46    var output= ['<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/562.atom</link><georss:polygon xmlns:georss="http://www.georss.org/georss">-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375 </georss:polygon></item></rss>', 
     47   '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/796.atom</link><georss:point xmlns:georss="http://www.georss.org/georss">75.5859375 15.46875 </georss:point></item></rss>', 
     48   '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 5</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/794.atom</link><georss:line xmlns:georss="http://www.georss.org/georss">28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125 </georss:line></item></rss>']; 
    3449 
    3550    </script>  
    3651</head>  
  • lib/OpenLayers/Format/GeoRSS.js

    old new  
    44 
    55/** 
    66 * @requires OpenLayers/Format.js 
     7 * @requires OpenLayers/Format/XML.js 
    78 * 
    89 * Class: OpenLayers.Format.GeoRSS 
    910 * Write-only GeoRSS. Create a new instance with the  
     
    1213 * Inherits from: 
    1314 *  - <OpenLayers.Format> 
    1415 */ 
    15 OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, { 
     16OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, { 
    1617     
    1718    /** 
    1819     * APIProperty: rssns 
     
    4243     *                    this instance. 
    4344     */ 
    4445    initialize: function(options) { 
    45         OpenLayers.Format.prototype.initialize.apply(this, [options]); 
     46        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); 
    4647    }, 
     48     
     49    /** 
     50     * Method: createGeometryFromItem 
     51     * Return an {<OpenLayers.Geometry>} from an XML dom GeoRSS Item. 
     52     */ 
     53    createGeometryFromItem: function(item) { 
     54        var point = this.getElementsByTagNameNS(item, 
     55                                                      this.georssns, 
     56                                                      "point"); 
     57        var lat = OpenLayers.Util.getNodes(item, 'geo:lat'); 
     58        var lon = OpenLayers.Util.getNodes(item, 'geo:long'); 
     59         
     60        var line = this.getElementsByTagNameNS(item, 
     61                                                this.georssns, 
     62                                                "line"); 
     63        var polygon = this.getElementsByTagNameNS(item, 
     64                                                this.georssns, 
     65                                                "polygon"); 
     66         
     67        if (point.length > 0 || (lat.length > 0 && lon.length > 0)) { 
     68            if (point.length > 0) { 
     69                var location = point[0].firstChild.nodeValue.trim().split(/\s+/); 
     70                 
     71                if (location.length !=2) { 
     72                    var location = point[0].firstChild.nodeValue.trim().split(/\s*,\s*/); 
     73                } 
     74            } else { 
     75                var location = [parseFloat(lat[0].firstChild.nodeValue), parseFloat(lon[0].firstChild.nodeValue)]; 
     76            }     
     77            var geometry = new OpenLayers.Geometry.Point(parseFloat(location[1]), 
     78                                                     parseFloat(location[0])); 
     79        } else if (line.length > 0) { 
     80            var coords = line[0].firstChild.nodeValue.trim().split(/\s+/); 
     81            var components = [];  
     82            for (var i=0; i < coords.length; i+=2) { 
     83                var point = new OpenLayers.Geometry.Point(parseFloat(coords[i+1]), parseFloat(coords[i])); 
     84                components.push(point); 
     85            } 
     86            geometry = new OpenLayers.Geometry.LineString(components); 
     87        } else if (polygon.length > 0) {  
     88            var coords = polygon[0].firstChild.nodeValue.trim().split(/\s+/); 
     89            var components = [];  
     90            for (var i=0; i < coords.length; i+=2) { 
     91                var point = new OpenLayers.Geometry.Point(parseFloat(coords[i+1]), parseFloat(coords[i])); 
     92                components.push(point); 
     93            } 
     94            geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]); 
     95        } 
     96        return geometry;                                              
     97    },         
    4798 
    4899    /** 
     100     * Method: createGeometryFromItem 
     101     * Return an {<OpenLayers.Feature.Vector>} from an XML dom GeoRSS Item. 
     102     */ 
     103    createFeatureFromItem: function(item) { 
     104            var geometry = this.createGeometryFromItem(item); 
     105            /* Provide defaults for title and description */ 
     106            var title = "Untitled"; 
     107            try { 
     108                title = OpenLayers.Util.getNodes(item,  
     109                        "title")[0].firstChild.nodeValue; 
     110            } 
     111            catch (e) { title="Untitled"; } 
     112            
     113            /* First try RSS descriptions, then Atom summaries */ 
     114            var descr_nodes = this.getElementsByTagNameNS(item, 
     115                                                          "*", 
     116                                                          "description"); 
     117            if (descr_nodes.length == 0) { 
     118                descr_nodes = this.getElementsByTagNameNS(item, 
     119                                                          "*", 
     120                                                          "content"); 
     121            } 
     122            var description = "No description."; 
     123            try { 
     124              description = descr_nodes[0].firstChild.nodeValue; 
     125            } 
     126            catch (e) { description="No description."; } 
     127 
     128            /* If no link URL is found in the first child node, try the 
     129               href attribute */ 
     130            var link = null; 
     131            var edit_link = null; 
     132            try { 
     133                var link = OpenLayers.Util.getNodes(item, "link")[0].firstChild.nodeValue; 
     134            } 
     135            catch (e) { 
     136                var link_list = OpenLayers.Util.getNodes(item, "link"); 
     137                for (var i = 0; i < link_list.length; i++) { 
     138                    var this_link = link_list[i]; 
     139                    link = this_link.getAttribute("href"); 
     140                }     
     141            } 
     142            var id = null; 
     143            try { 
     144                id = OpenLayers.Util.getNodes(item, "id")[0].firstChild.nodeValue; 
     145            } catch (e) { 
     146            } 
     147             
     148            var data = { 
     149                "title": title, 
     150                "description": description, 
     151                "link": link 
     152            }; 
     153            var feature = new OpenLayers.Feature.Vector(geometry, data); 
     154            feature.fid = id; 
     155            return feature; 
     156    },         
     157     
     158    /** 
     159     * APIMethod: read 
     160     * Return a list of features from a GeoRSS doc 
     161      
     162     * Parameters: 
     163     * data - {Element}  
     164     * 
     165     * Returns: 
     166     * An Array of <OpenLayers.Feature.Vector>s 
     167     */ 
     168    read: function(doc) { 
     169        if (typeof doc == "string") {  
     170            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]); 
     171        } 
     172 
     173        /* Try RSS items first, then Atom entries */ 
     174        var itemlist = null; 
     175        itemlist = this.getElementsByTagNameNS(doc, '*', 'item'); 
     176        if (itemlist.length == 0) { 
     177            itemlist = this.getElementsByTagNameNS(doc, '*', 'entry'); 
     178        } 
     179         
     180        var features = []; 
     181        for(var i=0; i<itemlist.length; i++) { 
     182            // this is horrendous - please change this 
     183            var item = itemlist[i]; 
     184            features.push(this.createFeatureFromItem(item)); 
     185        } 
     186        return features; 
     187    }, 
     188     
     189 
     190    /** 
    49191     * APIMethod: write 
    50192     * Accept Feature Collection, and return a string.  
    51193     *  
    52194     * Parameters:  
    53195     * features - Array({<OpenLayers.Feature.Vector>}) List of features to serialize into a string. 
    54196     */ 
    55      write: function(features) { 
    56         var featureCollection = document.createElementNS(this.rssns, "rss"); 
    57         for (var i=0; i < features.length; i++) { 
    58             featureCollection.appendChild(this.createFeatureXML(features[i])); 
     197    write: function(features) { 
     198        var georss; 
     199        if(features instanceof Array) { 
     200            georss = this.createElementNS(this.rssns, "rss"); 
     201            for(var i=0; i < features.length; i++) { 
     202                georss.appendChild(this.createFeatureXML(features[i])); 
     203            } 
     204        } else { 
     205            georss = this.createFeatureXML(features); 
    59206        } 
    60         return featureCollection
     207        return OpenLayers.Format.XML.prototype.write.apply(this, [georss])
    61208     }, 
    62      
     209 
    63210    /** 
    64211     * Method: createFeatureXML 
    65212     * Accept an <OpenLayers.Feature.Vector>, and build a geometry for it. 
     
    72219     */ 
    73220    createFeatureXML: function(feature) { 
    74221        var geometryNode = this.buildGeometryNode(feature.geometry); 
    75         var featureNode = document.createElementNS(this.rssns, "item"); 
    76         var titleNode = document.createElementNS(this.rssns, "title"); 
    77         titleNode.appendChild(document.createTextNode(feature.attributes.title ? feature.attributes.title : "")); 
    78         var descNode = document.createElementNS(this.rssns, "description"); 
    79         descNode.appendChild(document.createTextNode(feature.attributes.description ? feature.attributes.description : "")); 
     222        var featureNode = this.createElementNS(this.rssns, "item"); 
     223        var titleNode = this.createElementNS(this.rssns, "title"); 
     224        titleNode.appendChild(this.createTextNode(feature.attributes.title ? feature.attributes.title : "")); 
     225        var descNode = this.createElementNS(this.rssns, "description"); 
     226        descNode.appendChild(this.createTextNode(feature.attributes.description ? feature.attributes.description : "")); 
    80227        featureNode.appendChild(titleNode); 
    81228        featureNode.appendChild(descNode); 
     229        if (feature.attributes.link) { 
     230            var linkNode = this.createElementNS(this.rssns, "link"); 
     231            linkNode.appendChild(this.createTextNode(feature.attributes.link)); 
     232            featureNode.appendChild(linkNode); 
     233        }     
    82234        for(var attr in feature.attributes) { 
    83             var attrText = document.createTextNode(feature.attributes[attr]);  
     235            if (attr == "link" || attr == "title" || attr == "description") { continue; }  
     236            var attrText = this.createTextNode(feature.attributes[attr]);  
    84237            var nodename = attr; 
    85238            if (attr.search(":") != -1) { 
    86239                nodename = attr.split(":")[1]; 
    87240            }     
    88             var attrContainer = document.createElementNS(this.featureNS, "feature:"+nodename); 
     241            var attrContainer = this.createElementNS(this.featureNS, "feature:"+nodename); 
    89242            attrContainer.appendChild(attrText); 
    90243            featureNode.appendChild(attrContainer); 
    91244        }     
     
    104257        var gml = ""; 
    105258        // match MultiPolygon or Polygon 
    106259        if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") { 
    107                 gml = document.createElementNS(this.georssns, 'georss:polygon'); 
    108                  
    109                 gml.appendChild(this.buildCoordinatesNode(geometry.components[0])); 
    110            
     260            gml = this.createElementNS(this.georssns, 'georss:polygon'); 
     261             
     262            gml.appendChild(this.buildCoordinatesNode(geometry.components[0])); 
     263       
    111264        // match MultiLineString or LineString 
    112265        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") { 
    113                      gml = document.createElementNS(this.georssns, 'georss:line'); 
    114                       
    115                      gml.appendChild(this.buildCoordinatesNode(geometry)); 
    116                  
     266            gml = this.createElementNS(this.georssns, 'georss:line'); 
     267             
     268            gml.appendChild(this.buildCoordinatesNode(geometry)); 
     269       
    117270        // match MultiPoint or Point 
    118271        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") { 
    119                 gml = document.createElementNS(this.georssns, 'georss:point'); 
    120                 gml.appendChild(this.buildCoordinatesNode(geometry)); 
     272            gml = this.createElementNS(this.georssns, 'georss:point'); 
     273            gml.appendChild(this.buildCoordinatesNode(geometry)); 
    121274        } else {     
    122           alert("Couldn't parse " + geometry.CLASS_NAME); 
     275            alert("Couldn't parse " + geometry.CLASS_NAME); 
    123276        }   
    124277        return gml;          
    125278    }, 
     
    145298        } else { 
    146299           path += geometry.y + " " + geometry.x + " "; 
    147300        } 
    148         return document.createTextNode(path); 
     301        return this.createTextNode(path); 
    149302    }, 
    150303 
    151304    CLASS_NAME: "OpenLayers.Format.GeoRSS"