source: extensions/rv_gmaps/trunk/include/functions_map.php @ 22180

Last change on this file since 22180 was 22180, checked in by rvelices, 12 years ago

rv_gmaps: more forgiving about some wrong exif gps formatting + small technical stuff

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 14.2 KB
Line 
1<?php
2/* Reminder about urls
3map      unused but passes flat to map_data ...
4map_data automatic show flat, start is unused
5mapl     automatic show flat, start is used in GET only (blowup)
6kml      if flat network links, start is unused*/
7
8function rvm_get_config_file_name()
9{
10  global $page, $conf;
11  unset( $page['__rvm_config__'] );
12  return PHPWG_ROOT_PATH.$conf['data_location'].'/plugins/'.basename(dirname(dirname(__FILE__))).'.dat';
13}
14
15function rvm_get_config()
16{
17  global $page;
18  if (isset($page['__rvm_config__']))
19    return $page['__rvm_config__'];
20  $x = @file_get_contents( rvm_get_config_file_name() );
21  if ($x!==false)
22    $page['__rvm_config__'] = unserialize($x);
23  if ( !is_array(@$page['__rvm_config__']) )
24    $page['__rvm_config__'] = array();
25  return $page['__rvm_config__'];
26}
27
28function rvm_get_config_var($var, $default)
29{
30  global $page;
31  if (!isset($page['__rvm_config__']))
32    rvm_get_config();
33  if ( array_key_exists($var,$page['__rvm_config__']) )
34    return $page['__rvm_config__'][$var];
35  return $default;
36}
37
38function rvm_parse_map_data_url($tokens, &$next_token)
39{
40  $page = parse_section_url($tokens, $next_token);
41  if ( !isset($page['section']) )
42    $page['section'] = 'categories';
43
44  $page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
45  $page['start']=0;
46  $page['box'] = rvm_bounds_from_url( @$_GET['box'] );
47  return $page;
48}
49
50function rvm_parse_kml_url($tokens, &$next_token)
51{
52  $page = parse_section_url($tokens, $next_token);
53  if ( !isset($page['section']) )
54    $page['section'] = 'categories';
55
56  $page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
57  $page['start']=0;
58  $page['box'] = rvm_bounds_from_url( @$_GET['box'] );
59  if ( isset($_GET['ll']) )
60    $page['ll'] = rvm_ll_from_url( $_GET['ll'] );
61  return $page;
62}
63
64function rvm_duplicate_blowup_url($redefined=array(), $removed=array())
65{
66  return rvm_make_blowup_url(
67    params_for_duplication($redefined, $removed)
68    );
69}
70
71function rvm_make_blowup_url($params)
72{
73  global $conf, $rvm_dir;
74  if ( file_exists(PHPWG_ROOT_PATH.'mapl.php') )
75    $url = get_root_url().'mapl';
76  else
77    $url = get_root_url().'plugins/'.$rvm_dir.'/mapl';
78  if ($conf['php_extension_in_urls'])
79    $url .= '.php';
80  if ($conf['question_mark_in_urls'])
81    $url .= '?';
82  $url .= make_section_in_url($params);
83  $url = add_well_known_params_in_url($url, array_intersect_key($params, array('flat'=>1) ) );
84
85  $get_params = array();
86  if ( isset($params['box']) and !empty($params['box']) and !bounds_is_world($params['box']) )
87    $get_params['box'] = bounds_to_url($params['box']);
88  elseif ( isset($params['ll']) and !empty($params['ll']) )
89    $get_params['ll'] = $params['ll']['lat'].','.$params['ll']['lon'];
90  if ( isset($params['start']) and $params['start']>0 )
91    $get_params['start'] = $params['start'];
92  $url = add_url_params($url, $get_params );
93  return $url;
94}
95
96function rvm_parse_blowup_url($tokens, &$next_token)
97{
98  $page = parse_section_url($tokens, $next_token);
99  if ( !isset($page['section']) )
100    $page['section'] = 'categories';
101  $page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
102  $page['start']=0;
103  if ( isset($_GET['start']) )
104    $page['start']=$_GET['start'];
105  $page['box'] = rvm_bounds_from_url( @$_GET['box'] );
106  if ( isset($_GET['ll']) )
107    $page['ll'] = rvm_ll_from_url( $_GET['ll'] );
108  return $page;
109}
110
111function rvm_bounds_from_url($str)
112{
113  if ( !isset($str) or strlen($str)==0 )
114    return null;
115  $r = explode(',', $str );
116  if ( count($r) != 4)
117    bad_request( $str.' is not a valid geographical bound' );
118  $b = array(
119      's' => $r[0],
120      'w' => $r[1],
121      'n' => $r[2],
122      'e' => $r[3],
123    );
124  return $b;
125}
126
127function rvm_bounds_to_sql( $b )
128{
129  if ( !isset($b) or empty($b) )
130    return null;
131  $sql_where = 'i.lat BETWEEN '.$b['s'].' AND '.($b['n']);
132  $sql_where .= ' AND ';
133  if ($b['e'] >= $b['w'])
134    $sql_where .= 'i.lon BETWEEN '.$b['w'].' AND '.($b['e']);
135  else
136    $sql_where .= 'i.lon NOT BETWEEN '.($b['e']+1e-7).' AND '.($b['w']-1e-7);
137  return $sql_where;
138}
139
140function bounds_to_url($b, $p = 6 )
141{
142  if ( empty($b) )
143    return '';
144  return round($b['s'],$p).','.round($b['w'],$p).','.round($b['n'],$p).','.round($b['e'],$p);
145}
146
147function rvm_ll_from_url($str)
148{
149  if ( !isset($str) or strlen($str)==0 )
150    return null;
151  $r = explode(',', $str );
152  if ( count($r) != 2)
153    bad_request( $str.' is not a valid geographical position' );
154  $b = array('lat'=>$r[0],'lon'=>$r[1]);
155  return $b;
156}
157
158function rvm_ll_to_sql( $ll, &$order_by )
159{
160  $cos_lat = max( 1e-2, cos($ll['lat']*M_PI/180) );
161  $dlat = 3; // 1 degree is approx between 111 and 116 km
162  $dlon = min( 3/$cos_lat, 180 );
163  $bounds = array(
164      's' => $ll['lat'] - $dlat,
165      'w' => $ll['lon'] - $dlon,
166      'n' => $ll['lat'] + $dlat,
167      'e' => $ll['lon'] + $dlon,
168    );
169  if ($bounds['s']<-90) $bounds['s']=-90;
170  if ($bounds['w']<-180) $bounds['w']+=360;
171  if ($bounds['n']>90) $bounds['n']=90;
172  if ($bounds['e']>180) $bounds['e']-=360;
173  $where_sql = rvm_bounds_to_sql( $bounds );
174  $order_by = 'ORDER BY POW('.$ll['lat'].'-i.lat,2)+POW('.$cos_lat.'*('.$ll['lon'].'-i.lon),2)';
175  return $where_sql;
176}
177
178
179function bounds_is_world( $b )
180{
181  if (empty($b)) return false;
182  return $b['n']>=90 and $b['s']<=-90 and $b['w']<=-180 and $b['e']>=180;
183}
184
185function bounds_add($bounds, $lat, $lon)
186{
187  if ( empty($bounds) )
188  {
189    $bounds = array(
190      's' => $lat,
191      'n' => $lat,
192      'w' => $lon,
193      'e' => $lon,
194      'count' => 1
195      );
196  }
197  else
198  {
199    if ( $lat>$bounds['n'] )
200      $bounds['n']=$lat;
201    elseif ( $lat<$bounds['s'] )
202      $bounds['s']=$lat;
203    if ( $lon>$bounds['e'] )
204      $bounds['e']=$lon;
205    elseif ( $lon<$bounds['w'] )
206      $bounds['w']=$lon;
207    $bounds['count']=$bounds['count']+1;
208  }
209
210  return $bounds;
211}
212
213function bounds_union($b1, $b2)
214{
215  $total_count = $b1['count'] + $b2['count'];
216  $res =
217    array_merge(
218      $b1,
219      array(
220        's' => min( $b1['s'], $b2['s'] ),
221        'n' => max( $b1['n'], $b2['n'] ),
222        'w' => min( $b1['w'], $b2['w'] ),
223        'e' => max( $b1['e'], $b2['e'] ),
224        'count' => $total_count,
225      )
226    );
227  if ( isset($b2['min_date']) )
228    $res = array_merge(
229      $res,
230      array(
231        'min_date' => min( $b1['min_date'], $b2['max_date'] ),
232        'max_date' => max( $b1['max_date'], $b2['max_date'] ),
233      )
234    );
235  return $res;
236}
237
238function bounds_center($b)
239{
240  if (empty($b))
241    return array();
242  return array(
243    'lat' => ($b['s']+$b['n'])/2,
244    'lon' => ($b['w']+$b['e'])/2,
245    );
246}
247
248function bounds_sw($b)
249{
250  if (empty($b))
251    return array();
252  return array(
253    'lat' => $b['s'],
254    'lon' => $b['w'],
255    );
256}
257
258function bounds_ne($b)
259{
260  if (empty($b))
261    return array();
262  return array(
263    'lat' => $b['n'],
264    'lon' => $b['e'],
265    );
266}
267
268
269function bounds_lat_range($b)
270{
271  if (empty($b))
272    return 0;
273  return $b['n'] - $b['s'];
274}
275
276function bounds_lon_range($b)
277{
278  if (empty($b))
279    return 0;
280  return $b['e'] - $b['w'];
281}
282
283
284function rvm_get_cat_bounds()
285{
286  $cache_file_name = rvm_get_cache_file_name();
287  if ( file_exists($cache_file_name) )
288  {
289    return unserialize( file_get_contents($cache_file_name) );
290  }
291  $forbidden = get_sql_condition_FandF(
292        array
293          (
294            'forbidden_categories' => 'category_id',
295            'visible_categories' => 'category_id',
296            'visible_images' => 'i.id'
297          ),
298        'AND'
299    );
300
301  $query = '
302SELECT category_id cat_id, uppercats, MAX(lat) AS n, MIN(lat) AS s, MAX(lon) AS e, MIN(lon) AS w, COUNT(i.id) count, MIN(i.date_creation) min_date, MAX(i.date_creation) max_date
303  FROM
304    '.CATEGORIES_TABLE.' as c
305      INNER JOIN
306    '.IMAGE_CATEGORY_TABLE.' ON category_id = c.id
307      INNER JOIN
308    '.IMAGES_TABLE.' i ON image_id=i.id
309  WHERE lat IS NOT NULL '.$forbidden.'
310  GROUP BY category_id
311;';
312
313  $result = pwg_query($query);
314  $uppercats_list = array();
315  $cat_bounds = array();
316  while ($row = pwg_db_fetch_assoc($result))
317  {
318    $uppercats_list[] = $row['uppercats'];
319    $cat_id = $row['cat_id'];
320    unset( $row['cat_id'], $row['uppercats'] );
321    $cat_bounds[ $cat_id ] = $row;
322    $cat_bounds[ $cat_id ]['self'] = $row;
323  }
324  natsort($uppercats_list);
325  //echo "<pre>" . var_export($uppercats_list,true);
326
327  foreach ( array_reverse($uppercats_list) as $uppercats)
328  {
329    $cat_ids = explode(',', $uppercats);
330    $bounds = $cat_bounds[ $cat_ids[count($cat_ids)-1] ];
331    for ($i=count($cat_ids)-2; $i>=0; $i--)
332    {
333      $this_bounds = @$cat_bounds[ $cat_ids[$i] ];
334      if ( !isset($this_bounds) )
335      {
336        $this_bounds = $bounds;
337        unset($this_bounds['self']);
338      }
339      else
340      {
341//        if ($cat_ids[$i]==43) echo "<pre>Before\n" . var_export($this_bounds,true);
342//        if ($cat_ids[$i]==43) echo "<pre>Union\n" . var_export($bounds,true);
343        $this_bounds = bounds_union($this_bounds, $bounds);
344      }
345      $this_bounds['nb_cats'] = 1 + @$this_bounds['nb_cats'];
346//      if ($cat_ids[$i]==43) echo "<pre>" . var_export($this_bounds,true);
347      $cat_bounds[ $cat_ids[$i] ] = $this_bounds;
348    }
349  }
350  //echo "<pre>" . var_export($cat_bounds,true);
351        mkgetdir( dirname($cache_file_name) );
352  $file = fopen($cache_file_name , 'w' );
353  fwrite($file, serialize($cat_bounds) );
354  fclose( $file );
355
356  return $cat_bounds;
357}
358
359
360define('RVM_BUILD_ARRAY',     0);
361define('RVM_BUILD_HASH',      1);
362define('RVM_BUILD_AGGREGATE', 2);
363
364function rvm_build_section_items($img_fields, $where_sql, $mode, $order_by=null)
365{
366  global $page, $conf, $user;
367
368  $page['items'] = array();
369
370  if (empty($where_sql))
371    $where_sql .= 'i.lat IS NOT NULL';
372  $where_sql_images_only = $where_sql;
373  $where_sql .= get_sql_condition_FandF(
374      array
375        (
376          'forbidden_categories' => 'category_id',
377          'visible_categories' => 'category_id',
378          'visible_images' => 'i.id'
379        ),
380      "\n  AND"
381  );
382
383  switch ($mode)
384  {
385    case RVM_BUILD_ARRAY:
386      $func = 'array_from_query';
387      $group_by = '
388  GROUP BY i.id';
389      break;
390    case RVM_BUILD_HASH:
391      $func = create_function( '$q', 'return hash_from_query($q, "id");' );
392      $group_by = '
393  GROUP BY i.id';
394      break;
395    case RVM_BUILD_AGGREGATE:
396      $func = 'array_from_query';
397      $group_by = '';
398      break;
399  }
400
401  if ($mode != RVM_BUILD_AGGREGATE )
402  {
403    if ($order_by==null and pwg_get_session_var('image_order',0) > 0)
404    {
405      $orders = get_category_preferred_image_orders();
406
407      $conf['order_by'] = str_replace(
408        'ORDER BY ',
409        'ORDER BY '.$orders[ pwg_get_session_var('image_order',0) ][1].',',
410        $conf['order_by']
411        );
412      $page['super_order_by'] = true;
413    }
414    elseif ($order_by!=null)
415    {
416      $conf['order_by']=$order_by;
417      $page['super_order_by'] = true;
418    }
419    elseif ( 'categories' == $page['section'] and isset($page['category']['image_order']) )
420    {
421      $conf['order_by'] = 'ORDER BY '.$page['category']['image_order'];
422    }
423  }
424  else
425  {
426    $conf['order_by'] = 'ORDER BY NULL';
427    $page['super_order_by'] = true;
428  }
429
430  if ('categories' == $page['section'])
431  {
432    if ( isset($page['flat']) or isset($page['category']) )
433    {
434      if (isset($page['flat']))
435      {
436        if ( isset($page['category']) )
437        {
438          $subcat_ids = get_subcat_ids( array($page['category']['id']) );
439          $where_sql .= ' AND category_id IN ('.implode(',',$subcat_ids).')';
440        }
441      }
442      else
443      {
444        $where_sql .= ' AND category_id='.$page['category']['id'];
445      }
446
447      $query='
448SELECT '.$img_fields.'
449  FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
450  WHERE '.$where_sql.$group_by.'
451  '.$conf['order_by'];
452
453      $page['items'] = $func($query);
454    }
455    if ( isset($page['category']) )
456    {
457      $page['title'] = trigger_event('render_category_name', $page['category']['name']);
458      $page['comment'] = $page['category']['comment'];
459    }
460    else
461      $page['title'] = $conf['gallery_title'];
462  }
463  else if ('tags' == $page['section'])
464  {
465    $items = get_image_ids_for_tags( array($page['tags'][0]['id']), 'AND', $where_sql_images_only, 'ORDER BY NULL' );
466    if ( !empty($items) )
467    {
468      $query = '
469SELECT '.$img_fields.'
470  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.IMAGES_TABLE.' i ON i.id=image_id
471  WHERE image_id IN ('.implode(',', $items).')'
472  .$group_by.'
473  '.$conf['order_by'];
474
475      $page['items'] = $func($query);
476    }
477    $page['title'] = strip_tags( get_tags_content_title() );
478  }
479  elseif ('search' == $page['section'])
480  {
481    include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
482    $search_result = get_search_results($page['search'], @$page['super_order_by'], $where_sql_images_only);
483    if ( !empty($search_result['items']) )
484    {
485      $query = '
486SELECT '.$img_fields.'
487  FROM '.IMAGES_TABLE.' i
488  WHERE id IN ('.implode(',', $search_result['items']).')'
489  .$group_by.'
490  '.$conf['order_by'].'
491;';
492
493      if ($mode != RVM_BUILD_AGGREGATE )
494      {
495        $page['items'] = hash_from_query($query, 'id' );
496
497        global $item_ranks;
498        $item_ranks = array_flip($search_result['items']);
499        function cmp_item_hash($a, $b)
500        {
501          global $item_ranks;
502          return $item_ranks [ $a['id'] ] - $item_ranks [ $b['id'] ];
503        }
504        uasort( $page['items'], 'cmp_item_hash' );
505        unset( $item_ranks );
506      }
507      else
508        $page['items'] = $func($query);
509    }
510
511    $page['title'] = l10n('Search results');
512  }
513  elseif ('recent_pics' == $page['section'])
514  {
515    $conf['order_by'] = ' ORDER BY hit DESC, file ASC';
516
517    $query ='
518SELECT '.$img_fields.'
519  FROM '.IMAGES_TABLE.' i
520    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
521  WHERE date_available >= SUBDATE(
522      CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY)
523    AND '.$where_sql
524  .$group_by.'
525  '.$conf['order_by'].'
526  LIMIT 0, '.$conf['top_number'].'
527;';
528
529    $page['items'] = $func($query);
530    $page['title'] = l10n('Recent photos');
531  }
532  else if ('list'==$page['section'])
533  {
534    $query ='
535SELECT '.$img_fields.'
536  FROM '.IMAGES_TABLE.' i
537    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
538  WHERE image_id IN ('.implode(',', $page['list']).')
539    AND '.$where_sql
540  .$group_by.'
541  '.$conf['order_by'].'
542;';
543
544    $page['items'] = $func($query);
545    $page['title'] = l10n('Random photos');
546  }
547  else
548    fatal_error( 'section '.$page['section']. ' not handled '. __FILE__);
549}
550
551?>
Note: See TracBrowser for help on using the repository browser.