file = db_fetch_object(db_query('SELECT * FROM {track} WHERE nid = %d', $nid)); return $extras->file->filepath; } function track_add() { return node_add("track"); } /** * Implementation of hook_menu. */ function track_menu($may_cache) { $items = array(); if ($may_cache) { // $items[] = array('path' => 'node/add/track', 'title' => t('track upload'), 'access' => user_access('create tracks')); $items[] = array('path' => 'track', 'callback' => 'list_trk', 'title' => t('track list'), 'access' => true); $items[] = array('path' => 'track/add', 'callback' => 'track_add', 'title' => t('track upload'), 'access' => user_access('create tracks')); } $items[] = array( 'path' => 'track/trk', 'callback' => 'download_trk', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/kml', 'callback' => 'download_kml', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/gpx', 'callback' => 'download_gpx', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/icon', 'callback' => 'get_icon', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/ajax/all', 'callback' => 'trackback_all', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/ajax/detail', 'callback' => 'trackback_detail', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/profile', 'callback' => 'trackback_profile', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/repartition', 'callback' => 'trackback_repartition', 'access' => true, 'type' => MENU_CALLBACK); $items[] = array( 'path' => 'track/boundslist', 'callback' => 'track_boundslist', 'access' => true, 'type' => MENU_CALLBACK); // this is added to enable settings in 5.x $items[] = array( 'path' => 'admin/settings/track', 'title' => t('Track'), 'description' => t('Setup the Google API'), 'callback' => 'drupal_get_form', 'callback arguments' => array('track_admin_settings'), 'access' => user_access('administer site configuration'), 'type' => MENU_NORMAL_ITEM, // optional ); return $items; } function track_boundslist() { $result = db_query('SELECT latmin, lonmin, latmax, lonmax FROM {track}'); if ($result) { while ($bounds = db_fetch_object($result)) { echo $bounds->lonmin .";".$bounds->latmin .";".$bounds->lonmax .";".$bounds->latmax."
\n"; } } } function trackback_profile($nid) { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($nid)); $aGPXfile->XMLforProfile(); } function trackback_repartition($nid) { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($nid)); $aGPXfile->XMLforRepartition(); } function get_icon($diff) { header("Content-type: image/png"); if ($diff == "S") { $image_name = "modules/track/misc/pushpins/058.png"; } elseif ($diff == "M") { $image_name = "modules/track/misc/pushpins/150.png"; } elseif ($diff == "L") { $image_name = "modules/track/misc/pushpins/011.png"; } else { $image_name = "modules/track/misc/pushpins/001.png"; } $im = imagecreatefrompng($image_name); imageAlphaBlending($im, true); imageSaveAlpha($im, true); if ($diff == "XL") { $black = imagecolorallocate($im, 255, 255, 255); } else { $black = imagecolorallocate($im, 0, 0, 0); } $string = $diff; $len = strlen($string); if($len <= 2) { $px = (imagesx($im) - 7 * strlen($string)) / 2 + 1; imagestring($im, 3, $px, 3, $string, $black); } else { $px = (imagesx($im) - 7 * strlen($string)) / 2 + 2; imagestring($im, 2, $px, 3, $string, $black); } imagepng($im); imagedestroy($im); } function trackback_detail($nid) { // echo "toto"; include_once("modules/track/track.google.map.inc"); // create interface object with map $aMap = new GoogleMap(); // init all values $aMap->Init(); // map is displaying sync, zoom if ($aMap->mapaction == "initsync") { $result = db_query('SELECT min(latmin) as latminr, min(lonmin) as lonminr,max(latmax) as latmaxr, max(lonmax) as lonmaxr, avg(latstart) as latavg, avg(lonstart) as lonavg FROM {track} WHERE nid='.$nid); if ($result) { while ($bounds = db_fetch_object($result)) { $latmin = $bounds->latminr; $lonmin = $bounds->lonminr; $latmax = $bounds->latmaxr; $lonmax = $bounds->lonmaxr; $latavg = $bounds->latavg; $lonavg = $bounds->lonavg; } } $varlon = max(1e-5, $lonmax - $lonmin); $angle = 360; $zoomlevellon = 17; while ($angle>$varlon) { $angle = $angle / 2; $zoomlevellon--; } $varlat = max(1e-5, $latmax - $latmin); $angle = 360; $zoomlevellat = 17; while ($angle>$varlat) { $angle = $angle / 2; $zoomlevellat--; } $zoomlevel = max(0, max($zoomlevellat, $zoomlevellon)); // center and zoom the map $aMap->MoveAndZoom($lonavg, $latavg, $zoomlevel); } // map is displaying async, display if ($aMap->mapaction == "initasync") { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($nid)); $aMap->AddClearLastTrace(); $points = $aGPXfile->PointsForGoogleMaps(2000); $track = node_load($nid); $desc = theme('info_window_html', $track); $aMap->AddTrace($points, "#0000ff", 2, 0.8); $intensite = $track->file->dzplus / ($track->file->length / 4); $intensite = ($intensite - 30) * (100 / 40); if ($intensite < 30) { $mapicon = base_path()."track/icon/S"; } elseif ($intensite < 60) { $mapicon = base_path()."track/icon/M"; } elseif ($intensite < 100) { $mapicon = base_path()."track/icon/L"; } else { $mapicon = base_path()."track/icon/XL"; } $aMap->AddPoint($points[0][0], $points[0][1], $track->nid, $desc, $mapicon); $aMap->DisplayInfo("info", ""); } // send scenario to map $aMap->ShowXMLforAJAX(); } function trackback_all() { include_once("modules/track/track.google.map.inc"); // create interface object with map $aMap = new GoogleMap(); // init all values $aMap->Init(); if ($aMap->mapaction == "initsync") { $result = db_query('SELECT min(latmin) as latminr, min(lonmin) as lonminr,max(latmax) as latmaxr, max(lonmax) as lonmaxr, avg(latstart) as latavg, avg(lonstart) as lonavg FROM {track}'); $nresult = 0; if ($result) { while ($bounds = db_fetch_object($result)) { $latmin = $bounds->latminr; $lonmin = $bounds->lonminr; $latmax = $bounds->latmaxr; $lonmax = $bounds->lonmaxr; $latavg = $bounds->latavg; $lonavg = $bounds->lonavg; $nresult++; } } if ($nresult > 0) { $varlon = max(1e-5, $lonmax - $lonmin); $angle = 360; $zoomlevellon = 17; while ($angle>$varlon) { $angle = $angle / 2; $zoomlevellon--; } $varlat = max(1e-5, $latmax - $latmin); $angle = 360; $zoomlevellat = 17; while ($angle>$varlat) { $angle = $angle / 2; $zoomlevellat--; } $zoomlevel = max(0, max($zoomlevellat, $zoomlevellon)); // center and zoom the map $aMap->MoveAndZoom($lonavg, $latavg, $zoomlevel); } else { $aMap->MoveAndZoom("0", "0", 17); } } if ($aMap->mapaction == "initasync") { $result = db_query('SELECT n.nid, r.title, r.teaser, u.name, u.uid, t.latstart, t.lonstart, t.dzplus, t.length FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid INNER JOIN {track} t ON t.nid = n.nid'); if ($result) { while ($track = db_fetch_object($result)) { $desc = theme('info_window_html', $track); $intensite = $track->dzplus / ($track->length / 4); $intensite = ($intensite - 30) * (100 / 40); if ($intensite < 30) { $mapicon = base_path()."track/icon/S"; } elseif ($intensite < 60) { $mapicon = base_path()."track/icon/M"; } elseif ($intensite < 100) { $mapicon = base_path()."track/icon/L"; } else { $mapicon = base_path()."track/icon/XL"; } $aMap->AddPoint($track->lonstart, $track->latstart, $track->nid, $desc, $mapicon); } } $aMap->DisplayInfo("info", ""); } // end init if ($aMap->mapaction == "clicked") { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($aMap->idclicked)); $aMap->AddClearLastTrace(); $aMap->AddTrace($aGPXfile->PointsForGoogleMaps(2000), "#0000ff", 2, 0.8); $track = node_load($aMap->idclicked); $desc = theme('info_details', $track); $aMap->DisplayInfo("info", $desc); } // send scenario to map $aMap->ShowXMLforAJAX(); } function theme_info_window_html($track) { $output = ""; $output .= "".$track->title.""; $output .= " ".t("by")." "; $output .= l($track->name, 'user/'.$track->uid); $output .= check_markup($track->teaser, $track->format, FALSE); $output .= "".l(t('More details'), 'node/'.$track->nid).""; return $output; } function theme_info_details($track) { $output = theme('track_files', $track, true); return $output; } function prepare_google_maps() { $key = variable_get('googlemapskey', 'AAAAAAAAAAA'); //drupal_set_html_head(''); $basepath = $GLOBALS['base_path']; drupal_add_js('modules/track/misc/map.inc.js'); $GLOBALS['base_path'] = ""; drupal_add_js('http://maps.google.com/maps?file=api&v=2&key='.$key); $GLOBALS['base_path'] = $basepath; } function track_footer($main = 0) { global $phptrackback; if ($phptrackback != "") { prepare_google_maps(); $content = ''; $content .= "\n"; } return $content; } function track_page_last() { $output = ''; $result = pager_query(db_rewrite_sql("SELECT n.nid, n.created FROM {node} n WHERE n.type = 'track' AND n.status = 1 ORDER BY n.created DESC"), variable_get('default_nodes_main', 10)); $header = array(); $header[] = t("Name"); $header[] = t("Teaser"); $header[] = t("Length"); $header[] = t("Z+"); $header[] = t("Z-"); $header[] = "".t("Intensité").""; $rows = array(); while ($node = db_fetch_object($result)) { $row = array(); $track = node_load($node->nid); $row[] = l($track->title, 'node/'.$track->nid); $row[] = check_markup($track->teaser, $track->format, FALSE); $row[] = sprintf('%2.2f', $track->file->length)." km"; $row[] = sprintf('%2.2f', $track->file->dzplus)." m"; $row[] = sprintf('%2.2f', $track->file->dzminu)." m"; $intensite = $track->file->dzplus / ($track->file->length / 4); $intensite = ($intensite - 30) * (100 / 40); if ($intensite < 30) { $sint = "S"; } elseif ($intensite < 60) { $sint = "M"; } elseif ($intensite < 100) { $sint = "L"; } else { $sint = "XL"; } $row[] = "".$sint.""; $rows[] = $row; } $output .= theme_table($header, $rows); $output .= theme('pager', NULL, variable_get('default_nodes_main', 10)); return $output; } function list_trk() { global $phptrackback; $phptrackback = 'track/ajax/all'; $content = ''; // $content .= '
'; $content .= '
'; $content .= '
'; $content .= '
'; $content .= '
'.t("Loading").'...'.'
'; $content .= '
'; $content .= track_page_last(); return $content; } function download_trk($nid = 0) { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($nid)); $aGPXfile->ConvertToTRK(); } function download_kml($nid = 0) { $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile(get_gpx_filepath($nid)); $aGPXfile->ConvertToKML(); } function download_gpx($nid = 0) { $file = get_gpx_filepath($nid); file_transfer($file, array('Content-Disposition: attachment; filename="'.basename($file).'"') ); } /** * Implementation of hook_perm. */ function track_perm() { return array('create tracks'); } /** * Implementation of hook_help. */ function track_help($section) { switch ($section) { case 'admin/modules#description': return t('Allows users to upload GPS tracks.'); case 'node/add#track': return t('Upload new track.'); } } /** * Implementation of hook_node_info. */ function track_node_info() { return array('track' => array('name' => t('track'), 'base' => 'track')); } /** * Implementation of hook_access. */ function track_access($op, $node) { global $user; switch ($op) { case 'create': return user_access("create tracks"); case 'update': case 'delete': return user_access("create tracks") && ($user->uid == $node->uid); } } function track_flash_chart($width, $height, $nid, $type) { $swf = "FC2Line.swf"; if ($type == "repartition") $swf = "FC2Column.swf"; $output = ''; $output .= ''; $output .= ''; $output .= ''; $output .= 'nid."/"; $node = node_prepare($node, $teaser); $node->body .= theme('track_files', $node, false); $node->teaser .= theme('track_files', $node, true) . "
".l(t('More details'), 'node/'.$node->nid).""; } function theme_track_files($node, $teaser) { //theme_node_example_order_info $output = ""; if ($file = $node->file) { $output .= "

"; $output .= theme_item_list( array( t('Length').' : '.sprintf('%2.2f', $node->file->length).'km', t('Positive Z').' : '.sprintf('%2.2f', $node->file->dzplus).'m', t('Negative Z').' : '.sprintf('%2.2f', $node->file->dzminu).'m', t('Z min').' : '.sprintf('%2.2f', $node->file->zmin).'m', t('Z max').' : '.sprintf('%2.2f', $node->file->zmax).'m' ), t('Characteristics'), 'ul' ); if (!$teaser) { $output .= theme_item_list( array(), t('Map'), 'ul' ); // $output .= '

'; // $output .= '
'.t("Loading").'...'.'
'; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'.t("Loading").'...'.'
'; $output .= '
'; $output .= theme_item_list( array( track_flash_chart(565, 420, $node->nid, "profile"), track_flash_chart(565, 420, $node->nid, "repartition") ), t('Charts')." (".l("FusionCharts", "http://www.infosoftglobal.com/FusionCharts/").")", 'ul' ); // Only create link to file when it is in the proper location. if (file_check_location($file->filepath, file_directory_path())) { $output .= theme_item_list( array( "

".l($node->title . ' - '.t('GPX file'), 'track/gpx/'.$node->nid), "

".l($node->title . ' - '.t('TRK file'), 'track/trk/'.$node->nid), "

".l($node->title . ' - '.t('KML file'), 'track/kml/'.$node->nid) ), t('Downloads'), 'ul' ); } } $output .= "

"; } return $output; } /** * Implementation of hook_form(). * * Return an array of the form elements needed to edit this node. */ function track_form(&$node) { $op = isset($_POST['op']) ? $_POST['op'] : ''; if ($op == t('Preview')) { track_validate($node); } if ($op == t('Submit')) { track_validate($node); } // Set form parameters so we can accept file uploads. $form['#attributes'] = array('enctype' => 'multipart/form-data'); // Title of the track $form['title'] = array('#type' => 'textfield', '#title' => t('Title'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5); // Check if a file exists for the node if ($node->file->filepath) { $form['title']['#description'] .= t('A file already exists, you cannot upload a new one.'); $form['current_file'] = array( '#type' => 'hidden', '#value' => $node->file->filepath ); } else { // file upload field $form['file'] = array( '#type' => 'file', '#title' => t('File').'*', '#size' => 40, '#default_value' => '', '#weight' => -3 ); } $form['body_filter']['body'] = array( '#type' => 'textarea', '#title' => t('Body'), '#default_value' => $node->body, '#rows' => 10, '#weight' => -2, '#required' => TRUE); $form['body_filter']['filter'] = filter_form($node->format); return $form; } function track_form_alter($form_id, &$form) { } function file_check_local($source) { $file = new StdClass(); $file->filename = trim(basename($source), '.'); $file->filepath = $source; return $file; } function track_validate_file(&$node) { // Check for a new file upload. if ($file = file_check_upload('file')) { $ext = strtolower(ereg_replace("^.+\\.([^.]+)$", "\\1", $file->filename)); if ($ext != "gpx") { form_set_error('file', t('A GPX file must be provided.')); } else { $node->file = file_save_upload($file, file_directory_path(), false); $node->current_file = $node->file->filepath; } } else { $current_file = isset($_POST['edit']['current_file']) ? $_POST['edit']['current_file'] : ''; if (file_exists($current_file)) { $node->file = file_check_local($current_file); $node->current_file = $node->file->filepath; } } return $file; } /** * Implementation of hook_validate(). * * Verify that there is a file attached to the node. */ function track_validate(&$node) { $file = track_validate_file($node); // Make sure there is an upload or an existing file. if (!$file && !file_exists($node->current_file) && !file_exists($node->file->filepath)) { form_set_error('file', t('A file must be provided.')); } } /** * Implementation of hook_execute(). * * If a file was uploaded save it before updating the database. */ function track_execute(&$node) { $file = track_validate_file($node); // Make sure there is an upload or an existing file. if (!$file && !file_exists($node->current_file)) { form_set_error('file', t('A file must be provided.')); } } /** * Implementation of hook_load(). * * The node is being loaded. Load the file's information from the database so * it can be added to the node. */ function track_load($node) { $extras = new StdClass(); $extras->file = db_fetch_object(db_query('SELECT filename, filepath, '. 'latstart,lonstart,latmin,latmax,lonmin,lonmax,length,dzminu,dzplus,zmin,zmax'. ' FROM {track} WHERE nid = %d', $node->nid)); return $extras; } /** * Implementation of hook_insert(). * * The node is being created, save the file's infomation to the database. */ function track_insert($node) { track_validate($node); $file = $node->file; $aGPXfile = new GPX_file(); $aGPXfile->LoadFromFile($file->filepath); $aGPXfile->getInfos($latstart,$lonstart,$latmin,$latmax,$lonmin,$lonmax,$length,$dzminu,$dzplus,$zmin,$zmax); db_query("INSERT INTO {track} (nid, filename, filepath, ". "latstart,lonstart,latmin,latmax,lonmin,lonmax,length,dzminu,dzplus,zmin,zmax". ") VALUES (%d, '%s', '%s', %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)", $node->nid, $file->filename, $file->filepath, $latstart,$lonstart,$latmin,$latmax,$lonmin,$lonmax,$length,$dzminu,$dzplus,$zmin,$zmax ); } /** * Implementation of hook_delete(). * * The node is being delete, remove the file and any information. */ function track_delete($node) { file_delete($node->filepath); db_query("DELETE FROM {track} WHERE nid = %d", $node->nid); } // this is added to support 5.x admin settings. function track_admin_settings() { $form['API'] = array( '#type' => 'textfield', '#title' => t('Google Maps key'), '#default_value' => variable_get('googlemapskey', 'AAAAAAAAAAA'), '#size' => 120, '#maxlength' => 255, '#description' => t('Required by Google. ').l(t('You will be able to generate your key here'), 'http://www.google.com/apis/maps/signup.html') ); return system_settings_form($form); } /* function track_settings() { $form['googlemapskey'] = array( '#type' => 'textfield', '#title' => t('Google Maps key'), '#default_value' => variable_get('googlemapskey', 'AAAAAAAAAAA'), '#size' => 120, '#maxlength' => 255, '#description' => t('Required by Google. ').l(t('You will be able to generate your key here'), 'http://www.google.com/apis/maps/signup.html') ); return $form; } */