1 : <?php
2 : /**
3 : * @category NoiseLabs
4 : * @package ToolKit
5 : *
6 : * Phoogle Maps 2.0 | Uses Google Maps API to create customizable maps
7 : * that can be embedded on your website
8 : * Copyright (C) 2005 Justin Johnson
9 : *
10 : * This program is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License as published by
12 : * the Free Software Foundation; either version 2 of the License, or
13 : * (at your option) any later version.
14 : *
15 : * This program is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU General Public License
21 : * along with this program; if not, write to the Free Software
22 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 : *
24 : * Phoogle Maps 2.0
25 : * Uses Google Maps Mapping API to create customizable Google Maps that can be
26 : * embedded on your website
27 : *
28 : * @author Justin Johnson <justinjohnson@system7designs.com>
29 : * @copyright 2005 system7designs
30 : */
31 :
32 : namespace NoiseLabs\ToolKit\GoogleAPI;
33 :
34 : /**
35 : * Uses Google Maps API to create customizable maps that can be embedded on your
36 : * website.
37 : *
38 : * This class is a rewrite of the original PhoogleMap class created by Justin
39 : * Johnson (system7designs).
40 : *
41 : * @author Justin Johnson <justinjohnson@system7designs.com>
42 : * @author Vítor Brandão <noisebleed@noiselabs.org>
43 : */
44 : class GoogleMap
45 0 : {
46 : const LOCALHOST_API_KEY = 'ABQIAAAAdi_0xCw-nuskZRWE2Z6PBhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxR3tBq3ZXP3CHmGs13Ec_yYzjqSfA';
47 :
48 : /**
49 : * validPoints : array
50 : * Holds addresses and HTML Messages for points that are valid (ie: have longitude and latitutde)
51 : */
52 : public $validPoints = array();
53 :
54 : /**
55 : * invalidPoints : array
56 : * Holds addresses and HTML Messages for points that are invalid (ie: don't have longitude and latitutde)
57 : */
58 : public $invalidPoints = array();
59 :
60 : /**
61 : * mapWidth
62 : * width of the Google Map, in pixels
63 : */
64 : public $mapWidth = 300;
65 :
66 : /**
67 : * mapHeight
68 : * height of the Google Map, in pixels
69 : */
70 : public $mapHeight = 300;
71 :
72 : /**
73 : * apiKey
74 : * Google API Key
75 : */
76 : public $apiKey = '';
77 :
78 : /**
79 : * showControl
80 : * True/False whether to show map controls or not
81 : */
82 : public $showControl = true;
83 :
84 : /**
85 : * showType
86 : * True/False whether to show map type controls or not
87 : */
88 : public $showType = true;
89 :
90 : /**
91 : * controlType
92 : * string: can be 'small' or 'large'
93 : * display's either the large or the small controls on the map, small by default
94 : */
95 : public $controlType = 'small';
96 :
97 : /**
98 : * zoomLevel
99 : * int: 0-17
100 : * set's the initial zoom level of the map
101 : */
102 : public $zoomLevel = 4;
103 :
104 : /**
105 : *
106 : */
107 : public static function create(array $options = array())
108 : {
109 0 : $map = new static();
110 0 : $map->setAPIKey(static::LOCALHOST_API_KEY);
111 :
112 0 : return $map;
113 : }
114 :
115 : /**
116 : * Add's an address to be displayed on the Google Map using latitude/longitude
117 : * early version of this function, considered experimental.
118 : */
119 : public function addGeoPoint($lat, $long, $infoHTML)
120 : {
121 0 : $pointer = count($this->validPoints);
122 0 : $this->validPoints[$pointer]['lat'] = $lat;
123 0 : $this->validPoints[$pointer]['long'] = $long;
124 0 : $this->validPoints[$pointer]['htmlMessage'] = $infoHTML;
125 0 : }
126 :
127 : /**
128 : * Center's Google Map on a specific point (thus eliminating the need for
129 : * two different show methods from version 1.0).
130 : */
131 : public function centerMap($lat, $long)
132 : {
133 0 : $this->centerMap = "map.centerAndZoom(new GPoint(".$long.",".$lat."), ".$this->zoomLevel.");\n";
134 0 : }
135 :
136 : /**
137 : * Add's an address to be displayed on the Google Map (thus eliminating the
138 : * need for two different show methods from version 1.0).
139 : *
140 : * @param $address:string
141 : * @return Boolean True:False (True if address has long/lat, false if it
142 : * doesn't)
143 : */
144 : public function addAddress($address,$htmlMessage=null)
145 : {
146 0 : if (!is_string($address)){
147 0 : die("All Addresses must be passed as a string");
148 : }
149 0 : $apiURL = "http://maps.google.com/maps/geo?&output=xml&key=ABQIAAAAJUqzkGTwxHyfr_AFlet6FRSqiy-aFjcz-2DijvkBG8XEujeXPxSyYk3YLvgZJq0HyHrB2gCTJJRVAg&q=";
150 0 : $addressData = file_get_contents($apiURL.urlencode($address));
151 :
152 0 : $results = $this->xml2array($addressData);
153 0 : if (empty($results['Point']['coordinates'])) {
154 0 : $pointer = count($this->invalidPoints);
155 0 : $this->invalidPoints[$pointer]['lat']= $results['Point']['coordinates'][0];
156 0 : $this->invalidPoints[$pointer]['long']= $results['Point']['coordinates'][1];
157 0 : $this->invalidPoints[$pointer]['passedAddress'] = $address;
158 0 : $this->invalidPoints[$pointer]['htmlMessage'] = $htmlMessage;
159 0 : }
160 : else {
161 0 : $pointer = count($this->validPoints);
162 0 : $this->validPoints[$pointer]['lat']= $results['Point']['coordinates'];
163 0 : $this->validPoints[$pointer]['long']= $results['Point']['coordinates'];
164 0 : $this->validPoints[$pointer]['passedAddress'] = $address;
165 0 : $this->validPoints[$pointer]['htmlMessage'] = $htmlMessage;
166 : }
167 0 : }
168 :
169 : /**
170 : * Displays either a table or a list of the address points that are valid.
171 : * Mainly used for debugging but could be useful for showing a list of
172 : * addresses on the map.
173 : *
174 : * @param $displayType:string
175 : * @param $css_id:string
176 : * @return nothing
177 : */
178 : public function showValidPoints($displayType,$css_id)
179 : {
180 0 : $total = count($this->validPoints);
181 0 : if ($displayType == "table") {
182 0 : echo "<table id=\"".$css_id."\">\n<tr>\n\t<td>Address</td>\n</tr>\n";
183 0 : for ($t=0; $t<$total; $t++) {
184 0 : echo"<tr>\n\t<td>".$this->validPoints[$t]['passedAddress']."</td>\n</tr>\n";
185 0 : }
186 0 : echo "</table>\n";
187 0 : }
188 0 : if ($displayType == "list") {
189 0 : echo "<ul id=\"".$css_id."\">\n";
190 0 : for ($lst=0; $lst<$total; $lst++) {
191 0 : echo "<li>".$this->validPoints[$lst]['passedAddress']."</li>\n";
192 0 : }
193 0 : echo "</ul>\n";
194 0 : }
195 0 : }
196 :
197 : /**
198 : * Displays either a table or a list of the address points that are invalid.
199 : * Mainly used for debugging shows only the points that are NOT on the map.
200 : *
201 : * @param $displayType:string
202 : * @param $css_id:string
203 : * @return nothing
204 : */
205 : public function showInvalidPoints($displayType,$css_id)
206 : {
207 0 : $total = count($this->invalidPoints);
208 0 : if ($displayType == "table") {
209 0 : echo "<table id=\"".$css_id."\">\n<tr>\n\t<td>Address</td>\n</tr>\n";
210 0 : for ($t=0; $t<$total; $t++){
211 0 : echo"<tr>\n\t<td>".$this->invalidPoints[$t]['passedAddress']."</td>\n</tr>\n";
212 0 : }
213 0 : echo "</table>\n";
214 0 : }
215 0 : if ($displayType == "list") {
216 0 : echo "<ul id=\"".$css_id."\">\n";
217 0 : for ($lst=0; $lst<$total; $lst++) {
218 0 : echo "<li>".$this->invalidPoints[$lst]['passedAddress']."</li>\n";
219 0 : }
220 0 : echo "</ul>\n";
221 0 : }
222 0 : }
223 :
224 : /**
225 : * Sets the width of the map to be displayed.
226 : *
227 : * @param $width:int
228 : * @return nothing
229 : */
230 : public function setWidth($width)
231 : {
232 0 : $this->mapWidth = $width;
233 0 : }
234 :
235 : /**
236 : * Sets the height of the map to be displayed
237 : *
238 : * @param $height:int
239 : * @return nothing
240 : */
241 : public function setHeight($height)
242 : {
243 0 : $this->mapHeight = $height;
244 0 : }
245 :
246 : /**
247 : * Stores the API Key acquired from Google.
248 : *
249 : * @param $key:string
250 : * @return nothing
251 : */
252 : public function setAPIkey($key)
253 : {
254 0 : $this->apiKey = $key;
255 0 : }
256 :
257 : /**
258 : * Adds the necessary Javascript for the Google Map to function should be
259 : * called in between the html <head></head> tags.
260 : *
261 : * @return othing
262 : */
263 : public function printGoogleJS()
264 : {
265 0 : echo "\n<script src=\"http://maps.google.com/maps?file=api&v=2&key=".$this->apiKey."\" type=\"text/javascript\"></script>\n";
266 0 : }
267 :
268 : /**
269 : * Displays the Google Map on the page.
270 : */
271 : public function showMap()
272 : {
273 0 : echo "\n<div id=\"map\" style=\"width: ".$this->mapWidth."px; height: ".$this->mapHeight."px\">\n</div>\n";
274 : echo " <script type=\"text/javascript\">\n
275 : function showmap(){
276 : //<![CDATA[\n
277 : if (GBrowserIsCompatible()) {\n
278 0 : var map = new GMap(document.getElementById(\"map\"));\n";
279 0 : if (empty($this->centerMap)) {
280 0 : echo "map.centerAndZoom(new GPoint(".$this->validPoints[0]['long'].",".$this->validPoints[0]['lat']."), ".$this->zoomLevel.");\n";
281 0 : }
282 : else {
283 0 : echo $this->centerMap;
284 : }
285 : echo "}\n
286 : var icon = new GIcon();
287 : icon.image = \"http://labs.google.com/ridefinder/images/mm_20_red.png\";
288 : icon.shadow = \"http://labs.google.com/ridefinder/images/mm_20_shadow.png\";
289 : icon.iconSize = new GSize(12, 20);
290 : icon.shadowSize = new GSize(22, 20);
291 : icon.iconAnchor = new GPoint(6, 20);
292 : icon.infoWindowAnchor = new GPoint(5, 1);
293 0 : ";
294 0 : if ($this->showControl) {
295 0 : if ($this->controlType == 'small') { echo "map.addControl(new GSmallMapControl());\n"; }
296 0 : if ($this->controlType == 'large') { echo "map.addControl(new GLargeMapControl());\n"; }
297 0 : }
298 0 : if ($this->showType) {
299 0 : echo "map.addControl(new GMapTypeControl());\n";
300 0 : }
301 :
302 0 : $numPoints = count($this->validPoints);
303 0 : for ($g = 0; $g<$numPoints; $g++) {
304 0 : echo "var point".$g." = new GPoint(".$this->validPoints[$g]['long'].",".$this->validPoints[$g]['lat'].")\n;
305 0 : var marker".$g." = new GMarker(point".$g.");\n
306 0 : map.addOverlay(marker".$g.")\n
307 0 : GEvent.addListener(marker".$g.", \"click\", function() {\n";
308 0 : if ($this->validPoints[$g]['htmlMessage']!=null) {
309 0 : echo "marker".$g.".openInfoWindowHtml(\"".$this->validPoints[$g]['htmlMessage']."\");\n";
310 0 : }
311 : else {
312 0 : echo "marker".$g.".openInfoWindowHtml(\"".$this->validPoints[$g]['passedAddress']."\");\n";
313 : }
314 0 : echo "});\n";
315 0 : }
316 : echo " //]]>\n
317 : }
318 : window.onload = showmap;
319 0 : </script>\n";
320 0 : }
321 :
322 : /***************************************************************************
323 : * THIS BLOCK OF CODE IS FROM Roger Veciana's CLASS (assoc_array2xml)
324 : * OBTAINED FROM PHPCLASSES.ORG
325 : **************************************************************************/
326 :
327 : public function xml2array($xml)
328 : {
329 0 : $this->depth=-1;
330 0 : $this->xml_parser = xml_parser_create();
331 0 : xml_set_object($this->xml_parser, $this);
332 0 : xml_parser_set_option ($this->xml_parser,XML_OPTION_CASE_FOLDING,0);//Don't put tags uppercase
333 0 : xml_set_element_handler($this->xml_parser, "startElement", "endElement");
334 0 : xml_set_character_data_handler($this->xml_parser,"characterData");
335 0 : xml_parse($this->xml_parser,$xml,true);
336 0 : xml_parser_free($this->xml_parser);
337 0 : return $this->arrays[3];
338 :
339 : }
340 :
341 : public function startElement($parser, $name, $attrs)
342 : {
343 0 : $this->keys[]=$name;
344 0 : $this->node_flag=1;
345 0 : $this->depth++;
346 0 : }
347 :
348 : public function characterData($parser,$data)
349 : {
350 0 : $key=end($this->keys);
351 0 : $this->arrays[$this->depth][$key]=$data;
352 0 : $this->node_flag=0;
353 0 : }
354 :
355 : public function endElement($parser, $name)
356 : {
357 0 : $key=array_pop($this->keys);
358 0 : if($this->node_flag==1){
359 0 : $this->arrays[$this->depth][$key]=$this->arrays[$this->depth+1];
360 0 : unset($this->arrays[$this->depth+1]);
361 0 : }
362 0 : $this->node_flag=1;
363 0 : $this->depth--;
364 0 : }
365 :
366 : /*** END CODE FROM Roger Veciana's CLASS (assoc_array2xml) ****************/
367 : }
368 :
|