hey, it really works
[mediawiki.git] / experiments / geo / geo.php
blob420984ec52a3c1ef407db1f4ed1892eb4d834158
1 <?
3 $a = array (
5 "germany.bavaria/bw" => "!data:484627,092026 484900,092638 485407,092842 485407,093801 490146,092945 490329,094006 490146,094720 485640,094720 485822,095333 485549,095741 484718,100048 484354,100456 484536,101109 484212,101517 483341,101619 482146,101824 481639,102130 481224,102640 480302,103355 474925,103457 474509,102743 474600,102538 474145,102640 473456,102640 473041,101619 473041,101415 472535,101007 471339,101619 470053,101721 465314,101721 464443,101517 463521,101619 463521,100558 463521,095639 463014,094822",
6 "germany.bavaria/hesse" => "!data:484900,091923 485407,091821 490004,092026 490926,091617 492212,091107 492537,092026 492628,093251 492537,094108 493316,094006 493458,094720 493914,095231 494745,095537 494602,100252 495251,100905",
7 "germany.bavaria/thuringia" => "!data:495615,101109 495615,101926 494602,102947 494329,103804 493407,104008 493641,105131 494238,104620 494602,105335 494420,110805 493914,111111 494238,111622 495200,111417 495524,112132 494927,112541 494602,112949 494927,115031",
8 "germany.bavaria/saxony" => "!data:494602,115235 494329,115644 494056,120256",
9 "germany.bavaria/east" => "!data:493549,120154 492901,120909 492121,122134 491433,122747 490329,121930 484212,123604 483756,125033 482834,130054 482328,131013 481224,132137 481224,132749 480626,133912 475431,134321 474236,133810 474509,132545 473912,132443 472950,132034 472352,131115 472210,125952 471613,125238 471015,124625 470418,125340 465405,125850 464352,130054 464301,130401 463936,130605 462832,130401",
10 "germany.bavaria/south" => "!data:462832,130401 463014,125238 463754,125135 464118,124319 463703,123502 464118,122747 463936,121930 464443,121828 464118,121317 463430,121726 463157,115542 463157,114316 462741,114010 462650,113153 462235,113255 462001,112336 462235,111928 461910,111315 462001,110458 462650,110152 463014,104620 462650,104110 463014,103559 462235,103804 461910,103804 460949,102436 460806,101926 461455,102334 461404,101721 462001,101517 462650,100150 462923,095844 462508,095639 462741,095027",
12 "germany.bw/south" => "!data:463014,094312 463521,093659 463703,092945 464716,091617 463521,092332 464210,091107 463703,091311 463339,090658 463936,085943 463936,085535 464210,085535 464352,084922 464301,084106 463612,084003 463339,084310 463612,085229 463106,084922 462923,084106 462923,083351 463248,083147 463106,082330 462832,082125 462650,081513 462650,081207 463106,080656 462650,075737",
13 "germany.bw/west" => "!data:463703,074920 464807,075022 465820,075329 470509,075124 472210,075941 473132,080248 474145,080758 475107,081615 475704,082228 480717,082738",
14 "germany.bw/rp" => "!data:480808,083044 481639,083759 482743,084514 483847,084412 483847,084208 484900,084003",
15 "germany.bw/hesse" => "!data:484951,084106 484536,084922 485042,085024 485133,085535 484536,085535 484445,090352 483847,090556 484718,091719",
17 "germany.nrw/west" => "!data:515435,072940 514747,072021 514240,071306 513734,072021 513045,071409 513045,065531 513136,064305 512903,063244 511850,063551 510928,064305 510057,064612 504447,063857 504356,064305 503252,062529 502745,063346 502006,063551 501641,063142 501044,063755 500304,064612 495758,064101 495342,064816 494836,064918 494511,065122",
18 "germany.nrw/rp" => "!data:494602,065020 494511,065428 494420,065939 494420,070552 494420,071409 495109,071000 495524,071306 495109,071715 495342,071919 495524,072021 500213,073655 500810,074614 500953,075022 501226,075941 501732,080350 502421,080656 502006,081207 501641,081411 501459,081717 500902,082023 500537,082432",
19 "germany.nrw/hesse" => "!data:500628,082534 500902,082636 501317,082738 502006,083555 501732,084208 502148,084514 503252,084718 503343,085127 503434,085943 504214,085841 504538,085943 504538,085229 504811,085024 505409,085637 505551,090902 510148,090800 510422,091719 505733,091923 510057,092740 511110,093353",
20 "germany.nrw/ns" => "!data:511343,093353 511941,093251 512812,093801 512903,093047 513551,092434 514604,092230 514656,091413 515344,091719 515526,091107 520033,091617 520448,091923 521228,091821 520630,090902 520357,090148 521319,085739 521319,085331 520904,083901 520306,084310 515344,084514 514929,084616 514422,083555 514240,082228 514149,081819 514422,081615 514838,082125 515111,081615 515800,082023 520357,081717 520306,080900 520955,080145 520448,080145 520124,075431 515617,074308 515526,073144",
22 "germany.mv/brandenburg" => "!data:531619,134729 531710,134219 531345,134014 531254,133056 532125,133708 532307,133606 532358,133056 532358,132239 533138,131524 532632,131218 532358,130911 532034,130259 531437,130401 531203,125748 530839,124931 530606,123706 530424,122441 530839,120909 531528,114827 531021,114623 530606,113255 530606,112438 530059,112336 525644,112336 525917,111724 525644,110907",
23 "germany.mv/ns" => "!data:525644,110907 525826,110356 531203,105029 530839,104723 531203,103559",
24 "germany.mv/sh" => "!data:531203,103559 531943,103804 532632,104518 532905,105131 533502,105131 533736,104518 534424,104110 534840,104314 535255,104825",
25 "germany.mv/north-east" => "!data:535346,104825 535619,105437 535710,110152 535619,110601 535255,111417 535802,111724 540906,112438 540906,113153 542101,115542 543256,120705 543529,122849 544400,123604 545048,124727 544218,125135 544400,130054 543944,130259 543205,125952 542658,130911 542152,130605 542607,125646 542101,124931 541503,124727 541048,125544 541412,130707 541230,131830 540632,132953 535853,133300 535204,131932 534606,133606 532125,134627",
27 "germany.mv" => "
28 !type[political]:state
29 !name[de]:Mecklenburg-Vorpommern
30 !name[en]:Mecklenburg-Western Pomerania
31 !region[political]:
32 polygon(germany.mv/brandenburg,germany.mv/ns,germany.mv/sh,germany.mv/north-east)
35 "germany.nrw" => "
36 !type[political]:state
37 !name[de]:Nordrhein-Westphalen
38 !name[en]:North Rhine-Westphalia
39 !region[political]:
40 polygon(germany.nrw/west,germany.nrw/rp,germany.nrw/hesse,germany.nrw/ns)
43 "germany.bavaria" => "
44 !type[political]:state
45 !name[de]:Bayern
46 !name[en]:Bavaria
47 !region[political]:
48 polygon(germany.bavaria/hesse,germany.bavaria/thuringia,germany.bavaria/saxony,germany.bavaria/east,germany.bavaria/south,germany.bavaria/bw)
51 "germany.bw" => "
52 !type[political]:state
53 !name[de]:Baden-Württemberg
54 !name[en]:Baden-Württemberg
55 !region[political]:
56 polygon(germany.bavaria/bw,germany.bw/south,germany.bw/west,germany.bw/rp,germany.bw/hesse)
59 "germany" => "
60 !type[political]:country
61 !name[de]:Deutschland
62 !name[en]:Germany
63 !region[political]:
64 addregs(germany.bavaria,germany.bw,germany.nrw,germany.mv)
67 "danube" => "
68 !type:river
69 !region:polyline(danube_germany,danube_austria)
70 " ,
72 "danube_germany" =>"!data:120,350 180,250 200,290" ,
73 "danube_austria" =>"!data:220,350 250,320 300,370" ,
75 ) ;
77 include_once ( "geo_functions.php" ) ;
79 # Global, evil variables
80 $min_x = $min_y = 1000000 ;
81 $max_x = $max_y = -1000000 ;
83 # Global functions
84 function geo_get_text ( $id )
86 global $a ;
87 return $a[$id] ;
90 function data_to_real ( &$x , &$y )
92 $x = coordinate_to_number ( coordinate_take_apart ( $x ) ) ;
93 $y = coordinate_to_number ( coordinate_take_apart ( $y ) ) ;
95 $z = $x ; $x = $y ; $y = $z ;
96 $y = 90 * 3600 - $y ;
98 // $x /= 100 ;
99 // $y /= 100 ;
101 # Recording min and max
102 global $min_x , $min_y , $max_x , $max_y ;
103 $min_x = min ( $min_x , $x ) ;
104 $min_y = min ( $min_y , $y ) ;
105 $max_x = max ( $max_x , $x ) ;
106 $max_y = max ( $max_y , $y ) ;
110 # geo paramaters
111 class geo_params
113 var $labels = array () ;
115 function add_label ( $text_array )
117 $this->labels[] = $text_array ;
120 function get_svg_labels ()
122 $ret = "" ;
123 foreach ( $this->labels AS $l )
125 $text = $l['text'] ;
126 $x = $l['x'] ;
127 $y = $l['y'] ;
128 $s = "<text style='" ;
129 $fs = $l['font-size'] ;
130 if ( $fs == "medium" ) $fs = "1000" ;
131 if ( $fs == "" ) $fs = "800" ;
133 $p = array() ;
134 $p[] = "text-anchor:middle" ;
135 $p[] = "fill-opacity:0.7" ;
136 $p[] = "font-size:{$fs}pt" ;
137 $s .= implode ( ";" , $p ) ;
139 $s .= "' x='{$x}' y='{$y}'>{$text}</text>\n" ;
140 $ret .= $s ;
141 # $ret = "<text style='font-size:1000pt;text-anchor:middle;fill-opacity:0.7' x='{$x}' y='{$y}'>{$text}</text>\n" ;
143 return $ret ;
147 # "geo" class
148 class geo
150 var $data = array () ;
151 var $xsum , $ysum , $count ;
153 function set_from_text ( $t )
155 $t = explode ( "\n!" , "\n".$t ) ;
156 $this->data = array () ;
157 foreach ( $t AS $x )
159 $b = explode ( ":" , $x , 2 ) ;
160 while ( count ( $b ) < 2 ) $b[] = "" ;
161 $key = strtolower ( str_replace ( " " , "" , array_shift ( $b ) ) ) ;
162 $key = str_replace ( "\n" , "" , $key ) ;
163 $value = trim ( str_replace ( "\n" , "" , array_shift ( $b ) ) ) ;
164 $value = explode ( ";" , $value ) ;
165 if ( $key != "" ) $this->data[$key] = $value ;
169 function set_from_id ( $id )
171 $this->set_from_text ( geo_get_text ( $id ) ) ;
174 function get_data ()
176 $ret = array () ;
177 if ( !isset ( $this->data["data"] ) ) return $ret ; # No data in this set
178 $data = $this->data["data"] ;
179 $data = array_shift ( $data ) ;
180 $data = explode ( " " , $data ) ;
181 foreach ( $data AS $a )
183 $a = explode ( "," , $a ) ;
184 if ( count ( $a ) == 2 )
186 $x = trim ( array_shift ( $a ) ) ;
187 $y = trim ( array_shift ( $a ) ) ;
188 data_to_real ( $x , $y ) ;
189 $ret[] = array ( $x , $y ) ;
192 return $ret ;
195 function add_reordered_data ( &$original , &$toadd )
197 if ( count ( $toadd ) == 0 ) return ; # Nothing to add
198 if ( count ( $original ) == 0 )
200 $original = $toadd ;
201 return ;
204 $o_last = array_pop ( $original ) ; array_push ( $original , $o_last ) ; # Get last one and restore
205 $t_last = array_pop ( $toadd ) ; array_push ( $toadd , $t_last ) ; # Get last one and restore
206 $t_first = array_shift ( $toadd ) ; array_unshift ( $toadd , $t_first ) ; # Get first one and restore
208 $dist_to_first = ( $o_last[0] - $t_first[0] ) * ( $o_last[0] - $t_first[0] ) +
209 ( $o_last[1] - $t_first[1] ) * ( $o_last[1] - $t_first[1] ) ;
211 $dist_to_last = ( $o_last[0] - $t_last[0] ) * ( $o_last[0] - $t_last[0] ) +
212 ( $o_last[1] - $t_last[1] ) * ( $o_last[1] - $t_last[1] ) ;
214 if ( $dist_to_last < $dist_to_first ) # If the last point of toadd is closer than the fist one,
215 $toadd = array_reverse ( $toadd ) ; # add in other direction
217 $original = array_merge ( $original , $toadd ) ;
220 function get_specs ( $base , $modes )
222 foreach ( $modes AS $x )
224 if ( isset ( $this->data["{$base}[{$x}]"] ) )
225 return "{$base}[{$x}]" ;
227 if ( isset ( $this->data[$base] ) )
228 return $base ;
229 return "" ;
232 function get_current_type ( &$params ) # params may override native type
234 $t = $this->get_specs ( "type" , array ( "political" ) ) ;
235 if ( $t != "" ) $t = $this->data[$t][0] ;
236 return $t ;
239 function get_current_style ( &$params )
241 $t = trim ( strtolower ( $this->get_current_type ( $params ) ) ) ;
242 if ( $t == "river" ) $s = "fill:none; stroke:blue; stroke-width:2" ;
243 else $s = "fill:brown; stroke:black; stroke-width:1" ;
244 return "style=\"{$s}\"" ;
247 function draw_line ( $line , &$params )
249 $ret = "" ;
250 $a = explode ( "(" , $line , 2 ) ;
251 while ( count ( $a ) < 2 ) $a[] = "" ;
252 $command = trim ( strtolower ( array_shift ( $a ) ) ) ;
253 $values = trim ( str_replace ( ")" , "" , array_shift ( $a ) ) ) ;
254 # print "Evaluating command {$line}\n" ;
255 if ( $command == "addregs" || $command == "include" )
257 $values = explode ( "," , $values ) ;
258 foreach ( $values AS $v )
260 $v = trim ( strtolower ( $v ) ) ;
261 $ng = new geo ;
262 $ng->set_from_id ( $v ) ;
263 $ret .= $ng->draw ( $params ) ;
266 else if ( $command == "polygon" || $command == "polyline" )
268 $data = array () ;
269 $values = explode ( "," , $values ) ;
270 foreach ( $values AS $v )
272 $v = trim ( strtolower ( $v ) ) ;
273 $ng = new geo ;
274 $ng->set_from_id ( $v ) ;
275 $b = $ng->get_data () ;
276 $this->add_reordered_data ( $data , $b ) ;
279 $style = $this->get_current_style ( $params ) ;
280 if ( $command == "polygon" ) $ret .= "<polygon {$style} points=\"" ;
281 if ( $command == "polyline" ) $ret .= "<polyline {$style} points=\"" ;
282 foreach ( $data AS $a )
284 $x = $a[0] ;
285 $y = $a[1] ;
286 // data_to_real ( $x , $y ) ;
287 $this->xsum += $x ;
288 $this->ysum += $y ;
289 $this->count++ ;
290 $ret .= "{$x},{$y} " ;
292 $ret = trim ( $ret ) . "\"/>\n" ;
295 return $ret ;
298 function add_label ( $x , $y , &$params )
300 $text = $this->get_specs ( "name" , array ( "de" ) ) ;
301 if ( $text == "" ) return "" ;
302 $text = utf8_decode ( $this->data[$text][0] ) ;
303 $x = floor ( $x ) ;
304 $y = floor ( $y ) ;
306 $a = array ( "text" => $text , "x" => $x , "y" => $y , "font-size" => "medium" ) ;
307 $params->add_label ( $a ) ;
310 function draw ( &$params )
312 $ret = "" ;
313 $this->xsum = $this->ysum = $this->count = 0 ;
314 $match = $this->get_specs ( "region" , array ( "political" ) ) ;
315 if ( $match != "" )
317 $a = $this->data[$match] ;
318 foreach ( $a AS $line )
319 $ret .= $this->draw_line ( $line , $params ) ;
321 if ( $this->count > 0 )
323 $x = $this->xsum / $this->count ;
324 $y = $this->ysum / $this->count ;
325 $this->add_label ( $x , $y , $params ) ;
327 return $ret ;
332 $g = new geo ;
333 $g->set_from_id ( "germany" ) ;
335 $p = new geo_params ;
336 $svg = $g->draw ( $p ) ;
337 $svg .= $p->get_svg_labels () ;
339 $styles = "" ;
341 $styles = ' <defs>
342 <style type="text/css"><![CDATA[
343 .stuff {fill:none; stroke:blue; stroke-width:2}
344 ]]></style>
345 </defs>
349 $width = $max_x - $min_x ;
350 $height = $max_y - $min_y ;
351 $min_x -= $width / 10 ;
352 $min_y -= $height / 10 ;
353 $max_x += $width / 10 ;
354 $max_y += $height / 10 ;
356 $max_x -= $min_x ;
357 $max_y -= $min_y ;
359 $svg =
360 '<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
361 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd">
362 <svg viewBox="' . "{$min_x} {$min_y} {$max_x} {$max_y}" .
363 '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
365 . $styles .
366 ' <g id="mainlayer">
368 . $svg .
369 '</g>
370 </svg>
373 print $svg ;