source: subversion/applications/utils/import/gml2osm/gml2osm.php @ 5763

Last change on this file since 5763 was 3721, checked in by isortega, 13 years ago

Added gml2osm import utility - use it when importing data from GML format.
It's able to reuse nodes/segments, and translates a subset of the EGM data dictionary into OSM map features.

File size: 5.8 KB
Line 
1<?php
2
3/**
4 * @file gml2osm
5 * @brief GML to OSM convertor
6 *
7 * This set of scripts can convert data from Geographic Markup Language (GML) to OpenStreetMap XML format (OSM).
8 *
9 * @version 0.2
10 * @date 2007-07-25
11 *
12 *
13 * Changelog:
14 * v0.2 - Added basic EGM metadata to OSM tags
15 * v0.1 - Basic Point, Linestring, MultiLinestring and MultiPolygon conversion to n/s/w.
16 */
17
18// proj4-based coordinate conversion wrapper
19include('cs2cs_wrapper.php');
20
21
22// aux. functions, to manage adding nodes/segments to the internal tables
23// main reason behind this is to not duplicate nodes nor segments.
24include('gml2osm_funcs.php');
25
26
27if ($argc < 4)
28{
29        echo "Usage: gml2osm.php infile namespace outfile\n";
30        echo "example: gml2osm.php foobar.gml foowfs foobar.osm\n";
31        echo "The namespace is dependant on the GML source; peek at the GML file to guess it. It's the only namespace not being 'gml','xlink' or 'wfs'.\n\n";
32        die();
33}
34
35
36
37
38/// TODO: add sanity check: does the input file exist?
39/// TODO: add variable arguments to specify custom tags to be added to every element (source tags, mostly)
40                   
41$file = $argv[1];
42$namespace = $argv[2];
43$outfile = $argv[3];
44
45
46// $filename gets printed on the tags, as source:file.
47$filename = $file;
48
49// The namespaces for features (featuremember) and tags (elements inside a featuremember) might be different in strange cases.
50$tags_namespace = $feature_namespace = $namespace;
51
52
53// ofd = Output File Descriptor
54$ofd = fopen($outfile,'w');
55
56
57$xml = simplexml_load_file($file);
58
59// print_r($xml);
60// print_r($xml->'gml:featureMember');
61
62
63fwrite($ofd, "<?xml version='1.0' encoding='UTF-8'?>
64<osm version='0.4' generator='ivansanchez_idee_importer'>");
65
66$namespaces   = $xml->getDocNamespaces();
67// print_r($xml_namespaces);
68/// FIXME: add error checking: the namespaces used in the tags should be declared!!
69/// TODO: This should detect any namespace different than xpath, gml and wfs.
70
71/// Every GML document puts all the data in a gml:featureList and gml:featureMembers ... So, every GML document we'll parse will have the 'gml' namespace declared.
72$xml_gml = $xml->children($namespaces['gml']);
73
74
75/// $feature  is a <featureMember>
76/// $feature2 is a <featureMember><custom>
77
78$element_id = 0;
79$way_tags = array();
80
81foreach ($xml_gml->featureMember as $feature)
82{
83        // Parse data:
84        /// TODO: one featuremember can have more than one piece of data inside??
85        $feature = $feature->children($namespaces[$feature_namespace]);
86       
87        foreach($feature as $featuretype=>$feature2)
88        {
89                $tags = array();
90                $mynodes= array();
91                $myways = array();
92
93                foreach($feature2 as $key=>$tag)
94                {
95                        if ($tag)       // Standard namespace data, add to tags
96                        {
97                                $tags["$tags_namespace:$key"] = (string) $tag;
98                        }
99                        else    // This might be an invisible SimpleXML object, containing the geometry.
100                        {
101                                $geometries = $tag->children($namespaces['gml']);
102                               
103                                foreach($geometries as $geom_type=>$geometry)
104                                {
105                                        if ($geom_type=='Point')
106                                        {
107                                                $mynodes[] = point2node($geometry);
108                                        }
109                                        else if ($geom_type=='LineString')
110                                        {
111                                                $myways[] = linestring2way($geometry);
112                                        }
113                                        else if ($geom_type=='MultiLineString')
114                                        {
115                                                foreach($geometry->lineStringMember as $linestringmember)
116                                                {
117                                                        $myways[] = linestring2way($linestringmember->LineString);
118                                                }
119                                        }
120                                        else if ($geom_type=='MultiPolygon')
121                                        {
122                                                foreach($geometry->polygonMember as $polygonMember)
123                                                {
124                                                        /// TODO: check that a linear ring is indeed a linear ring (a linestring that ends in its first point)
125                                                        /// TODO: Add support for inner rings
126                                                        /// TODO: merge segments from the inner rings into the outer ring, delete inner ring way IDs.
127                                                        /// TODO: check topology of polygons - we're supposing that they're just right.
128                                                        $myways[] = $outerring = linestring2way($polygonMember->Polygon->outerBoundaryIs->LinearRing);
129                                                }
130                                        }
131                                }
132                        }
133                }
134               
135               
136               
137                /// Generic gml-to-osm metadata-to-tags conversion
138                // Two generic conversions are done: everything in the $tags_namespace has already been added as a $namespace:$tag=$value tag, and every attribute in the GML nodes will be added as gml:$attr=$value.
139               
140                $attrs = $feature2->attributes($namespaces['gml']);
141               
142                foreach ($attrs as $key=>$attr)
143                {
144                        $tags["gml:$key"] = $attr;
145                }
146               
147                $tags['source:filename'] = $file;
148               
149                /// EuroGlobalMaps metadata conversion
150                include('gml2osm_egmtags.php');
151               
152               
153//              print_r($tags);
154               
155                // This may overwrite previously defined tags for that node!!!!!!!!
156                foreach($mynodes as $node_id)
157                {
158                        $node_tags[$node_id] = $tags;
159                }
160                foreach($myways as $way_id)
161                {
162                        print_r($myways);
163                        $way_tags[$way_id] = $tags;
164                }
165        }
166}
167
168
169
170// Everything has been parsed; now, let's output everything...
171
172
173// print_r($node_list);
174
175foreach($node_tags as $node_id=>$tags)
176{
177        $node_count++;
178        list($lat,$lon) = $node_coords[$node_id];
179        fwrite($ofd, "<node id='$node_id' visible='true' lat='$lat' lon='$lon' >\n");
180        foreach($tags as $k=>$tag)
181        {
182                $k   = htmlspecialchars($k);
183                $tag = htmlspecialchars($tag);
184                fwrite($ofd, "<tag k=\"$k\" v=\"$tag\" />\n");
185        }
186        fwrite($ofd, "</node>\n");
187}
188
189
190
191foreach($segment_list as $from=>$tos)
192{
193        $segment_count++;
194        foreach($tos as $to=>$segment_id)
195        {
196                fwrite($ofd, "<segment id='$segment_id' visible='true' from='$from' to='$to' />\n");
197        }
198}
199
200
201
202foreach($way_tags as $way_id=>$tags)
203{
204        $way_count++;
205        fwrite($ofd, "<way id='$way_id' visible='true'>\n");
206       
207        $segments_in_this_way = $way_list[$way_id];
208        foreach($segments_in_this_way as $segment_id)
209        {
210                fwrite($ofd, "<seg id='$segment_id'/>\n");
211        }
212       
213        foreach($tags as $k=>$tag)
214        {
215                $k   = htmlspecialchars($k);
216                $tag = htmlspecialchars($tag);
217                fwrite($ofd, "<tag k=\"$k\" v=\"$tag\" />\n");
218        }
219        fwrite($ofd, "</way>\n");
220}
221
222
223fwrite($ofd, "<!-- \nTotal:\nNodes: $node_count\nSegments: $segment_count\nWays:$way_count\n-->\n");
224
225
226
227
228fwrite($ofd, "\n</osm>\n");
229?>
Note: See TracBrowser for help on using the repository browser.