source: subversion/applications/rendering/wms/class.datafactory.php @ 8663

Last change on this file since 8663 was 8663, checked in by isortega, 11 years ago

WMS now features the 60 UTM zones and polar stereographic coordinate systems.

File size: 12.9 KB
Line 
1<?php
2
3/// @author Iván Sánchez Ortega <ivan@sanchezortega.es>
4
5/**
6    OSM WMS ("OpenStreetMap Web Map Service")
7    Copyright (C) 2008, Iván Sánchez Ortega
8
9    This program is free software: you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21*/   
22
23/// Data factory: ask this for some data in some projection, and the factory will ask the appropiate backend and (re)project it.
24
25
26class datafactory
27{
28       
29        static private $backend = 'backend_osmxapi';    /// Which backend to use. Valid values are "backend_api", "backend_osmxapi".
30        //static private $backend = 'backend_api';      /// Which backend to use. Valid values are "backend_api", "backend_osmxapi".
31       
32       
33        static public $available_crs = array('EPSG:4326' =>array(-180,-90,180,90)
34        ,'CRS:84'    =>array(-180,-90,180,90)
35       
36        // Infamous "google" projection
37        ,'EPSG:900913'=>array(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
38       
39        // UTM zones, WGS 84
40        ,'EPSG:32601'=>array(-1500000,0,1500000,10000000)       // UTM 1 N
41        ,'EPSG:32602'=>array(-1500000,0,1500000,10000000)       // UTM 2 N
42        ,'EPSG:32603'=>array(-1500000,0,1500000,10000000)       // UTM 3 N
43        ,'EPSG:32604'=>array(-1500000,0,1500000,10000000)       // UTM 4 N
44        ,'EPSG:32605'=>array(-1500000,0,1500000,10000000)       // UTM 5 N
45        ,'EPSG:32606'=>array(-1500000,0,1500000,10000000)       // UTM 6 N
46        ,'EPSG:32607'=>array(-1500000,0,1500000,10000000)       // UTM 7 N
47        ,'EPSG:32608'=>array(-1500000,0,1500000,10000000)       // UTM 8 N
48        ,'EPSG:32609'=>array(-1500000,0,1500000,10000000)       // UTM 9 N
49        ,'EPSG:32610'=>array(-1500000,0,1500000,10000000)       // UTM 10 N
50        ,'EPSG:32611'=>array(-1500000,0,1500000,10000000)       // UTM 11 N
51        ,'EPSG:32612'=>array(-1500000,0,1500000,10000000)       // UTM 12 N
52        ,'EPSG:32613'=>array(-1500000,0,1500000,10000000)       // UTM 13 N
53        ,'EPSG:32614'=>array(-1500000,0,1500000,10000000)       // UTM 14 N
54        ,'EPSG:32615'=>array(-1500000,0,1500000,10000000)       // UTM 15 N
55        ,'EPSG:32616'=>array(-1500000,0,1500000,10000000)       // UTM 16 N
56        ,'EPSG:32617'=>array(-1500000,0,1500000,10000000)       // UTM 17 N
57        ,'EPSG:32618'=>array(-1500000,0,1500000,10000000)       // UTM 18 N
58        ,'EPSG:32619'=>array(-1500000,0,1500000,10000000)       // UTM 19 N
59        ,'EPSG:32620'=>array(-1500000,0,1500000,10000000)       // UTM 20 N
60        ,'EPSG:32621'=>array(-1500000,0,1500000,10000000)       // UTM 21 N
61        ,'EPSG:32622'=>array(-1500000,0,1500000,10000000)       // UTM 22 N
62        ,'EPSG:32623'=>array(-1500000,0,1500000,10000000)       // UTM 23 N
63        ,'EPSG:32624'=>array(-1500000,0,1500000,10000000)       // UTM 24 N
64        ,'EPSG:32625'=>array(-1500000,0,1500000,10000000)       // UTM 25 N
65        ,'EPSG:32626'=>array(-1500000,0,1500000,10000000)       // UTM 26 N
66        ,'EPSG:32627'=>array(-1500000,0,1500000,10000000)       // UTM 27 N
67        ,'EPSG:32628'=>array(-1500000,0,1500000,10000000)       // UTM 28 N
68        ,'EPSG:32629'=>array(-1500000,0,1500000,10000000)       // UTM 29 N
69        ,'EPSG:32630'=>array(-1500000,0,1500000,10000000)       // UTM 30 N
70        ,'EPSG:32631'=>array(-1500000,0,1500000,10000000)       // UTM 31 N
71        ,'EPSG:32632'=>array(-1500000,0,1500000,10000000)       // UTM 32 N
72        ,'EPSG:32633'=>array(-1500000,0,1500000,10000000)       // UTM 33 N
73        ,'EPSG:32634'=>array(-1500000,0,1500000,10000000)       // UTM 34 N
74        ,'EPSG:32635'=>array(-1500000,0,1500000,10000000)       // UTM 35 N
75        ,'EPSG:32636'=>array(-1500000,0,1500000,10000000)       // UTM 36 N
76        ,'EPSG:32637'=>array(-1500000,0,1500000,10000000)       // UTM 37 N
77        ,'EPSG:32638'=>array(-1500000,0,1500000,10000000)       // UTM 38 N
78        ,'EPSG:32639'=>array(-1500000,0,1500000,10000000)       // UTM 39 N
79        ,'EPSG:32640'=>array(-1500000,0,1500000,10000000)       // UTM 40 N
80        ,'EPSG:32641'=>array(-1500000,0,1500000,10000000)       // UTM 41 N
81        ,'EPSG:32642'=>array(-1500000,0,1500000,10000000)       // UTM 42 N
82        ,'EPSG:32643'=>array(-1500000,0,1500000,10000000)       // UTM 43 N
83        ,'EPSG:32644'=>array(-1500000,0,1500000,10000000)       // UTM 44 N
84        ,'EPSG:32645'=>array(-1500000,0,1500000,10000000)       // UTM 45 N
85        ,'EPSG:32646'=>array(-1500000,0,1500000,10000000)       // UTM 46 N
86        ,'EPSG:32647'=>array(-1500000,0,1500000,10000000)       // UTM 47 N
87        ,'EPSG:32648'=>array(-1500000,0,1500000,10000000)       // UTM 48 N
88        ,'EPSG:32649'=>array(-1500000,0,1500000,10000000)       // UTM 49 N
89        ,'EPSG:32650'=>array(-1500000,0,1500000,10000000)       // UTM 50 N
90        ,'EPSG:32651'=>array(-1500000,0,1500000,10000000)       // UTM 51 N
91        ,'EPSG:32652'=>array(-1500000,0,1500000,10000000)       // UTM 52 N
92        ,'EPSG:32653'=>array(-1500000,0,1500000,10000000)       // UTM 53 N
93        ,'EPSG:32654'=>array(-1500000,0,1500000,10000000)       // UTM 54 N
94        ,'EPSG:32655'=>array(-1500000,0,1500000,10000000)       // UTM 55 N
95        ,'EPSG:32656'=>array(-1500000,0,1500000,10000000)       // UTM 56 N
96        ,'EPSG:32657'=>array(-1500000,0,1500000,10000000)       // UTM 57 N
97        ,'EPSG:32658'=>array(-1500000,0,1500000,10000000)       // UTM 58 N
98        ,'EPSG:32659'=>array(-1500000,0,1500000,10000000)       // UTM 59 N
99        ,'EPSG:32660'=>array(-1500000,0,1500000,10000000)       // UTM 60 N
100       
101        ,'EPSG:32701'=>array(-1500000,0,1500000,10000000)       // UTM 1 S
102        ,'EPSG:32702'=>array(-1500000,0,1500000,10000000)       // UTM 2 S
103        ,'EPSG:32703'=>array(-1500000,0,1500000,10000000)       // UTM 3 S
104        ,'EPSG:32704'=>array(-1500000,0,1500000,10000000)       // UTM 4 S
105        ,'EPSG:32705'=>array(-1500000,0,1500000,10000000)       // UTM 5 S
106        ,'EPSG:32706'=>array(-1500000,0,1500000,10000000)       // UTM 6 S
107        ,'EPSG:32707'=>array(-1500000,0,1500000,10000000)       // UTM 7 S
108        ,'EPSG:32708'=>array(-1500000,0,1500000,10000000)       // UTM 8 S
109        ,'EPSG:32709'=>array(-1500000,0,1500000,10000000)       // UTM 9 S
110        ,'EPSG:32710'=>array(-1500000,0,1500000,10000000)       // UTM 10 S
111        ,'EPSG:32711'=>array(-1500000,0,1500000,10000000)       // UTM 11 S
112        ,'EPSG:32712'=>array(-1500000,0,1500000,10000000)       // UTM 12 S
113        ,'EPSG:32713'=>array(-1500000,0,1500000,10000000)       // UTM 13 S
114        ,'EPSG:32714'=>array(-1500000,0,1500000,10000000)       // UTM 14 S
115        ,'EPSG:32715'=>array(-1500000,0,1500000,10000000)       // UTM 15 S
116        ,'EPSG:32716'=>array(-1500000,0,1500000,10000000)       // UTM 16 S
117        ,'EPSG:32717'=>array(-1500000,0,1500000,10000000)       // UTM 17 S
118        ,'EPSG:32718'=>array(-1500000,0,1500000,10000000)       // UTM 18 S
119        ,'EPSG:32719'=>array(-1500000,0,1500000,10000000)       // UTM 19 S
120        ,'EPSG:32720'=>array(-1500000,0,1500000,10000000)       // UTM 20 S
121        ,'EPSG:32721'=>array(-1500000,0,1500000,10000000)       // UTM 21 S
122        ,'EPSG:32722'=>array(-1500000,0,1500000,10000000)       // UTM 22 S
123        ,'EPSG:32723'=>array(-1500000,0,1500000,10000000)       // UTM 23 S
124        ,'EPSG:32724'=>array(-1500000,0,1500000,10000000)       // UTM 24 S
125        ,'EPSG:32725'=>array(-1500000,0,1500000,10000000)       // UTM 25 S
126        ,'EPSG:32726'=>array(-1500000,0,1500000,10000000)       // UTM 26 S
127        ,'EPSG:32727'=>array(-1500000,0,1500000,10000000)       // UTM 27 S
128        ,'EPSG:32728'=>array(-1500000,0,1500000,10000000)       // UTM 28 S
129        ,'EPSG:32729'=>array(-1500000,0,1500000,10000000)       // UTM 29 S
130        ,'EPSG:32730'=>array(-1500000,0,1500000,10000000)       // UTM 30 S
131        ,'EPSG:32731'=>array(-1500000,0,1500000,10000000)       // UTM 31 S
132        ,'EPSG:32732'=>array(-1500000,0,1500000,10000000)       // UTM 32 S
133        ,'EPSG:32733'=>array(-1500000,0,1500000,10000000)       // UTM 33 S
134        ,'EPSG:32734'=>array(-1500000,0,1500000,10000000)       // UTM 34 S
135        ,'EPSG:32735'=>array(-1500000,0,1500000,10000000)       // UTM 35 S
136        ,'EPSG:32736'=>array(-1500000,0,1500000,10000000)       // UTM 36 S
137        ,'EPSG:32737'=>array(-1500000,0,1500000,10000000)       // UTM 37 S
138        ,'EPSG:32738'=>array(-1500000,0,1500000,10000000)       // UTM 38 S
139        ,'EPSG:32739'=>array(-1500000,0,1500000,10000000)       // UTM 39 S
140        ,'EPSG:32740'=>array(-1500000,0,1500000,10000000)       // UTM 40 S
141        ,'EPSG:32741'=>array(-1500000,0,1500000,10000000)       // UTM 41 S
142        ,'EPSG:32742'=>array(-1500000,0,1500000,10000000)       // UTM 42 S
143        ,'EPSG:32743'=>array(-1500000,0,1500000,10000000)       // UTM 43 S
144        ,'EPSG:32744'=>array(-1500000,0,1500000,10000000)       // UTM 44 S
145        ,'EPSG:32745'=>array(-1500000,0,1500000,10000000)       // UTM 45 S
146        ,'EPSG:32746'=>array(-1500000,0,1500000,10000000)       // UTM 46 S
147        ,'EPSG:32747'=>array(-1500000,0,1500000,10000000)       // UTM 47 S
148        ,'EPSG:32748'=>array(-1500000,0,1500000,10000000)       // UTM 48 S
149        ,'EPSG:32749'=>array(-1500000,0,1500000,10000000)       // UTM 49 S
150        ,'EPSG:32750'=>array(-1500000,0,1500000,10000000)       // UTM 50 S
151        ,'EPSG:32751'=>array(-1500000,0,1500000,10000000)       // UTM 51 S
152        ,'EPSG:32752'=>array(-1500000,0,1500000,10000000)       // UTM 52 S
153        ,'EPSG:32753'=>array(-1500000,0,1500000,10000000)       // UTM 53 S
154        ,'EPSG:32754'=>array(-1500000,0,1500000,10000000)       // UTM 54 S
155        ,'EPSG:32755'=>array(-1500000,0,1500000,10000000)       // UTM 55 S
156        ,'EPSG:32756'=>array(-1500000,0,1500000,10000000)       // UTM 56 S
157        ,'EPSG:32757'=>array(-1500000,0,1500000,10000000)       // UTM 57 S
158        ,'EPSG:32758'=>array(-1500000,0,1500000,10000000)       // UTM 58 S
159        ,'EPSG:32759'=>array(-1500000,0,1500000,10000000)       // UTM 59 S
160        ,'EPSG:32760'=>array(-1500000,0,1500000,10000000)       // UTM 60 S
161       
162        // Universal Polar Stereographic (WGS 84)
163        ,'EPSG:32661'=>array(-4000000,-4000000,4000000,-4000000)        // UPS north
164        ,'EPSG:32761'=>array(-4500000,-4000000,4000000,-4000000)        // UPS south
165);
166       
167       
168       
169
170        /**
171         * @param bbox  A bounding box, as requested via WMS
172         * @param crs   The Coordinate Reference System as requested via WMS. EPSG:3426 and CRS:84 are unprojected, any other has to be reprojected.
173         * @param nodes A reference to an arrays of nodes, which will be filled up with data.
174         * @param ways  A reference to an array of ways, which will be filled up with data.
175         *
176         * TODO: refactor the check for non-numeric bbox elements; the only entry point for the data requests is this datagactory method, so the backends shouldn't have to check for this.
177         */
178        static function get_parsed_data($bbox,$crs,&$nodes,&$ways)
179        {
180                $backend = new self::$backend;
181               
182//              var_dump($backend);
183
184                // If the CRS is not WPSG:4326 or CRS:84, then the bbox has to be reprojected in order for the backends to fetch the appropiate set of data.
185                if ($crs != 'EPSG:4326' && $crs != 'CRS:84')
186                {
187                        list($left,$bottom,$right,$top) = explode(',',$bbox);
188               
189                        if ( !is_numeric($left) ||
190                        !is_numeric($bottom) ||
191                        !is_numeric($right) ||
192                        !is_numeric($top))
193                                trigger_error("Coordinates of the bounding box are not numbers!",E_USER_ERROR);
194                       
195                        // cs2cs gets numbers in an x-y fashion...
196                        $corners = array ('UL' => array( $left , $top    )
197                                         ,'UR' => array( $right, $top    )
198                                         ,'BR' => array( $right, $bottom )
199                                         ,'BL' => array( $left , $bottom )
200                                         );
201                       
202                        /// TODO: check that the target CRS is valid (i.e. in the array of available CRSs)
203                        self::cs2cs($corners,strtolower($crs));
204                       
205//                      var_dump($corners);
206//                      $bbox = "$left,$bottom,$right,$top";
207                       
208                        // Get the min and max latitudes and longitudes
209                        foreach($corners as $corner)
210                        {
211                                list ($lon,$lat) = $corner;
212                                if (!isset($east))      // Init from the first set of coords
213                                {
214                                        $east = $west = $lon;
215                                        $south = $north = $lat;
216                                }
217                                else    // check maximums
218                                {
219                                        if ($lon > $west)  $west  = $lon;
220                                        if ($lon < $east)  $east  = $lon;
221                                        if ($lat > $north) $north = $lat;
222                                        if ($lat < $south) $south = $lat;
223                                }
224                        }
225                        $bbox = "$east,$south,$west,$north";
226                       
227                        $backend->get_parsed_data($bbox,&$nodes,&$ways);
228                       
229//                      var_dump($bbox,$nodes);
230                        // Now, convert back all nodes' coordinates to the requested CRS...
231                       
232                        self::cs2cs($nodes,'epsg:4326',strtolower($crs),true);
233                       
234//                      var_dump($bbox,$nodes);
235                }
236                else
237                {
238                        // Requested a CRS native to the backends, just get the data...
239                       
240                        $backend->get_parsed_data($bbox,&$nodes,&$ways);
241                       
242                }
243               
244               
245               
246        }
247       
248       
249       
250       
251
252/*      function cs2cs($x,$y,$srs_in='epsg:4258',$srs_out='epsg:4326')
253        {
254                $r = shell_exec("echo \"$x $y\" | cs2cs -f %.20f +init=$srs_in +to +init=$srs_out");
255                sscanf($r,"%f %f",$x,$y);
256                return (array($x,$y));
257        }*/
258               
259        function cs2cs(& $points,$srs_in='epsg:4326',$srs_out='epsg:4326',$invert_input=false)
260        {
261                // Open some pipes to a "cs2cs" process, feed the points, parse the resulting points...
262       
263                $descriptorspec = array(
264                        0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
265                        1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
266                        2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
267                );
268               
269                $cwd = '/tmp';
270                $env = array();
271               
272                if ($invert_input)      $invert_flag = " -r -s"; else $invert_flag = '';
273               
274                $process = proc_open("cs2cs -f %.20f +init=$srs_in +to +init=$srs_out $invert_flag", $descriptorspec, $pipes, $cwd, $env);
275               
276//              $result = array();
277                if (is_resource($process)) {
278                       
279                        foreach($points as $id=>$point)
280                        {
281                                list($x,$y) = $point;
282                                fwrite($pipes[0], "$x $y\n");
283//                              echo "Point $id ($x,$y) passed to cs2cs\n"; ob_flush();
284                        }
285                        fclose($pipes[0]);
286                       
287                        foreach($points as $id=>$point)
288                        {
289//                              echo "Recovering point $id\n"; ob_flush();
290                                fscanf($pipes[1], "%f %f\n", $x2, $y2);
291                                $points[$id] = array( $x2 , $y2 );
292                        }
293                       
294                        fclose($pipes[1]);
295                }
296       
297//              return ($result);
298        }
299
300       
301}
302
303
304
305
Note: See TracBrowser for help on using the repository browser.