OpenLayers OpenLayers

Ticket #927: KML.js.patch

File KML.js.patch, 11.3 kB (added by openlayers, 1 year ago)

Makes KML class extend XML class, implements the write() method (GGE compatible), uses the XML class methods for XML manipulation

  • /home/dcorpataux/workspace/openlayers/lib/OpenLayers/Format/KML.js

    old new  
    1 /* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license. 
    2  * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     1/* Copyright (c) 2006 MetaCarta, Inc., published under a BSD license. 
     2 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt  
    33 * for the full text of the license. */ 
    44 
    55/** 
     
    66 * @requires OpenLayers/Format.js 
    77 * @requires OpenLayers/Feature/Vector.js 
    88 * @requires OpenLayers/Ajax.js 
     9 * 
     10 * Class: OpenLayers.Format.KML 
     11 * Read/Wite KML. Create a new instance with the <OpenLayers.Format.KML> 
     12 *     constructor.  
    913 *  
    10  * Class: OpenLayers.Format.KML 
    11  * Read only KML. Largely Proof of Concept: does not support advanced Features, 
    12  *     including Polygons.  Create a new instance with the  
    13  *     <OpenLayers.Format.KML> constructor. 
    14  * 
    1514 * Inherits from: 
    1615 *  - <OpenLayers.Format> 
    1716 */ 
    18 OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format, { 
     17OpenLayers.Format.KML = OpenLayers.Class.create(); 
     18OpenLayers.Format.KML.prototype =  
     19  OpenLayers.Class.inherit(OpenLayers.Format.XML, { 
    1920     
    2021    /** 
    2122     * APIProperty: kmlns 
     
    2324     */ 
    2425    kmlns: "http://earth.google.com/kml/2.0", 
    2526     
     27    /**  
     28     * APIProperty: placemarksDesc 
     29     * Name of the placemarks. 
     30     */ 
     31    placemarksDesc: "No description available", 
     32     
     33    /**  
     34     * APIProperty: foldersName 
     35     * Name of the folders. 
     36     */ 
     37    foldersName: "OpenLayers export", 
     38     
     39    /**  
     40     * APIProperty: foldersDesc 
     41     * Description of the folders. 
     42     */ 
     43    foldersDesc: "Exported on " + new Date(), 
     44     
    2645    /** 
    2746     * Constructor: OpenLayers.Format.KML 
    2847     * Create a new parser for KML 
     
    4059     * Read data from a string, and return a list of features.  
    4160     *  
    4261     * Parameters:  
    43      * data - {string} or {XMLNode>} data to read/parse. 
     62     * data - {string} or {<XMLNode>} data to read/parse. 
    4463     */ 
    4564     read: function(data) { 
    46         if (typeof data == "string") {  
    47             data = OpenLayers.parseXMLString(data); 
    48         }     
    49         var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.kmlns, "", "Placemark"); 
    50          
     65        if (typeof data == "string") { 
     66           data = OpenLayers.parseXMLString(data); 
     67        }             
     68        var featureNodes = this.getElementsByTagNameNS(data, this.kmlns, "Placemark"); 
     69 
    5170        var features = []; 
    5271         
    5372        // Process all the featureMembers 
     
    7796        var feature = new OpenLayers.Feature.Vector(); 
    7897 
    7998        // match Point 
    80         if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, 
    81             this.kmlns, "", "Point").length != 0) { 
    82             var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, 
    83                 this.kmlns, "", "Point")[0]; 
    84              
     99        if (this.getElementsByTagNameNS(xmlNode, this.kmlns, "Point").length != 0) { 
     100            var point = this.getElementsByTagNameNS(xmlNode, this.kmlns, "Point")[0]; 
    85101            p = this.parseCoords(point); 
    86102            if (p.points) { 
    87103                geom = p.points[0]; 
     
    90106            } 
    91107         
    92108        // match LineString  
    93         } else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, 
    94             this.kmlns, "", "LineString").length != 0) { 
    95             var linestring = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, 
    96                 this.kmlns, "", "LineString")[0]; 
     109        } else if (this.getElementsByTagNameNS(xmlNode, this.kmlns, "LineString").length != 0) { 
     110            var linestring = this.getElementsByTagNameNS(xmlNode, this.kmlns, "LineString")[0]; 
    97111            p = this.parseCoords(linestring); 
    98112            if (p.points) { 
    99113                geom = new OpenLayers.Geometry.LineString(p.points); 
     
    100114                // TBD Bounds only set for one of multiple geometries 
    101115                geom.extendBounds(p.bounds); 
    102116            } 
     117 
     118        // match Polygon  
     119        } else if (this.getElementsByTagNameNS(xmlNode, this.kmlns, "Polygon").length != 0) { 
     120            var polygon = this.getElementsByTagNameNS(xmlNode, this.kmlns, "Polygon")[0]; 
     121            p = this.parseCoords(polygon); 
     122            if (p.points) { 
     123                var linearRing = new OpenLayers.Geometry.LinearRing(p.points); 
     124                geom = new OpenLayers.Geometry.Polygon(linearRing); 
     125                // TBD Bounds only set for one of multiple geometries 
     126                geom.extendBounds(p.bounds); 
     127            } 
    103128        } 
    104129         
    105130        feature.geometry = geom; 
     
    156181        p.points = []; 
    157182        // TBD: Need to handle an array of coordNodes not just coordNodes[0] 
    158183         
    159         var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.kmlns, "", "coordinates")[0]; 
     184        var coordNodes = this.getElementsByTagNameNS(xmlNode, this.kmlns, "coordinates")[0]; 
    160185        var coordString = OpenLayers.Util.getXmlNodeValue(coordNodes); 
    161186         
    162187        var firstCoord = coordString.split(" "); 
     
    191216        return p; 
    192217    }, 
    193218 
     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 */ 
    194386    CLASS_NAME: "OpenLayers.Format.KML"  
    195 });      
     387});