Changeset 1223

Show
Ignore:
Timestamp:
09/19/10 14:39:36 (3 years ago)
Author:
d0nut
Message:

gmap serverside clustering

Location:
g-map
Files:
1 added
6 modified

Legend:

Unmodified
Added
Removed
  • g-map/files/lib/data/gmap/Gmap.class.php

    r1222 r1223  
    11<?php 
    22 
    3 class Gmap extends Foo { 
     3/** 
     4 * gets several positions and returns a clustered array 
     5 * 
     6 * @author      Torben Brodt 
     7 * @license     GNU General Public License <http://opensource.org/licenses/gpl-3.0.html> 
     8 */ 
     9class Gmap extends DatabaseObject { 
    410         
    511        /** 
     
    814         */ 
    915        public static function search($location) { 
    10                 $res = array( 
    11                         'x' => 0, 
    12                         'y' => 0 
    13                 ); 
     16                $res = null; 
    1417 
    1518                $lookupstring = urlencode(trim($location)); 
     
    2730                                $send = fgets($io, 4096); 
    2831                                if (preg_match('/^200,[^,]+,([^,]+),([^,]+)$/', $send, $hits)) { 
    29                                         $res['x'] = trim($hits[1]); 
    30                                         $res['y'] = trim($hits[2]); 
     32                                        $res = array( 
     33                                                'lat' => trim($hits[1]), 
     34                                                'lon' => trim($hits[2]) 
     35                                        ); 
    3136                                        break; 
    3237                                } 
     
    3742                return $res; 
    3843        } 
    39  
    40         /** 
    41          * try to update database position 
    42          * 
    43          * @param location 
    44          */ 
    45         public static function update($location) { 
    46                 $column = "userOption".User::getUserOptionID('location'); 
    47                 if(empty($column)) return; 
    48  
    49                 // ask geocoder 
    50                 $res = self::search($street, $zip, $city, $country); 
    51  
    52                 // update all locations 
    53                 $sql = "UPDATE          wcf".WCF_N."_user 
    54                         USING           wcf".WCF_N."_user_option_value 
    55                         INNER JOIN      wcf".WCF_N."_user USING(userID) 
    56                         SET             coords = PointFromText('POINT(".$res['x']." ".$res['y'].")') 
    57                         WHERE           ".$column." = '".escapeString($location)."';"; 
    58                 WCF::getDB()->sendQuery($sql); 
    59         } 
    60          
    61         /** 
    62          * 
    63          * @param pt1 -> point1 in format array(lat, lng) 
    64          * @param pt2 -> point2 in format array(lat, lng) 
    65          */ 
    66         public static function getDistance($pt1, $pt2) { 
    67                 $lat1 = $pt1[0]; 
    68                 $lng1 = $pt1[1]; 
    69                 $lat2 = $pt2[0]; 
    70                 $lng2 = $pt2[1]; 
    71  
    72                 return round(acos((sin($lat1) * sin($lat2)) + (cos($lat1) * cos($lat2) * cos($lng1 - $lng2))) * 6380 / 100 * 1.609344,2); 
    73         } 
    7444} 
  • g-map/files/lib/data/gmap/GmapBounds.class.php

    r1222 r1223  
    44 * gets several positions and builds the bounding box 
    55 * 
    6  * @package     de.gmap.wcf.util 
    76 * @author      Torben Brodt 
    87 * @license     GNU General Public License <http://opensource.org/licenses/gpl-3.0.html> 
    98 */ 
    10 class BoundsUtil { 
     9class GmapBounds { 
    1110        public $left = 0, $right = 0, $bottom = 0, $top = 0; 
    1211 
  • g-map/files/lib/page/MapAjaxPage.class.php

    r1221 r1223  
    33require_once(WCF_DIR.'lib/page/AbstractPage.class.php'); 
    44 
    5 // bounding box import 
    6 require_once(WCF_DIR.'lib/util/BoundsUtil.class.php'); 
     5// map imports 
     6require_once(WCF_DIR.'lib/data/gmap/GmapCluster.class.php'); 
    77 
    88/** 
     
    1414 */ 
    1515class MapAjaxPage extends AbstractPage { 
    16  
    17         /** 
    18          * read data by users 
    19          */ 
    20         private function readDataByCities() { 
    21                 if(!WCF::getUser()->getPermission('user.map.canView')) 
    22                         return; 
    23  
    24                 $max = MAP_BIGMAP_MAX_ENTRYS - $this->pins; 
    25                  
    26                 // sql query             
    27                 $sql = "SELECT          COUNT(*) AS c, 
    28                                         GROUP_CONCAT(REPLACE(user.username,' ','&nbsp;') SEPARATOR ' ') AS mixNames,  
    29                                         GROUP_CONCAT(user.userID SEPARATOR ' ') AS mixIDs,  
    30                                         coords AS pos, 
    31                                         CONCAT(location, ' (', COUNT(*), ')') AS head 
    32                                         ".$this->pluginColumns('cities')." 
    33                         FROM            wcf".WCF_N."_user user  
    34                                         ".$this->pluginJoins('cities')." 
    35                         WHERE            
    36                         GROUP BY        coords 
    37                                         ".$this->pluginGroups('cities',false)." 
    38                         ORDER BY        c DESC 
    39                                         ".$this->pluginOrders('cities',false)."  
    40                                         LIMIT {$max};"; 
    41                                          
    42                 // apply filters 
    43                 $sql = $this->applyFilters($sql, $this->filter); 
    44  
    45                 $result = WCF::getDB()->sendQuery($sql); 
    46                 while ($row = WCF::getDB()->fetchArray($result)) { 
    47                         $keys = explode(' ', $row['mixIDs']); 
    48                         $values = explode(' ', $row['mixNames']); 
    49                          
    50                         $userlist = $this->optimizeAll($keys, $values); 
    51                          
    52                         $this->positions[] = array( 
    53                                         'pos'   => explode(',',$row['pos']), 
    54                                         'head'  => $this->optimizeSingle($row['head']), 
    55                                         'user'  => $userlist 
    56                                 ); 
    57  
    58                         // increase counters 
    59                         $this->total += $row['c']; 
    60                         $this->pins++; 
    61                 } 
    62         } 
    63          
     16        protected $zoom; 
     17        protected $distance = 30; 
     18         
     19        protected $markers = array(); 
     20         
    6421        /** 
    65          * reads public personal markers 
     22         * @see Page::readData() 
    6623         */ 
    67         private function readDataPersonal() { 
    68                 if(!$this->markers || !WCF::getUser()->getPermission('user.map.canViewPersonal')) 
    69                         return; 
    70  
    71                 // abort, if there are no users 
    72                 if($this->type == 'personal' && count($this->users) == 0) 
    73                         return; 
    74  
    75                 // sql query             
    76                 $sql = "SELECT          mapID, 
    77                                         X(pt) AS lng, 
    78                                         Y(pt) AS lat, 
    79                                         mapTitle AS head, 
    80                                         mapInfoCache 
    81                         FROM            wcf".WCF_N."_gmap  
    82                                         ".$this->pluginJoins('personal'). 
    83                                         (!empty($this->users) ? "WHERE userID IN (".implode(",", $this->users).");" : ";"). 
    84                                         $this->pluginConditions('personal',empty($this->users))." 
    85                                         ".$this->pluginGroups('personal',true)." 
    86                                         ".$this->pluginOrders('personal',true); 
    87  
    88                 // apply filters 
    89                 $sql = $this->applyFilters($sql, $this->filter); 
    90  
    91                 $result = WCF::getDB()->sendQuery($sql); 
    92                 while ($row = WCF::getDB()->fetchArray($result)) { 
    93                         $pos = array($row['lat'],$row['lng']); 
    94                          
    95                         // that's the trick to seperate users from public markers 
    96                         $row['mapID'] *= -1; 
    97                          
    98                         $this->positions[] = array( 
    99                                         'pos'   => $pos, 
    100                                         'head'  => $this->optimizeSingle($row['head']), 
    101                                         'user'  => array($row['mapID']=>"<![CDATA[".$row['mapInfoCache']."]]>") 
    102                                 ); 
    103                                  
    104                         $this->boundsUtil->add($pos[0], $pos[1]); 
    105  
    106                         // increase counters 
    107                         $this->total++; 
    108                         $this->pins++; 
    109                 } 
    110         } 
    111          
    112         /** 
    113          * reads alien user and own user 
    114          */ 
    115         private function readDataDistance() { 
    116                 if(!WCF::getUser()->getPermission('user.map.canView')) 
    117                         return; 
    118  
    119                 // abort, if there are no users 
    120                 if(count($this->users) == 0) 
    121                         return; 
    122  
    123                 // append own user 
    124                 if(is_numeric(WCF::getUser()->userID) && !in_array(WCF::getUser()->userID, $this->users)) { 
    125                         $this->users[] = WCF::getUser()->userID; 
    126                 } 
    127          
    128                 // sql query             
    129                 $sql = "SELECT          user.userID, user.username, 
    130                                         coords AS coord, 
    131                                         location AS head 
    132                                         ".$this->pluginColumns('distance')." 
    133                         FROM            wcf".WCF_N."_user user 
    134                                         ".$this->pluginJoins('distance')." 
    135                         WHERE           user.userID IN (".implode(",", $this->users).")  
    136                                         ".$this->pluginConditions('distance', false)." 
    137                                         ".$this->pluginGroups('distance', true)." 
    138                                         ".$this->pluginOrders('distance', true); 
    139  
    140                 // apply filters 
    141                 $sql = $this->applyFilters($sql, $this->filter); 
    142  
    143                 $result = WCF::getDB()->sendQuery($sql); 
    144                 while ($row = WCF::getDB()->fetchArray($result)) { 
    145                         $keys = array($row['userID']); 
    146                         $values = array($row['username']); 
    147                          
    148                         $userlist = $this->optimizeAll($keys, $values); 
    149                         $pos = explode(',',$row['coord']); 
    150                          
    151                         $this->positions[] = array( 
    152                                         'pos'   => $pos, 
    153                                         'head'  => $this->optimizeSingle($row['head']), 
    154                                         'user'  => $userlist 
    155                                 ); 
    156                                  
    157                         $this->boundsUtil->add($pos[0], $pos[1]); 
    158  
    159                         // increase counters 
    160                         $this->total++; 
    161                         $this->pins++; 
    162                 } 
     24        public function readParameters() { 
     25                parent::readParameters(); 
    16326                 
    164                 if(count($this->positions) > 1) { 
    165                         $this->dist = MapDiscover::getDistance($this->positions[0]['pos'], $this->positions[1]['pos']); 
    166                 } 
    167         } 
    168  
     27                $this->zoom = min(max(21, $_GET['zoom']), 0); 
     28        } 
     29         
    16930        /** 
    17031         * @see Page::readData() 
     
    17334                parent::readData(); 
    17435                 
    175                 // bounding box util 
    176                 $this->boundsUtil = new BoundsUtil(); 
     36                $markers = array(); 
    17737 
    178                 // read positions 
    179                 switch($this->type) { 
    180                         case 'cities': 
    181                                 $this->readDataPersonal(); 
    182                                 $this->readDataByCities(); 
    183                         break; 
    184                         case 'distance': 
    185                                 $this->readDataPersonal(); 
    186                                 $this->readDataDistance(); 
    187                         break; 
    188                 } 
     38                $sql = 'SELECT          X(pt) AS lon, 
     39                                        Y(pt) AS lat 
     40                        FROM            wcf'.WCF_N.'_gmap_user'; 
     41 
     42                $result = WCF::getDB()->sendQuery($sql); 
     43                while ($row = WCF::getDB()->fetchArray($result)) { 
     44                        $markers[] = $row; 
     45                } 
     46                 
     47                $cluster = new GmapCluster($this->distance, $this->zoom); 
     48                $this->markers = $cluster->getMarkers($markers); 
    18949        } 
    19050 
     
    19555                parent::show(); 
    19656 
    197                 // send header 
    198                 @header('Content-Type: application/xml; charset='.CHARSET); 
    199                  
    200                 foreach($this->positions as $p) { 
    201                          
    202                 } 
     57                echo json_encode($this->markers); 
    20358        } 
    20459} 
  • g-map/files/lib/page/MapPage.class.php

    r1221 r1223  
    1111 */ 
    1212class MapPage extends AbstractPage { 
    13         public $templateName = 'MapPage'; 
     13        public $templateName = 'mapOverview'; 
    1414 
    1515         /** 
  • g-map/files/lib/system/event/listener/GMapUserProfileEditFormListener.class.php

    r1222 r1223  
    44 
    55/** 
    6  * instantly updates geoposition 
     6 * instantly updates geoposition, using my maps from http://gmaps-samples.googlecode.com/svn/trunk/poly/mymapstoolbar.html 
    77 * 
    88 * @package     de.gmap.wcf 
  • g-map/install.sql

    r1088 r1223  
    1 CREATE TABLE wcf1_gmap ( 
     1CREATE TABLE wcf1_gmap_personal ( 
    22        mapID int(10) UNSIGNED NOT NULL auto_increment, 
    33        userID int(10) UNSIGNED NOT NULL DEFAULT 0, 
     4        PRIMARY KEY  (mapID), 
     5) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
     6 
     7CREATE TABLE wcf1_gmap_personal_data ( 
     8        dataID int(10) UNSIGNED NOT NULL auto_increment, 
     9        collection int(10) UNSIGNED NOT NULL DEFAULT 0, 
     10        mapID int(10) UNSIGNED NOT NULL DEFAULT 0, 
     11        type ENUM('point') NOT NULL DEFAULT 'point', 
     12        text TEXT NOT NULL DEFAULT '', 
    413        pt point NOT NULL, 
    5         mapTitle varchar(255) NOT NULL, 
    6         mapInfo TEXT NOT NULL, 
    7         mapInfoCache TEXT NOT NULL, 
    8         PRIMARY KEY  (mapID), 
     14        PRIMARY KEY  (dataID), 
     15        INDEX  (mapID), 
    916        SPATIAL KEY pt (pt) 
    1017) ENGINE=MyISAM DEFAULT CHARSET=utf8; 
    1118 
    12 CREATE TABLE wcf1_user_position ( 
     19CREATE TABLE wcf1_gmap_user ( 
    1320        userID int(10) UNSIGNED NOT NULL, 
    1421        pt point NOT NULL,