Advertisement
kirill-k2

GPSies+ userscript for Greasemonkey.user

Aug 19th, 2014
1,054
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name GPSies+
  3. // @namespace k2lab.org/gm/gpsies/
  4. // @description Add some features to GPSies.com (route annotation)
  5. // @author Kirill Kozlovskiy
  6. // @version 3.2
  7. // @downloadURL https://pastebin.com/raw/6TxYBihx
  8. // @match *://*.gpsies.com/map.do*
  9. // @match *://*.gpsies.com/editTrack.do*
  10. // @match *://*.gpsies.com/createTrack.do*
  11. // @match *://*.gpsies.com/mapOnly.do*
  12. // @match *://*.gpsies.com/mapUser.do*
  13. // @match *://*.gpsies.com/trackList.do*
  14. // @match *://*.gpsies.com/mapFolder.do*
  15. // @match *://*.gpsies.com/userList.do*
  16. // @match *://*.gpsies.com/upload.do*
  17. // @exclude file://*
  18. // @grant   none
  19. // @require http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
  20. // ==/UserScript==
  21. /*
  22. This code is licenced under the GPL
  23. www.fsf.org/licensing/licenses/gpl.html
  24. */
  25.  
  26. (function() {
  27.  
  28. this.$ = this.jQuery = jQuery.noConflict(true);
  29.  
  30. var LOG = function () {};
  31. LOG = (! "console" in window) ? function () {} : console.log;
  32.  
  33. var __routeWaypoints = [ "Straight", "Left", "TSLL", "TSHL", "Right", "TSLR", "TSHR", "TU"  ];
  34. var __routeWaypoints2RUS = { "Straight": "Прямо", "Left": "Налево", "TSLL": "Левее", "TSHL": "Резко налево", "Right": "Направо", "TSLR": "Правее", "TSHR": "Резко направо", "TU": "Разворот"  };
  35.  
  36. var __controlPointPrefix = "КП";
  37.  
  38.     function isRouteWaypoint(wpt) {
  39.         for (var i = 0, j = __routeWaypoints.length; i < j; i++) {
  40.             if (__routeWaypoints[i] == wpt.type) {
  41.                 return true;
  42.             }
  43.         }
  44.         return false;
  45.     }
  46.  
  47.     function isWptControlPoint(wptName) {
  48.         return (wptName.indexOf(__controlPointPrefix) == 0)
  49.     }
  50.  
  51.  
  52. function GPSiesRouteAnnotation() {
  53.  
  54.    
  55.     var __result_odo_multiplier__ = 0.001;
  56.     var __result_odo_round_to__ = 1;
  57.     var __probe_radius__ = 500;
  58.     var __start_hour__ = 8;
  59.  
  60.     function props(obj) {
  61.         result = "";
  62.         for (property in obj) {
  63.             result += property + ':' + obj[property]+'; ';
  64.         }
  65.    
  66.         return result;
  67.     }
  68.  
  69.     function formatHours(someHours) {
  70.         var hours = Math.floor(someHours)
  71.         var minutes = Math.round(60 * (someHours - hours));
  72.         var days = Math.floor(hours / 24);
  73.        
  74.         return (days > 0 ? (days+1)+"д."+(hours % 24) : hours ) + ':' + (minutes < 10 ? '0' : '') + minutes;
  75.     }
  76.  
  77.  
  78.     annotateRoute = function() {
  79.  
  80.  
  81.         this.totalDistance = 0;
  82.  
  83.         advWaypoint = function(wpt) {
  84. //          LOG("[GPSies+] adding wpt :", props(wpt));
  85.  
  86.             this.waypoint = wpt;
  87.             this.distance = -1;
  88.  
  89.             this._latlng = new L.LatLng(wpt.lat, wpt.lon);
  90.             this._closesPoint = null;
  91.             this._closesDist = -1;
  92.    
  93.             this.checkDistance = function (latlng, odo = -1) {
  94.                 d = latlng.distanceTo(this._latlng);
  95.                 if (this._closesDist < 0 || d < this._closesDist) {
  96.                     this._closesDist = d;
  97.                     this._closesPoint = latlng;
  98.                     this.distance = odo;
  99.                 }
  100.             }
  101.  
  102.             this.getLatLng = function() {
  103.                 return this._latlng;
  104.             }
  105.  
  106.             return this;
  107.         }
  108.  
  109.         function formatWaypoint(wpt) {
  110.             var metricDistance = (wpt.distance * __result_odo_multiplier__)
  111.             var metricTotalDistance = (totalDistance  * __result_odo_multiplier__ )
  112.  
  113.             var distance = metricDistance.toFixed(__result_odo_round_to__);
  114.             var ret;
  115.  
  116.             // 15-30 км/час для дистанций до 600 км и 13,5-30 км/час для дистанций от 600 до 1000 км
  117.  
  118.             // TODO: Magic Numbers !!!
  119.  
  120.             var minSpeed = 15;
  121.             if (metricTotalDistance > 650) {
  122.                 minSpeed = 13.3;
  123.             }
  124.  
  125.  
  126.             // Оч. странный алгоритм. Суть - регрессия максимальной скорости от 35 на 0 до 30 на 1050
  127.             var maxSpeed = 30 + 5 * (1050 - metricDistance) / 1050;
  128.  
  129.  
  130.             ret = "[" + distance + "] " + wpt.waypoint.name;
  131.  
  132.             ret += ( isWptControlPoint(wpt.waypoint.name) ? " {"
  133.                 + (formatHours(__start_hour__ + (metricDistance / maxSpeed)))
  134.                 + "-"
  135.                 + (formatHours(__start_hour__ + (metricDistance / minSpeed))) +"}"
  136.                     : "");
  137.  
  138.             ret += (wpt.waypoint.desc.length > 0 ? ": " + wpt.waypoint.desc : "" );
  139.  
  140.             LOG("ret="+ret);
  141.  
  142.             return ret;
  143.  
  144.         }
  145.    
  146.         // Create array of waypoints to operate
  147.         var _wpa = waypointsArray;
  148.         var wayPoints = [];
  149.  
  150.         if (_wpa.size() <= 0) {
  151.             LOG("[GPSies+] GPSiesRouteAnnotation - Nothing to do: no waypoints found!");
  152.             return;
  153.         }
  154.  
  155.         for (var wi=0; wi < _wpa.size(); wi++) {
  156.             wayPoints.push( new this.advWaypoint(_wpa[wi]) );
  157.         }
  158. //      LOG("[GPSies+] wpa= ", props(wpa));
  159.  
  160.         // Let's get the closes point to each WPT and calculate  some distance
  161.         var polylineLL = polyline.getLatLngs();
  162.  
  163.         this.totalDistance = 0;
  164.  
  165.         var currPnt = null;
  166.         var prevPnt = null;
  167.  
  168.         if (polylineLL.size() > 0) {
  169.             currPnt = polylineLL[0];
  170.             prevPnt = polylineLL[0];
  171.         }
  172.  
  173.         for (var i=0; i < polylineLL.size(); i++) {
  174.             currPnt = polylineLL[i];
  175.  
  176.             for (var wi=0; wi < wayPoints.length; wi++) {
  177.  
  178. //              // Chech for the nearest point
  179. //              wpa[wi].checkDistance(currPnt, this.totalDistance);
  180.  
  181.                 // Chech for the nearest projection
  182.                 var wpaPnt = wayPoints[wi].getLatLng();
  183.                 var projPnt = map.unproject ( L.LineUtil.closestPointOnSegment(
  184.                         map.project(wpaPnt),
  185.                         map.project(prevPnt),
  186.                         map.project(currPnt)
  187.                     ));
  188.  
  189.                 var radius = wpaPnt.distanceTo(projPnt);
  190.                 if (radius <= __probe_radius__) {
  191. //                  LOG("Got it! i=",i,"; wi=",wi,"; totalDistance=", this.totalDistance + "; D=" + (this.totalDistance + prevPnt.distanceTo(projPnt)));
  192.                     wayPoints[wi].checkDistance(projPnt, (0.0 + this.totalDistance + prevPnt.distanceTo(projPnt)));
  193.                 }
  194.             }
  195.  
  196.             this.totalDistance += currPnt.distanceTo(prevPnt);
  197.             prevPnt = currPnt;
  198.         }
  199.  
  200.         // Sorting by distance from start point
  201.         wayPoints.sort(function(a, b) {
  202.                 return a.distance - b.distance;
  203.             });
  204.    
  205.         result = [];
  206.  
  207.         for (var wi=0; wi < wayPoints.length; wi++) {
  208.             // DEBUG
  209. //            map.addLayer( new L.Marker(wpa[wi]._closesPoint, { title: wpa[wi].desc }) );
  210.  
  211.             if (wayPoints[wi].distance >= 0 ) {
  212.                 result.push( formatWaypoint(wayPoints[wi]) );
  213.             }
  214.         }
  215.        
  216.         return result;
  217.     }
  218.  
  219.     updateAnnotation = function () {
  220.  
  221.         LOG("[GPSies+]  updating annotation...");
  222.  
  223.         __result_odo_multiplier__ = parseFloat($("#odo_multiplier").val());
  224.         __result_odo_round_to__ = parseFloat($("#odo_round_to").val());
  225.         __probe_radius__ = parseFloat($("#probe_radius").val());
  226.         __start_hour__ = parseInt($("#start_hour").val(), 10);;
  227.  
  228.         LOG("__result_odo_multiplier__ "+ __result_odo_multiplier__);
  229.         LOG("__probe_radius__ " + __probe_radius__);
  230.  
  231.         $("#routeAnnotation").empty();
  232.         $("#routeAnnotation").append('<p>'+this.annotateRoute().join('<br />')+'</p>');
  233.  
  234.         return false;
  235.     }
  236.  
  237.     updateCUE = function () {
  238.  
  239.         LOG("[GPSies+]  updating CUE...");
  240.  
  241.             for (var i = 0, j = waypointsArray.length; i < j; i++) {
  242.                 wpt = waypointsArray[i] ;
  243.                 if (isRouteWaypoint(wpt)) {
  244.                     wpt.name = __routeWaypoints2RUS[wpt.type];
  245.  
  246.                     if (map.hasLayer(wpt.marker)) {
  247.                         map.removeLayer(wpt.marker);
  248.                         map.addLayer(wpt.marker);
  249.                     }
  250.  
  251.                 }
  252.             }
  253.  
  254.         return false;
  255.     }
  256.  
  257.     updateInterface = function () {
  258.  
  259.         if ($("#contentboxRouteAnnotation").length > 0) {
  260.             LOG("[GPSies+] GPSiesRouteAnnotation WTF?! Got old interface. Are you cheating me?");
  261.             $("#contentboxRouteAnnotation").remove();
  262.         }
  263.  
  264.         // Check for the page elements
  265.         if ($("#contentboxFlyoutChart").length > 0 ) {
  266.             LOG("[GPSies+] map edit on editTrack.do detected!");
  267.  
  268.             $("#contentboxFlyoutChart").after(
  269. '<div id="contentboxRouteAnnotation" class="panel panel-default panel-form"> \
  270.     <div class="panel-heading"> \
  271.         <a data-toggle="collapse" data-parent="#accordion" href="#routeAnnotationShow" class="collapsed">Route Annotation <small>(GPSies+)</small> \
  272.         <i class="fa fa-caret-down pull-right"></i><i class="fa fa-caret-up pull-right"></i> \
  273.    </a> \
  274.  </div> \
  275.     <div id="routeAnnotationShow" class="panel-collapse collapse"> \
  276.         <div class="panel-body" id="routeAnnotationDiv"></div> \
  277.     </div> \
  278. </div>');
  279.  
  280. //      $("#routeAnnotationShow").before('');
  281.  
  282.         } else if ($("#recommendFriend").length > 0 ) {
  283.             LOG("[GPSies+]  map view on map.do detected!");
  284.  
  285.             $("#recommendFriend").after(
  286. '<div id="contentboxRouteAnnotation" class="panel panel-default panel-form"> \
  287.     <div class="panel-heading"> \
  288.         <a data-toggle="collapse" data-parent="#accordion" href="#routeAnnotationShow" class="collapsed">Route Annotation <small>(GPSies+)</small> \
  289.         <i class="fa fa-caret-down pull-right"></i><i class="fa fa-caret-up pull-right"></i> \
  290.    </a> \
  291.  </div> \
  292.     <div id="routeAnnotationShow" class="panel-collapse collapse"> \
  293.         <div class="panel-body" id="routeAnnotationDiv"></div> \
  294.     </div> \
  295. </div>');
  296.  
  297.         }
  298.  
  299.         if (! $("#routeAnnotationDiv").length > 0 ) {
  300.             LOG("[GPSies+]  nothing to do - no known elements found!");
  301.             return;
  302.         }
  303.    
  304.         $("#routeAnnotationDiv").append(
  305. '<div class="row"> \
  306.     <div class="col-sm-3"><div class="form-group"> \
  307.         <label for="start_hour">Starting hour</label> \
  308.         <input id="start_hour" class="form-control" type="text" onchange="" value="' + __start_hour__ + '" name="start_hour"> \
  309.     </div></div> \
  310.     <div class="col-sm-3"><div class="form-group"> \
  311.         <label for="odo_multiplier">ODO Multiplier</label> \
  312.         <input id="odo_multiplier" class="form-control" type="text" onchange="" value="' + __result_odo_multiplier__ + '" name="odo_multiplier"> \
  313.     </div></div> \
  314.     <div class="col-sm-3"><div class="form-group"> \
  315.         <label for="odo_round_to">ODO Round</label> \
  316.         <input id="odo_round_to" class="form-control" type="text" onchange="" value="' + __result_odo_round_to__ + '" name="odo_round_to"> \
  317.     </div></div> \
  318.     <div class="col-sm-3"><div class="form-group"> \
  319.         <label for="probe_radius">Probe radius, m</label> \
  320.         <input id="probe_radius" class="form-control" type="text" onchange="" value="' + __probe_radius__ + '" name="probe_radius"> \
  321.     </div></div> \
  322. </div> \
  323. ');    
  324.  
  325.         $("#routeAnnotationDiv").append('<div class="row"><div class="col-sm-6"> \
  326. <ul class="list-inline"> \
  327. <li><a id="runUpdateAnnotation" class="btn btn-default" onclick="return false;" href="#">Create/Update Annotation</a></li> \
  328. <li><a id="runUpdateCUE" class="btn btn-default" onclick="return false;" href="#">Simplify CUE</a></li> \
  329. </ul> \
  330. </div></div> \
  331. ' );
  332.    
  333.         $("#runUpdateAnnotation").click(function() {
  334.             updateAnnotation();
  335.             return false;
  336.         });
  337.         $("#runUpdateCUE").click(function() {
  338.             updateCUE();
  339.             return false;
  340.         });
  341.  
  342.         $("#routeAnnotationDiv").append('<div class="row"><div class="col-sm-12"><b>Annotation:</b><br /><br /> <div id="routeAnnotation"><i>Nothing yet...</i></div> </div></div>');
  343.  
  344.     }
  345.  
  346.     this.run = function() {
  347. //          LOG ("[GPSies+] GPSiesRouteAnnotation.run");
  348.  
  349.         updateInterface();
  350.     };
  351. }
  352.  
  353. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  354.  
  355. function GPSiesWaypointToggler() {
  356.  
  357.     toggleRouteWaypoints = function () {
  358.         LOG("[GPSies+] toggleRouteWaypoints ()");
  359.    
  360.         if (isWaypoints()) {
  361.             for (var i = 0, j = waypointsArray.length; i < j; i++) {
  362.                 if (isRouteWaypoint(waypointsArray[i])) {
  363.                     if (map.hasLayer(waypointsArray[i].marker)) {
  364.                         map.removeLayer(waypointsArray[i].marker)
  365.                     } else if (!map.hasLayer(waypointsArray[i].marker)) {
  366.                         map.addLayer(waypointsArray[i].marker)
  367.                     }
  368.                 }
  369.             }
  370.         } else {
  371.             LOG("[GPSies+] No waypoints found to toggle!");
  372.         }
  373.     };
  374.  
  375.     toggleNonControlPoints = function () {
  376.         LOG("[GPSies+] toggleNonControlPoints ()");
  377.    
  378.         if (isWaypoints()) {
  379.             for (var i = 0, j = waypointsArray.length; i < j; i++) {
  380. //              LOG(props(waypointsArray[i]));
  381.                 if (! isWptControlPoint(waypointsArray[i].name)) {
  382.                     if (map.hasLayer(waypointsArray[i].marker)) {
  383.                         map.removeLayer(waypointsArray[i].marker)
  384.                     } else if (!map.hasLayer(waypointsArray[i].marker)) {
  385.                         map.addLayer(waypointsArray[i].marker)
  386.                     }
  387.                 }
  388.             }
  389.         } else {
  390.             LOG("[GPSies+] No waypoints found to toggle!");
  391.         }
  392.     };
  393.  
  394.  
  395.     updateInterface = function () {
  396.  
  397.         if ($("#wptTogglerPane").length > 0) {
  398.             LOG("[GPSies+] GPSiesWaypointToggler - WTF?! Got old interface. Are you cheating me?");
  399.             $("#wptTogglerPane").remove();
  400.         }
  401.  
  402.         // Check for the navigation pane
  403.         if ($("#navMore").length > 0 ) {
  404.             LOG("[GPSies+] map view detected!");
  405.  
  406.             $("li div input#waypointToggle").parent().parent()         
  407.                 .after('<div id="wptTogglerPane" style="display: block;"></div>');
  408.  
  409.         }
  410.  
  411. //      if (! $("div#wptTogglerPane").length > 0 ) {
  412. //          LOG("[GPSies+] GPSiesWaypointToggler - nothing to do - no known elements found!");
  413. //          return;
  414. //      }
  415.  
  416.         $("div#wptTogglerPane").append('<label style="vertical-align: text-bottom; cursor: pointer;" id="runToggleRouteWaypoints" onclick="return false;" href="#"> Toggle Route</label>' ).append('<label style="vertical-align: text-bottom; cursor: pointer;" id="runToggleNonControlPoints" onclick="return false;" href="#"> Toggle non-CP</label>' );
  417.        
  418.         $("#runToggleRouteWaypoints").click(function() {
  419.             toggleRouteWaypoints();
  420.             return false;
  421.         });
  422.         $("#runToggleNonControlPoints").click(function() {
  423.             toggleNonControlPoints();
  424.             return false;
  425.         });
  426.  
  427.  
  428.     };
  429.  
  430.     this.run = function() {
  431. //          LOG ("[GPSies+] GPSiesWaypointToggler.run");
  432.  
  433.         updateInterface();
  434.     };
  435.  
  436. }
  437.  
  438. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  439.  
  440. function GPSiesUpdateList() {
  441.  
  442.     updateInterface = function () {
  443.  
  444.         // Check for the page elements
  445.         if ($("#displayTable").length > 0 ) {
  446.             LOG("[GPSies+] map list detected!");
  447.  
  448.             $("h5 a span").each(function (index) { $( this ).text(this.title.replace(/^\S+\s/,""));} );
  449.  
  450.         } else {
  451.             LOG("[GPSies+] GPSiesUpdateList nothing to do - no known elements found!");
  452.             return;
  453.         }
  454.     }
  455.  
  456.     this.run = function() {
  457. //          LOG ("[GPSies+] GPSiesUpdateList.run");
  458.  
  459.         updateInterface();
  460.     };
  461. }
  462.  
  463. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  464.  
  465. function GPSiesUploadDefaults() {
  466.  
  467.     updateInterface = function () {
  468.  
  469.         // Check for the page elements
  470.         if ($("#uploadForm").length > 0 && /\/upload.do$/.test($("link[rel='canonical']").prop('href')) ) {
  471.             LOG("[GPSies+] upload form detected!");
  472.            
  473.             $("input#mountainbiking").prop('checked', true);
  474.             $("input#gpsRecorded").prop('checked', true);
  475.            
  476.             $("input#flat").prop('checked', true);
  477.             $("input#trackCombine").prop('checked', true);
  478.  
  479.  
  480.             //<option value="78821">4th-k.2016 Кубанские Четвергушки</option>
  481.             $("select#userFolder").val("78821");
  482.             //<option value="78821">4th-k.2017 Кубанские Четвергушки</option>
  483. //          $("select#userFolder").val("78855");
  484.            
  485.            
  486.            
  487.             $("input#websiteUrl").val("http://kirill-k2.blogspot.com/search/label/velo");
  488.            
  489.             $("input[name='formFile']").change(function (){
  490.          var fileName = $(this).val();
  491.                  var nameField = $("input[name='filename']");
  492.                  if ( nameField && !nameField.val()) {
  493.                      
  494.                      // cut file type and OruxMaps date suffix
  495.                      // i.e. all like '__20160402_1242.gpx'
  496.                      nameField.val(fileName.replace( /(__[\d_]{11,13})?\.\w{3,4}$/, "" ));
  497.                  }
  498.                 LOG(fileName + "!"+nameField);
  499.       });
  500.            
  501.             // Scroll down if no error
  502.             if ( $("ul.error:visible").length == 0) {
  503.                 $("html, body").scrollTop($(document).height() - $(window).height());
  504.            
  505.                // Auto open file dialog
  506.                $("input[name='formFile']").focus().trigger('click');
  507.           }
  508.         } else if ($("div#mainBox").length > 0 && $("a#directLink").length == 0) {
  509.             LOG("[GPSies+] map view detected!");
  510.  
  511.             if ( /\/(upload.do|editTrack.do)$/.test($("link[rel='canonical']").prop('href')) ) {
  512.            
  513.               var fileURL = 'http://www.gpsies.com/map.do?fileId='+$("form#downloadForm input#fileId").val();
  514. //            window.location.replace(fileURL);
  515.                 window.history.pushState("","", fileURL);
  516. //          $("div#mainBox").prepend('<a id="directLink" href="'+fileURL+'">'+fileURL+'</a><br />');
  517.             }
  518.         } else {
  519.             LOG("[GPSies+] GPSiesUploadDefaults nothing to do - no known elements found!");
  520.             return;
  521.         }
  522.     }
  523.  
  524.     this.run = function() {
  525. //          LOG ("[GPSies+] GPSiesUploadDefaults.run");
  526.  
  527.         updateInterface();
  528.            
  529.              
  530.         };
  531. }
  532. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  533.  
  534.  
  535. loadall = function () {
  536.     new GPSiesRouteAnnotation().run();
  537.         new GPSiesWaypointToggler().run();
  538.         new GPSiesUpdateList().run();
  539.       new GPSiesUploadDefaults().run();
  540.  
  541. };
  542.  
  543. LOG ("[GPSies+] is loading... JQuery info: ", $().jquery );
  544.  
  545. $(document).ready( loadall );
  546. $(window).load( loadall );
  547.  
  548. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement