OpenLayers OpenLayers

Changeset 5814

Show
Ignore:
Timestamp:
01/19/08 12:36:02 (1 year ago)
Author:
crschmidt
Message:

Add serialization support to OSM class. ID is now stored in osm_id property so that there are
no conflicts.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • sandbox/crschmidt/osm/lib/OpenLayers/Format/OSM.js

    r5751 r5814  
    111111                
    112112               // Since OSM is topological, we stash the node ID internally.  
    113                point.id = ways[i].nodes[j]; 
     113               point.osm_id = ways[i].nodes[j]; 
    114114               point_list[j] = point; 
    115115                
     
    131131            var feat = new OpenLayers.Feature.Vector(geometry, 
    132132                ways[i].tags); 
    133             feat.fid = ways[i].id; 
     133            feat.osm_id = ways[i].id; 
    134134            feat_list[i] = feat; 
    135135        }  
     
    156156                        this.internalProjection); 
    157157                }         
    158                 feat.fid = node_id;  
     158                feat.osm_id = node_id;  
    159159                feat_list.push(feat); 
    160160            }    
     
    274274        }     
    275275        return poly_shaped && (this.checkTags ? poly_tags : true);             
    276     },   
     276    },  
     277 
     278    /** 
     279     * APIMethod: write  
     280     * Takes a list of features, returns a serialized OSM format file for use 
     281     * in tools like JOSM. 
     282     * 
     283     * Parameters: 
     284     * features - Array({<OpenLayers.Feature.Vector>}) 
     285     */ 
     286    write: function(features) {  
     287        if (!(features instanceof Array)) { 
     288            features = [features]; 
     289        } 
     290         
     291        this.osm_id = 1; 
     292        this.created_nodes = {}; 
     293        var root_node = document.createElementNS(null, "osm"); 
     294        root_node.setAttribute("version", "0.5"); 
     295        root_node.setAttribute("generator", "OpenLayers "+ OpenLayers.VERSION_NUMBER); 
     296 
     297        // Loop backwards, because the deserializer puts nodes last, and  
     298        // we want them first if possible 
     299        for(var i = features.length - 1; i >= 0; i--) { 
     300            var nodes = this.createFeatureNodes(features[i]); 
     301            for (var j = 0; j < nodes.length; j++) { 
     302                root_node.appendChild(nodes[j]); 
     303            }     
     304        } 
     305        return OpenLayers.Format.XML.prototype.write.apply(this, [root_node]); 
     306    }, 
     307 
     308    /** 
     309     * Method: createFeatureNodes 
     310     * Takes a feature, returns a list of nodes from size 0->n. 
     311     * Will include all pieces of the serialization that are required which 
     312     * have not already been created. Calls out to createXML based on geometry 
     313     * type. 
     314     * 
     315     * Parameters: 
     316     * feature - {<OpenLayers.Feature.Vector>} 
     317     */ 
     318    createFeatureNodes: function(feature) { 
     319        var nodes = []; 
     320        var className = feature.geometry.CLASS_NAME; 
     321        var type = className.substring(className.lastIndexOf(".") + 1) 
     322        type = type.toLowerCase(); 
     323        var builder = this.createXML[type]; 
     324        if (builder) { 
     325            nodes = builder.apply(this, [feature]); 
     326        } 
     327        return nodes; 
     328    }, 
     329     
     330    /** 
     331     * Method: createXML 
     332     * Takes a feature, returns a list of nodes from size 0->n. 
     333     * Will include all pieces of the serialization that are required which 
     334     * have not already been created. 
     335     * 
     336     * Parameters: 
     337     * feature - {<OpenLayers.Feature.Vector>} 
     338     */ 
     339    createXML: { 
     340        'point': function(point) { 
     341            var id = null; 
     342            var geometry = point.geometry ? point.geometry : point; 
     343            var already_exists = false; // We don't return anything if the node 
     344                                        // has already been created 
     345            if (point.osm_id) { 
     346                id = point.osm_id; 
     347                if (this.created_nodes[id]) { 
     348                    already_exists = true; 
     349                }     
     350            } else { 
     351               id = -this.osm_id; 
     352               this.osm_id++;  
     353            } 
     354            if (already_exists) { 
     355                node = this.created_nodes[id]; 
     356            } else {     
     357                var node = this.createElementNS(null, "node"); 
     358            } 
     359            this.created_nodes[id] = node; 
     360            node.setAttribute("id", id); 
     361            node.setAttribute("lon", geometry.x);  
     362            node.setAttribute("lat", geometry.y); 
     363            if (point.attributes) { 
     364                this.serializeTags(point, node); 
     365            } 
     366            this.setState(point, node); 
     367            return already_exists ? [] : [node]; 
     368        },  
     369        linestring: function(feature) { 
     370            var nodes = []; 
     371            var geometry = feature.geometry; 
     372            if (feature.osm_id) { 
     373                id = feature.osm_id; 
     374            } else { 
     375               id = -this.osm_id; 
     376               this.osm_id++;  
     377            } 
     378            var way = this.createElementNS(null, "way"); 
     379            way.setAttribute("id", id); 
     380            for (var i = 0; i < geometry.components.length; i++) { 
     381                var node = this.createXML['point'].apply(this, [geometry.components[i]]); 
     382                if (node.length) { 
     383                    node = node[0]; 
     384                    var node_ref = node.getAttribute("id"); 
     385                    nodes.push(node); 
     386                } else { 
     387                    node_ref = geometry.components[i].osm_id; 
     388                    node = this.created_nodes[node_ref]; 
     389                } 
     390                this.setState(feature, node); 
     391                var nd_dom = this.createElementNS(null, "nd"); 
     392                nd_dom.setAttribute("ref", node_ref); 
     393                way.appendChild(nd_dom); 
     394            } 
     395            this.serializeTags(feature, way); 
     396            nodes.push(way); 
     397             
     398            return nodes; 
     399        }, 
     400        polygon: function(feature) { 
     401            var attrs = OpenLayers.Util.extend({'area':'yes'}, feature.attributes); 
     402            var feat = new OpenLayers.Feature.Vector(feature.geometry.components[0], attrs);  
     403            feat.osm_id = feature.osm_id; 
     404            return this.createXML['linestring'].apply(this, [feat]); 
     405        } 
     406    }, 
     407 
     408    /** 
     409     * Method: serializeTags 
     410     * Given a feature, serialize the attributes onto the given node. 
     411     * 
     412     * Parameters: 
     413     * feature - {<OpenLayers.Feature.Vector>} 
     414     * node - {DOMNode} 
     415     */ 
     416    serializeTags: function(feature, node) { 
     417        for (var key in feature.attributes) { 
     418            var tag = this.createElementNS(null, "tag"); 
     419            tag.setAttribute("k", key); 
     420            tag.setAttribute("v", feature.attributes[key]); 
     421            node.appendChild(tag); 
     422        } 
     423    }, 
     424 
     425    /** 
     426     * Method: setState  
     427     * OpenStreetMap has a convention that 'state' is stored for modification or deletion. 
     428     * This allows the file to be uploaded via JOSM or the bulk uploader tool. 
     429     * 
     430     * Parameters: 
     431     * feature - {<OpenLayers.Feature.Vector>} 
     432     * node - {DOMNode} 
     433     */ 
     434    setState: function(feature, node) { 
     435        if (feature.state) { 
     436            var state = null; 
     437            switch(feature.state) { 
     438                case OpenLayers.State.UPDATE: 
     439                    state = "modify"; 
     440                case OpenLayers.State.DELETE: 
     441                    state = "delete"; 
     442            } 
     443            if (state) { 
     444                node.setAttribute("state", state); 
     445            } 
     446        }     
     447    }, 
     448 
    277449    CLASS_NAME: "OpenLayers.Format.OSM"  
    278450});