/[drupal]/contributions/modules/geo/geo.module
ViewVC logotype

Contents of /contributions/modules/geo/geo.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.27 - (show annotations) (download) (as text)
Fri Aug 7 16:55:12 2009 UTC (3 months, 2 weeks ago) by vauxia
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-ALPHA1
Changes since 1.26: +3 -1 lines
File MIME type: text/x-php
It appears that the theme registry is not guaranteed to be available via
theme_get_registry().  Add an init_theme() call to make it so.
1 <?php // $Id: geo.module,v 1.26 2009/08/06 04:09:32 vauxia Exp $
2
3 /**
4 * Geo: Geospatial storage and retrieval.
5 */
6
7 define(GEO_SRID_DEFAULT, 4326);
8 define(GEO_DEGREE_M, 111206);
9
10 define(GEO_TYPE_POINT, 0);
11 define(GEO_TYPE_CURVE, 2);
12 define(GEO_TYPE_LINESTRING, 3);
13 define(GEO_TYPE_SURFACE, 4);
14 define(GEO_TYPE_POLYGON, 5);
15 define(GEO_TYPE_COLLECTION, 6);
16 define(GEO_TYPE_MULTIPOINT, 7);
17 define(GEO_TYPE_MULTICURVE, 8);
18 define(GEO_TYPE_MULTILINESTRING, 9);
19 define(GEO_TYPE_MULTISURFACE, 10);
20 define(GEO_TYPE_MULTIPOLYGON, 11);
21
22 /**
23 * Call an API function from the geo backend databases.
24 * This function will find and load the database backend files, and call
25 * the requested op from the backend or the default library, as needed.
26 *
27 * @return mixed
28 * The result of the database operation execution.
29 */
30 function geo($op = NULL) {
31 static $backend;
32
33 // Load common functions.
34 module_load_include('inc', 'geo');
35
36 // Load database-specific functions.
37 if (!isset($backend)) {
38 $backend = geo_backend_type();
39 module_load_include('inc', 'geo', 'db/'. $backend);
40 }
41
42 // Call the appropriate API function: If geo_$backend_$op exists, call that.
43 // Otherwise, resort to geo_$op. This creates a sort of inheritence system.
44 $args = func_get_args();
45 if($args) {
46 $op = array_shift($args);
47 if (!function_exists($func = 'geo_'. $backend .'_'. $op)) {
48 $func = 'geo_'. $op;
49 }
50 if (!function_exists($func)) {
51 drupal_set_message(t('Call to undefined geo operation %op', array('%op' => $op)), 'error');
52 return FALSE;
53 }
54 return call_user_func_array($func, $args);
55 }
56 }
57
58 /**
59 * Implementation of hook_theme().
60 */
61 function geo_theme() {
62 $file_path = drupal_get_path('module', 'geo') .'/includes';
63 return array(
64 'geo_formatter_default' => array(
65 'arguments' => array('element' => NULL),
66 'file' => 'geo.formatters.inc',
67 'path' => $file_path,
68 'gis input' => 'wkt',
69 ),
70 'geo_formatter_lat' => array(
71 'arguments' => array('element' => NULL),
72 'file' => 'geo.formatters.inc',
73 'path' => $file_path,
74 'gis input' => 'array',
75 ),
76 'geo_formatter_lon' => array(
77 'arguments' => array('element' => NULL),
78 'file' => 'geo.formatters.inc',
79 'path' => $file_path,
80 'gis input' => 'array',
81 ),
82 'geo_formatter_georss' => array(
83 'arguments' => array('element' => NULL),
84 'file' => 'geo.formatters.inc',
85 'path' => $file_path,
86 'gis input' => 'array',
87 ),
88 'geo_formatter_svg' => array(
89 'arguments' => array('element' => NULL),
90 'file' => 'geo.formatters.inc',
91 'path' => $file_path,
92 ),
93 'geo_fields' => array(
94 'arguments' => array('element' => NULL),
95 ),
96 'geo_latlon' => array(
97 'arguments' => array('element' => NULL),
98 ),
99 );
100 }
101
102 /**
103 * Implementation of hook_field_formatter_info().
104 */
105 function geo_field_formatter_info() {
106 // TODO some other formatters: asKML, asGML, asGeoRSS, etc
107 return array(
108 'default' => array(
109 'label' => t('Well Known Text'),
110 'field types' => geo_field_types(),
111 'gis types' => array('point', 'linestring', 'polygon'),
112 'gis input' => 'wkt',
113 ),
114 'lat' => array(
115 'label' => t('Latitude'),
116 'field types' => geo_field_types(),
117 'gis types' => array('point'),
118 'gis input' => 'array',
119 ),
120 'lon' => array(
121 'label' => t('Longitude'),
122 'field types' => geo_field_types(),
123 'gis types' => array('point'),
124 'gis input' => 'array',
125 ),
126 'georss' => array(
127 'label' => t('GeoRSS'),
128 'field types' => geo_field_types(),
129 'gis types' => array('point', 'linestring', 'polygon'),
130 'gis input' => 'text',
131 ),
132 );
133 }
134
135 /**
136 * API Function: Return any field types that may contain geospatial data.
137 */
138 function geo_field_types() {
139 static $field_types;
140 if (!isset($field_types)) {
141 $field_types = array('geo', 'geo_data');
142 drupal_alter('geo_field_types', $field_types);
143 }
144 return $field_types;
145 }
146
147 /**
148 * Implementation of hook_content_fieldapi().
149 */
150 function geo_content_fieldapi($op, $field) {
151 //TODO this will catalog (?) and possibly postprocess geo-fields.
152 $fields = $old_fields = variable_get('geo_fields', array());
153
154 // ANY field with a 'geo_type' value is acknowledged here.
155 if (isset($field['geo_type'])) {
156 switch ($op) {
157 case 'create instance':
158 $fields[$field['field name']] = array($field['geo_type']);
159 break;
160
161 case 'delete instance':
162 unset($fields[$field['field_name']]);
163 break;
164 }
165 }
166 }
167
168 /**
169 * Implementation of hook_views_api().
170 */
171 function geo_views_api() {
172 return array(
173 'api' => 2,
174 'path' => drupal_get_path('module', 'geo') .'/includes/views',
175 );
176 }
177
178 /**
179 * API Function: Format WKB data
180 */
181 function geo_wkb_get_data($wkb = NULL, $format = 'text', $fp = NULL, $type = NULL) {
182 module_load_include('inc', 'geo', 'includes/geo.wkb');
183 return _geo_wkb_get_data($wkb, $format, $fp, $type);
184 }
185
186 /**
187 * API Function: List of available units.
188 */
189 function geo_units($unit = NULL) {
190 $units = array(
191 'mi' => t('Miles'),
192 'km' => t('Kilometers'),
193 'm' => t('Meters'),
194 );
195
196 return $unit ? $units[$unit] : $units;
197 }
198
199 /**
200 * API Function: Convert between units.
201 */
202 function geo_unit_convert($val, $from_unit, $to_unit) {
203 switch ($from_unit) {
204
205 case 'm': // Meters
206 switch ($to_unit) {
207 case 'km':
208 $val = $val / 1000;
209 break;
210 case 'mi':
211 $val = $val / 1609.344;
212 break;
213 }
214 break;
215
216 case 'km': // Kilometers
217 switch ($to_unit) {
218 case 'm':
219 $val = $val * 1000;
220 break;
221 case 'mi':
222 $val = $val * 0.62137;
223 break;
224 }
225 break;
226
227 case 'mi': // Miles
228 switch ($to_unit) {
229 case 'm':
230 $val = $val * 1609.344;
231 break;
232 case 'km':
233 $val = $val * 1.609344;
234 break;
235 }
236 break;
237 }
238
239 return $val;
240 }
241
242 /**
243 * Implementation of hook_nodeapi().
244 */
245 function geo_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
246 // Append microformats onto geo node feeds.
247 if ($op == 'rss item' && isset($node->geo_fields)) {
248 $rss = array();
249 foreach ($node->geo_fields as $field_name => $type) {
250 foreach ($node->$field_name as $item) {
251 $rss[] = geo('rss_item', $item['wkb']);
252 }
253 }
254 return $rss;
255 }
256 }
257
258 /**
259 * Implementation of hook_elements().
260 */
261 function geo_elements() {
262 return array(
263 'geo_latlon' => array(
264 '#input' => TRUE,
265 '#process' => array('geo_latlon_process'),
266 ),
267 );
268 }
269
270 function theme_geo_fields($element) {
271 return $element['#children'];
272 }
273
274 /**
275 * A #process handler for the latlon element.
276 */
277 function geo_latlon_process($element, $edit, $form_state, $form) {
278 $field = $form['#field_info'][$element['#field_name']];
279
280 $element['lat'] = array(
281 '#type' => 'textfield',
282 '#title' => t('Latitude'),
283 '#default_value' => $element['#value']['lat'],
284 '#required' => $element['#required'],
285 '#size' => 12,
286 '#maxlength' => 15,
287 );
288 $element['lon'] = array(
289 '#type' => 'textfield',
290 '#title' => t('Longitude'),
291 '#default_value' => $element['#value']['lon'],
292 '#required' => $element['#required'],
293 '#size' => 12,
294 '#maxlength' => 15,
295 );
296 return $element;
297 }
298
299 function theme_geo_latlon($element) {
300 $output = '<div class="container-inline">'. $element['#children'] .'</div>';
301 return theme('form_element', $element, $output);
302 }
303
304 function geo_element_set_value($element, &$form_state) {
305 if (!$element['#value']) $element['#value'] = $element['#default_value'];
306 if (!isset($element['#gis_input_value'])) $element['#gis_input_value'] = $element['#value'];
307
308 $value = geo_value_convert($element['#value'], $element['#gis_input'], $element['#gis_output']);
309 $element['#gis_output_value'] = $value;
310 form_set_value($element, $value, $form_state);
311 return $element;
312 }
313
314 function geo_value_convert($value, $in = 'array', $out = 'wkt') {
315 // TODO We are taking the element's requested input and output formats, and
316 // making the necessary adjustments. This needs to be refactored and set up
317 // in some kind of a handler model. For now it's a proof-of-concept that
318 // gets the UI & existing inputs up and running.
319 switch ($in) {
320 case 'array':
321 if ($out == 'wkt') {
322 $value = geo('wkt_from_point', $value['lat'], $value['lon']);
323 }
324 break;
325 }
326
327 return $value;
328 }
329
330 /**
331 * Implementation of hook_gis_input_info().
332 */
333 function geo_gis_input_info($gis_type = NULL) {
334 $inputs = array(
335 'geo_wkt' => array(
336 'label' => t('Well known text'),
337 'gis input' => 'wkt',
338 'safe reverse' => TRUE,
339 'gis types' => array('point', 'linestring', 'polygon'),
340 'element' => array(
341 '#type' => 'textfield',
342 ),
343 ),
344 'geo_latlon' => array(
345 'label' => t('Latitude/Longitude'),
346 'gis input' => 'array',
347 'safe reverse' => TRUE,
348 'gis types' => array('point'),
349 'element' => array(
350 '#type' => 'geo_latlon',
351 ),
352 ),
353 );
354 return $inputs;
355 }
356
357 function geo_set_pre_render(&$element) {
358 if (!isset($element['#pre_render'])
359 || !in_array('geo_field_convert_value', $element['#pre_render'])) {
360 $element['#pre_render'][] = 'geo_field_convert_value';
361 }
362 }
363
364 function geo_field_convert_value($element) {
365 foreach (element_children($element) as $key) {
366 if (isset($element[$key]['field']) && $element[$key]['field']['#access']) {
367 $field = $element[$key]['field'];
368 $theme = $field['#single'] ? $field['items'][0]['#theme'] : $field['items']['#theme'];
369 foreach ($field['items'] as $i => $item) {
370 if (is_array($item) && isset($item['#item'])) {
371 $element[$key]['field']['items'][$i]['#item'] = geo_set_value($item['#item'], $theme);
372 }
373 }
374 }
375 }
376 return $element;
377 }
378
379 function geo_set_value($item, $theme) {
380 init_theme();
381 $registry = theme_get_registry();
382
383 if ($format = $registry[$theme]['gis input']) {
384 $value = geo_wkb_get_data($item['wkb'], $format);
385 $item[$format] = $value['value'];
386 }
387 return $item;
388 }

  ViewVC Help
Powered by ViewVC 1.1.2