Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/OpenLayers/lib/OpenLayers/Format/OSM.js @ 76

Revision 76, 15.4 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
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/Feature/Vector.js
9 * @requires OpenLayers/Geometry/Point.js
10 * @requires OpenLayers/Geometry/LineString.js
11 * @requires OpenLayers/Geometry/Polygon.js
12 * @requires OpenLayers/Projection.js
13 */
14
15/** 
16 * Class: OpenLayers.Format.OSM
17 * OSM parser. Create a new instance with the
18 *     <OpenLayers.Format.OSM> constructor.
19 *
20 * Inherits from:
21 *  - <OpenLayers.Format.XML>
22 */
23OpenLayers.Format.OSM = OpenLayers.Class(OpenLayers.Format.XML, {
24   
25    /**
26     * APIProperty: checkTags
27     * {Boolean} Should tags be checked to determine whether something
28     * should be treated as a seperate node. Will slow down parsing.
29     * Default is false.
30     */
31    checkTags: false,
32
33    /**
34     * Property: interestingTagsExclude
35     * {Array} List of tags to exclude from 'interesting' checks on nodes.
36     * Must be set when creating the format. Will only be used if checkTags
37     * is set.
38     */
39    interestingTagsExclude: null, 
40   
41    /**
42     * APIProperty: areaTags
43     * {Array} List of tags indicating that something is an area. 
44     * Must be set when creating the format. Will only be used if
45     * checkTags is true.
46     */
47    areaTags: null, 
48   
49    /**
50     * Constructor: OpenLayers.Format.OSM
51     * Create a new parser for OSM.
52     *
53     * Parameters:
54     * options - {Object} An optional object whose properties will be set on
55     *     this instance.
56     */
57    initialize: function(options) {
58        var layer_defaults = {
59          'interestingTagsExclude': ['source', 'source_ref', 
60              'source:ref', 'history', 'attribution', 'created_by'],
61          'areaTags': ['area', 'building', 'leisure', 'tourism', 'ruins',
62              'historic', 'landuse', 'military', 'natural', 'sport'] 
63        };
64         
65        layer_defaults = OpenLayers.Util.extend(layer_defaults, options);
66       
67        var interesting = {};
68        for (var i = 0; i < layer_defaults.interestingTagsExclude.length; i++) {
69            interesting[layer_defaults.interestingTagsExclude[i]] = true;
70        }
71        layer_defaults.interestingTagsExclude = interesting;
72       
73        var area = {};
74        for (var i = 0; i < layer_defaults.areaTags.length; i++) {
75            area[layer_defaults.areaTags[i]] = true;
76        }
77        layer_defaults.areaTags = area;
78
79        // OSM coordinates are always in longlat WGS84
80        this.externalProjection = new OpenLayers.Projection("EPSG:4326");
81       
82        OpenLayers.Format.XML.prototype.initialize.apply(this, [layer_defaults]);
83    },
84   
85    /**
86     * APIMethod: read
87     * Return a list of features from a OSM doc
88     
89     * Parameters:
90     * data - {Element}
91     *
92     * Returns:
93     * An Array of <OpenLayers.Feature.Vector>s
94     */
95    read: function(doc) {
96        if (typeof doc == "string") { 
97            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);
98        }
99
100        var nodes = this.getNodes(doc);
101        var ways = this.getWays(doc);
102       
103        // Geoms will contain at least ways.length entries.
104        var feat_list = new Array(ways.length);
105       
106        for (var i = 0; i < ways.length; i++) {
107            // We know the minimal of this one ahead of time. (Could be -1
108            // due to areas/polygons)
109            var point_list = new Array(ways[i].nodes.length);
110           
111            var poly = this.isWayArea(ways[i]) ? 1 : 0; 
112            for (var j = 0; j < ways[i].nodes.length; j++) {
113               var node = nodes[ways[i].nodes[j]];
114               
115               var point = new OpenLayers.Geometry.Point(node.lon, node.lat);
116               
117               // Since OSM is topological, we stash the node ID internally.
118               point.osm_id = parseInt(ways[i].nodes[j]);
119               point_list[j] = point;
120               
121               // We don't display nodes if they're used inside other
122               // elements.
123               node.used = true; 
124            }
125            var geometry = null;
126            if (poly) { 
127                geometry = new OpenLayers.Geometry.Polygon(
128                    new OpenLayers.Geometry.LinearRing(point_list));
129            } else {   
130                geometry = new OpenLayers.Geometry.LineString(point_list);
131            }
132            if (this.internalProjection && this.externalProjection) {
133                geometry.transform(this.externalProjection, 
134                    this.internalProjection);
135            }       
136            var feat = new OpenLayers.Feature.Vector(geometry,
137                ways[i].tags);
138            feat.osm_id = parseInt(ways[i].id);
139            feat.fid = "way." + feat.osm_id;
140            feat_list[i] = feat;
141        } 
142        for (var node_id in nodes) {
143            var node = nodes[node_id];
144            if (!node.used || this.checkTags) {
145                var tags = null;
146               
147                if (this.checkTags) {
148                    var result = this.getTags(node.node, true);
149                    if (node.used && !result[1]) {
150                        continue;
151                    }
152                    tags = result[0];
153                } else { 
154                    tags = this.getTags(node.node);
155                }   
156               
157                var feat = new OpenLayers.Feature.Vector(
158                    new OpenLayers.Geometry.Point(node['lon'], node['lat']),
159                    tags);
160                if (this.internalProjection && this.externalProjection) {
161                    feat.geometry.transform(this.externalProjection, 
162                        this.internalProjection);
163                }       
164                feat.osm_id = parseInt(node_id); 
165                feat.fid = "node." + feat.osm_id;
166                feat_list.push(feat);
167            }   
168            // Memory cleanup
169            node.node = null;
170        }       
171        return feat_list;
172    },
173
174    /**
175     * Method: getNodes
176     * Return the node items from a doc. 
177     *
178     * Parameters:
179     * node - {DOMElement} node to parse tags from
180     */
181    getNodes: function(doc) {
182        var node_list = doc.getElementsByTagName("node");
183        var nodes = {};
184        for (var i = 0; i < node_list.length; i++) {
185            var node = node_list[i];
186            var id = node.getAttribute("id");
187            nodes[id] = {
188                'lat': node.getAttribute("lat"),
189                'lon': node.getAttribute("lon"),
190                'node': node
191            };
192        }
193        return nodes;
194    },
195
196    /**
197     * Method: getWays
198     * Return the way items from a doc. 
199     *
200     * Parameters:
201     * node - {DOMElement} node to parse tags from
202     */
203    getWays: function(doc) {
204        var way_list = doc.getElementsByTagName("way");
205        var return_ways = [];
206        for (var i = 0; i < way_list.length; i++) {
207            var way = way_list[i];
208            var way_object = {
209              id: way.getAttribute("id")
210            };
211           
212            way_object.tags = this.getTags(way);
213           
214            var node_list = way.getElementsByTagName("nd");
215           
216            way_object.nodes = new Array(node_list.length);
217           
218            for (var j = 0; j < node_list.length; j++) {
219                way_object.nodes[j] = node_list[j].getAttribute("ref");
220            } 
221            return_ways.push(way_object);
222        }
223        return return_ways; 
224       
225    }, 
226   
227    /**
228     * Method: getTags
229     * Return the tags list attached to a specific DOM element.
230     *
231     * Parameters:
232     * node - {DOMElement} node to parse tags from
233     * interesting_tags - {Boolean} whether the return from this function should
234     *    return a boolean indicating that it has 'interesting tags' --
235     *    tags like attribution and source are ignored. (To change the list
236     *    of tags, see interestingTagsExclude)
237     *
238     * Returns:
239     * tags - {Object} hash of tags
240     * interesting - {Boolean} if interesting_tags is passed, returns
241     *     whether there are any interesting tags on this element.
242     */
243    getTags: function(dom_node, interesting_tags) {
244        var tag_list = dom_node.getElementsByTagName("tag");
245        var tags = {};
246        var interesting = false;
247        for (var j = 0; j < tag_list.length; j++) {
248            var key = tag_list[j].getAttribute("k");
249            tags[key] = tag_list[j].getAttribute("v");
250            if (interesting_tags) {
251                if (!this.interestingTagsExclude[key]) {
252                    interesting = true;
253                }
254            }   
255        } 
256        return interesting_tags ? [tags, interesting] : tags;     
257    },
258
259    /**
260     * Method: isWayArea
261     * Given a way object from getWays, check whether the tags and geometry
262     * indicate something is an area.
263     *
264     * Returns:
265     * {Boolean}
266     */
267    isWayArea: function(way) { 
268        var poly_shaped = false;
269        var poly_tags = false;
270       
271        if (way.nodes[0] == way.nodes[way.nodes.length - 1]) {
272            poly_shaped = true;
273        }
274        if (this.checkTags) {
275            for(var key in way.tags) {
276                if (this.areaTags[key]) {
277                    poly_tags = true;
278                    break;
279                }
280            }
281        }   
282        return poly_shaped && (this.checkTags ? poly_tags : true);           
283    }, 
284
285    /**
286     * APIMethod: write
287     * Takes a list of features, returns a serialized OSM format file for use
288     * in tools like JOSM.
289     *
290     * Parameters:
291     * features - {Array(<OpenLayers.Feature.Vector>)}
292     */
293    write: function(features) { 
294        if (!(features instanceof Array)) {
295            features = [features];
296        }
297       
298        this.osm_id = 1;
299        this.created_nodes = {};
300        var root_node = this.createElementNS(null, "osm");
301        root_node.setAttribute("version", "0.5");
302        root_node.setAttribute("generator", "OpenLayers "+ OpenLayers.VERSION_NUMBER);
303
304        // Loop backwards, because the deserializer puts nodes last, and
305        // we want them first if possible
306        for(var i = features.length - 1; i >= 0; i--) {
307            var nodes = this.createFeatureNodes(features[i]);
308            for (var j = 0; j < nodes.length; j++) {
309                root_node.appendChild(nodes[j]);
310            }   
311        }
312        return OpenLayers.Format.XML.prototype.write.apply(this, [root_node]);
313    },
314
315    /**
316     * Method: createFeatureNodes
317     * Takes a feature, returns a list of nodes from size 0->n.
318     * Will include all pieces of the serialization that are required which
319     * have not already been created. Calls out to createXML based on geometry
320     * type.
321     *
322     * Parameters:
323     * feature - {<OpenLayers.Feature.Vector>}
324     */
325    createFeatureNodes: function(feature) {
326        var nodes = [];
327        var className = feature.geometry.CLASS_NAME;
328        var type = className.substring(className.lastIndexOf(".") + 1);
329        type = type.toLowerCase();
330        var builder = this.createXML[type];
331        if (builder) {
332            nodes = builder.apply(this, [feature]);
333        }
334        return nodes;
335    },
336   
337    /**
338     * Method: createXML
339     * Takes a feature, returns a list of nodes from size 0->n.
340     * Will include all pieces of the serialization that are required which
341     * have not already been created.
342     *
343     * Parameters:
344     * feature - {<OpenLayers.Feature.Vector>}
345     */
346    createXML: {
347        'point': function(point) {
348            var id = null;
349            var geometry = point.geometry ? point.geometry : point;
350            var already_exists = false; // We don't return anything if the node
351                                        // has already been created
352            if (point.osm_id) {
353                id = point.osm_id;
354                if (this.created_nodes[id]) {
355                    already_exists = true;
356                }   
357            } else {
358               id = -this.osm_id;
359               this.osm_id++; 
360            }
361            if (already_exists) {
362                node = this.created_nodes[id];
363            } else {   
364                var node = this.createElementNS(null, "node");
365            }
366            this.created_nodes[id] = node;
367            node.setAttribute("id", id);
368            node.setAttribute("lon", geometry.x); 
369            node.setAttribute("lat", geometry.y);
370            if (point.attributes) {
371                this.serializeTags(point, node);
372            }
373            this.setState(point, node);
374            return already_exists ? [] : [node];
375        }, 
376        linestring: function(feature) {
377            var nodes = [];
378            var geometry = feature.geometry;
379            if (feature.osm_id) {
380                id = feature.osm_id;
381            } else {
382               id = -this.osm_id;
383               this.osm_id++; 
384            }
385            var way = this.createElementNS(null, "way");
386            way.setAttribute("id", id);
387            for (var i = 0; i < geometry.components.length; i++) {
388                var node = this.createXML['point'].apply(this, [geometry.components[i]]);
389                if (node.length) {
390                    node = node[0];
391                    var node_ref = node.getAttribute("id");
392                    nodes.push(node);
393                } else {
394                    node_ref = geometry.components[i].osm_id;
395                    node = this.created_nodes[node_ref];
396                }
397                this.setState(feature, node);
398                var nd_dom = this.createElementNS(null, "nd");
399                nd_dom.setAttribute("ref", node_ref);
400                way.appendChild(nd_dom);
401            }
402            this.serializeTags(feature, way);
403            nodes.push(way);
404           
405            return nodes;
406        },
407        polygon: function(feature) {
408            var attrs = OpenLayers.Util.extend({'area':'yes'}, feature.attributes);
409            var feat = new OpenLayers.Feature.Vector(feature.geometry.components[0], attrs); 
410            feat.osm_id = feature.osm_id;
411            return this.createXML['linestring'].apply(this, [feat]);
412        }
413    },
414
415    /**
416     * Method: serializeTags
417     * Given a feature, serialize the attributes onto the given node.
418     *
419     * Parameters:
420     * feature - {<OpenLayers.Feature.Vector>}
421     * node - {DOMNode}
422     */
423    serializeTags: function(feature, node) {
424        for (var key in feature.attributes) {
425            var tag = this.createElementNS(null, "tag");
426            tag.setAttribute("k", key);
427            tag.setAttribute("v", feature.attributes[key]);
428            node.appendChild(tag);
429        }
430    },
431
432    /**
433     * Method: setState
434     * OpenStreetMap has a convention that 'state' is stored for modification or deletion.
435     * This allows the file to be uploaded via JOSM or the bulk uploader tool.
436     *
437     * Parameters:
438     * feature - {<OpenLayers.Feature.Vector>}
439     * node - {DOMNode}
440     */
441    setState: function(feature, node) {
442        if (feature.state) {
443            var state = null;
444            switch(feature.state) {
445                case OpenLayers.State.UPDATE:
446                    state = "modify";
447                case OpenLayers.State.DELETE:
448                    state = "delete";
449            }
450            if (state) {
451                node.setAttribute("action", state);
452            }
453        }   
454    },
455
456    CLASS_NAME: "OpenLayers.Format.OSM" 
457});     
Note: See TracBrowser for help on using the repository browser.