1 if (Garmin == undefined) var Garmin = {}; 2 /** Copyright 2007 Garmin Ltd. or its subsidiaries. 3 * 4 * Licensed under the Apache License, Version 2.0 (the 'License') 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an 'AS IS' BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * @fileoverview Garmin.DeviceControl A mostly deprecated library of GPS track and waypoint data structures along with parsing tools. 17 * @deprecated use Garmin.GpxActivityFactory instead 18 * 19 * @author Developer developer.connect.at.garmin.com 20 * @version 1.0 21 */ 22 23 /** A waypoint represents a stored location. 24 * Equivalent to a <wpt> in GPX format 25 * Note: this class is only used by Garmin.Geocode but otherwise has been replaced by Garmin.Activity. 26 * 27 * @class Garmin.WayPoint 28 * @constructor 29 * @param {Number} lat 30 * @param {Number} lng 31 * @param {Number} elev 32 * @param {String} name 33 */ 34 Garmin.WayPoint = function(lat, lng, elev, name, addrdetails, desc, sym, type, cmt){}; 35 Garmin.WayPoint = Class.create(); 36 Garmin.WayPoint.prototype = { 37 38 /** Prototype constructor 39 */ 40 initialize: function(lat, lng, elev, name, addrdetails, desc, sym, type, cmt) { 41 this.lat = lat; 42 this.lng = lng; 43 this.name = name; 44 this.addrdetails = addrdetails; 45 46 // Get city, streetaddr, and zip data. 47 if( this.addrdetails ) { 48 this._initSubArea(); 49 } 50 this.elev = elev; 51 this.desc = desc; 52 this.sym = sym; 53 this.type = type; 54 this.cmt = cmt; 55 this.date = null; 56 }, 57 58 /** Initializes the subadministrative area, as designated by Google Maps API (see http://code.google.com/apis/maps/documentation/services.html#Geocoding_Structured). 59 * Apparently some locations have Locality while others don't, so this function takes care of both. 60 */ 61 _initSubArea: function() { 62 63 if( this.addrdetails.Country ) { 64 this.country = this.addrdetails.Country.CountryNameCode; 65 if (this.addrdetails.Country.AdministrativeArea) { 66 this.state = this.addrdetails.Country.AdministrativeArea.AdministrativeAreaName; 67 68 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea ) { 69 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality) { 70 this.city = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName; 71 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare ) { 72 this.streetaddr = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName; 73 } 74 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode ) { 75 this.zip = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber; 76 } 77 } else { 78 this.city = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName; 79 80 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Thoroughfare ) { 81 this.streetaddr = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.Thoroughfare.ThoroughfareName; 82 } 83 84 if( this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.PostalCode ) { 85 this.zip = this.addrdetails.Country.AdministrativeArea.SubAdministrativeArea.PostalCode.PostalCodeNumber; 86 } 87 } 88 } else { 89 if( this.addrdetails.Country.AdministrativeArea.Locality) { 90 this.city = this.addrdetails.Country.AdministrativeArea.Locality.LocalityName; 91 if( this.addrdetails.Country.AdministrativeArea.Locality.Thoroughfare ) { 92 this.streetaddr = this.addrdetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName; 93 } 94 if( this.addrdetails.Country.AdministrativeArea.Locality.PostalCode ) { 95 this.zip = this.addrdetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber; 96 } 97 } else { 98 this.city = this.addrdetails.Country.AdministrativeArea.SubAdministrativeAreaName; 99 100 if( this.addrdetails.Country.AdministrativeArea.Thoroughfare ) { 101 this.streetaddr = this.addrdetails.Country.AdministrativeArea.Thoroughfare.ThoroughfareName; 102 } 103 104 if( this.addrdetails.Country.AdministrativeArea.PostalCode ) { 105 this.zip = this.addrdetails.Country.AdministrativeArea.PostalCode.PostalCodeNumber; 106 } 107 } 108 } 109 } 110 } 111 }, 112 113 /** Get waypoint symbol usually associated with a display icon. 114 * @type String 115 * @return The symbol of this waypoint 116 */ 117 getSymbol: function() { 118 return this.sym; 119 }, 120 121 /** Get waypoint type. 122 * @type String 123 * @return The type of this waypoint 124 */ 125 getType: function() { 126 return this.type; 127 }, 128 129 /** Get waypoint name. 130 * @type String 131 * @return The name of this waypoint 132 */ 133 getName: function() { 134 return this.name; 135 }, 136 137 /** Get waypoint address XML string. Uses the extension element to generate XML address format listed in the 138 * GPX Extensions v3 schema: http://www8.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd 139 * 140 * @type String 141 * @return The address of this waypoint, as an XML string with the outermost element being gpxx::Address 142 */ 143 getAddress: function() { 144 return (this.addrdetails != null) ? "<gpxx:Address><gpxx:StreetAddress>" 145 + this.getStreetAddr() + "</gpxx:StreetAddress><gpxx:City>" 146 + this.getCity() + "</gpxx:City><gpxx:State>" 147 + this.getState() + "</gpxx:State><gpxx:PostalCode>" 148 + this.getZip() + "</gpxx:PostalCode></gpxx:Address>" : null; 149 }, 150 151 /** Get country that the waypoint is located in, according to Google Maps API. 152 * See http://www.google.com/apis/maps/ for details. 153 * @type String 154 * @return The country the waypoint is located in. 155 */ 156 getCountry: function() { 157 return this.country; 158 }, 159 160 /** Get state that the waypoint is located in, according to Google Maps API. 161 * See http://www.google.com/apis/maps/ for details. 162 * @type String 163 * @return The state the waypoint is located in. 164 */ 165 getState: function() { 166 return this.state; 167 }, 168 169 /** Get city that the waypoint is located in, according to Google Maps API. 170 * See http://www.google.com/apis/maps/ for details. 171 * @type String 172 * @return The city the waypoint is located in. 173 */ 174 getCity: function() { 175 return this.city; 176 }, 177 178 /** Get street address that the waypoint is located in, according to Google Maps API. 179 * See http://www.google.com/apis/maps/ for details. 180 * @type String 181 * @return The street address the waypoint is located in. 182 */ 183 getStreetAddr: function() { 184 return this.streetaddr; 185 }, 186 187 /** Get zip code that the waypoint is located in, according to Google Maps API. 188 * See http://www.google.com/apis/maps/ for details. 189 * @type String 190 * @return The zip code the waypoint is located in. 191 */ 192 getZip: function() { 193 return this.zip; 194 }, 195 196 /** Get waypoint description. 197 * @type String 198 * @return A description of this waypoint 199 */ 200 getDescription: function() { 201 return this.desc; 202 }, 203 204 /** Shortcut for directly getting the lat value 205 * 206 * @type Number 207 * @return The value of the latitude for this point 208 */ 209 getLat: function() { 210 return this.lat; 211 }, 212 213 /** Shortcut for directly getting the longitude value 214 * 215 * @type Number 216 * @return The value of the longitude for this point 217 */ 218 getLng: function() { 219 return this.lng; 220 }, 221 222 /** Shortcut for directly getting the elevation value 223 * 224 * @type Number 225 * @return The value of the elevation for this point 226 */ 227 getElev: function() { 228 return this.elev; 229 }, 230 231 /** Get comment. 232 * 233 * @type String 234 * @return The value of the comment for this point 235 */ 236 getComment: function() { 237 return this.cmt; 238 }, 239 240 241 /** Shortcut for directly getting the date/time 242 * 243 * @type Garmin.DateTimeFormat 244 * @return The DateTimeFormat object for this point 245 */ 246 getDate: function() { 247 return this.date; 248 }, 249 250 toString: function() { 251 return "Waypoint: (" + this.getLat() + ", " + this.getLng() + ")"; 252 } 253 }; 254 255 256 /** TrackPoint class reprsents a point from a track.<br> 257 * A TrackPoint contains an associative array of measurements, which can be retrieved with a 258 * #getMeasurement call passing in a string index.<br> 259 * Equivalent to a <trkpt> in GPX format 260 * @deprecated use Garmin.Activity instead 261 * @class Garmin.TrackPoint 262 * @constructor 263 */ 264 Garmin.TrackPoint = function(){}; 265 Garmin.TrackPoint = Class.create(); 266 Garmin.TrackPoint.prototype = { 267 /** prototype constructor 268 */ 269 initialize: function() { 270 this.measurements = null; 271 this.date = null; 272 }, 273 274 /** Get a Measurement from this TrackPoint 275 * If the measurement does not exist - return null 276 * 277 * @param {String} context of the measurement we would like to get 278 * @type Object 279 * @return A measurement object (important to remember it's value is in measurementObject.value!) 280 * or null if the measurement doesn't exist 281 */ 282 getMeasurement: function(context) { 283 var meas = this.measurements[context]; 284 if(meas == undefined) { 285 meas = null; 286 } 287 return meas; 288 }, 289 290 /** Determines if this TrackPoint point is valid for determing location 291 * @type Boolean 292 * @return True if lat/lon exist, false otherwise 293 */ 294 isValidLocation: function() { 295 return ( (this.getLat() != "null") && (this.getLat() != null) && (this.getLng() != "null") && (this.getLng() != null)); 296 }, 297 298 /** Shortcut for directly getting the lat value 299 * 300 * @type Number 301 * @return The value of the latitude for this point 302 */ 303 getLat: function() { 304 var meas = this.getMeasurement( "latitude" ); 305 if(meas == null) { 306 return null; 307 } else { 308 return meas.value; 309 } 310 }, 311 312 /** Shortcut for directly getting the longitude value 313 * 314 * @type Number 315 * @return The value of the longitude for this point 316 */ 317 getLng: function() { 318 var meas = this.getMeasurement( "longitude" ); 319 if(meas == null) { 320 return null; 321 } else { 322 return meas.value; 323 } 324 }, 325 326 /** Shortcut for directly getting the elevation value 327 * 328 * @type Number 329 * @return The value of the elevation for this point 330 */ 331 getElev: function() { 332 var meas = this.getMeasurement( "elevation" ); 333 if(meas == null) { 334 return null; 335 } else { 336 return meas.value; 337 } 338 }, 339 340 /** Shortcut for directly getting the date/time 341 * 342 * @type Garmin.DateTimeFormat 343 * @return The time for this point 344 */ 345 getDate: function() { 346 return this.date; 347 }, 348 349 toString: function() { 350 return "TrackPoint Point: (" + this.getLat() + ", " + this.getLng() + ")"; 351 } 352 }; 353 354 355 356 /** Equivalent to a <trkseg> in GPX format 357 * 358 * @deprecated use Garmin.Activity instead 359 * @class Garmin.TrackSegment 360 * @constructor 361 */ 362 Garmin.TrackSegment = function(){}; 363 Garmin.TrackSegment = Class.create(); 364 Garmin.TrackSegment.prototype = { 365 366 initialize: function() { 367 this.points = new Array(); 368 }, 369 370 addTrackPoint: function(trackPointObject) { 371 this.points.push(trackPointObject); 372 }, 373 374 /** Find the nearest valid point to the index given 375 * 376 * @param index is the index 377 * @param incDirection is an int in the direction we'd like to look positive 378 * nums are forward, negative nums are backwards 379 * 380 * @type Garmin.TrackPoint 381 * @return The nearest point (possibly the index) that has a validLocation 382 */ 383 findNearestValidLocationPoint: function(index, incDirection) { 384 if( this.getPoint( index ).isValidLocation() ) { 385 return this.getPoint( index ); 386 } else if( index >= this.getLength() ) { 387 return this.findNearestValidLocationPoint(this.getLength()-1, -1); 388 } else { 389 return this.findNearestValidLocationPoint(index+incDirection, incDirection); 390 } 391 }, 392 393 /** Get the point specified on the track 394 * If the number is negative, get's the first 395 * If it's larger than possible, get's the last 396 * Otherwise it gets the number requested 397 * 398 * @param {Number} index is the point we want 399 * @type Garmin.TrackPoint 400 * @return A TrackPoint that fits the pattern described above 401 */ 402 getPoint: function(index) { 403 index = Math.floor(index); 404 405 if(index >= this.getLength()) { 406 return this.getEnd(); 407 } 408 if(index <= 0) { 409 return this.getStart(); 410 } 411 412 return this.points[index]; 413 }, 414 415 /** Quick method to get the first point 416 * @type Garmin.TrackPoint 417 * @return The first point of this track 418 */ 419 getStart: function() { 420 return this.points[0]; 421 }, 422 423 /** Quick method to get the last point 424 * @type Garmin.TrackPoint 425 * @return The last point of this track 426 */ 427 getEnd: function() { 428 return this.points[this.getLength()-1]; 429 }, 430 431 /** Get the latitude for the start point of this segment 432 * @type Number 433 * @return Latitude of the first trackpoint 434 */ 435 getStartLat: function() { 436 return this.getStart().getLat(); 437 }, 438 439 /** Get the longitude for the start point of this segment 440 * @type Number 441 * @return Longitude of the first trackpoint 442 */ 443 getStartLng: function() { 444 return this.getStart().getLng(); 445 }, 446 447 /** Get the data/time for the start point of this segment 448 * @return date/time of the first trackpoint 449 * @type Garmin.DateTimeFormat 450 */ 451 getStartDate: function() { 452 return this.getStart().getDate(); 453 }, 454 455 /** Get the data/time for the end point of this segment 456 * @type Garmin.DateTimeFormat 457 * @return Date/time of the last trackpoint 458 */ 459 getEndDate: function() { 460 return this.getEnd().getDate(); 461 }, 462 463 /** Get the total duration for this track segment 464 * @type String 465 * @return String of Duration (hh:mm:ss) 466 */ 467 getDuration: function() { 468 return this.getStartDate().getDurationTo(this.getEndDate()); 469 }, 470 471 /** Get the total number of trackpoints in this segment 472 * @type Number 473 * @return Total number of trackpoints in this segment 474 */ 475 getLength: function() { 476 return this.points.length; 477 }, 478 479 /** String representation 480 * @type String 481 */ 482 toString: function() { 483 return "Track Segment w/ " + this.getLength() + " points."; 484 } 485 }; 486 487 488 /** A track is an ordered list of track segments.<br> 489 * Equivalent to a <trk> in GPX format. 490 * 491 * @deprecated use Garmin.Activity instead 492 * @class Garmin.Track 493 * @constructor 494 */ 495 Garmin.Track = function(){}; 496 Garmin.Track = Class.create(); 497 Garmin.Track.prototype = { 498 initialize: function() { 499 this.segments = new Array(); 500 }, 501 502 /** Add a segment to this track 503 * @type Garmin.TrackPoint 504 */ 505 addSegment: function(trackSegment) { 506 this.segments.push(trackSegment); 507 }, 508 509 /** Get the segment specified on the track 510 * If the number is negative, get's the first 511 * If it's larger than possible, get's the last 512 * Otherwise it gets the number requested 513 * 514 * @param {Number} index is the segment we want 515 * @type Garmin.TrackSegment 516 * @return A segment that fits the pattern described above 517 */ 518 getSegment: function(index) { 519 index = Math.floor(index); 520 521 if(index >= this.getLastSegment()) { 522 return this.getEnd(); 523 } 524 if(index <= 0) { 525 return this.getFirstSegment(); 526 } 527 528 return this.segments[index]; 529 }, 530 531 /** Get the first segment 532 * @type Garmin.TrackSegment 533 * @return The first segment of this track 534 */ 535 getFirstSegment: function() { 536 return this.segments[0]; 537 }, 538 539 /** Get the last segment 540 * @type Garmin.TrackSegment 541 * @return The last segment of this track 542 */ 543 getLastSegment: function() { 544 return this.segments[this.getNumSegments()-1]; 545 }, 546 547 /** Get the total length of the track 548 * @type Number 549 */ 550 getNumSegments: function() { 551 return this.segments.length; 552 }, 553 554 /** Get the start point for the track 555 * @type Garmin.TrackPoint 556 */ 557 getStart: function() { 558 return this.getFirstSegment().getStart(); 559 }, 560 561 /** Get the latitude of the start point for the track 562 * @type Number 563 */ 564 getStartLat: function() { 565 return this.getFirstSegment().getStartLat(); 566 }, 567 568 /** Get the lpngitude of the start point for the track 569 * @type Number 570 */ 571 getStartLng: function() { 572 return this.getFirstSegment().getStartLng(); 573 }, 574 575 /** Get the DateTimeFormat object for the start of this track 576 * @type Garmin.DateTimeFormat 577 */ 578 getStartDate: function() { 579 return this.getFirstSegment().getStartDate(); 580 }, 581 582 /** Get the end point for the track 583 * @type Garmin.TrackPoint 584 */ 585 getEnd: function() { 586 return this.getLastSegment().getEnd(); 587 }, 588 589 /** Get the DateTimeFormat object for the end of this track 590 * @type Garmin.DateTimeFormat 591 */ 592 getEndDate: function() { 593 return this.getLastSegment().getEndDate(); 594 }, 595 596 /** Get the total duration for this track 597 * @type String 598 */ 599 getDuration: function() { 600 return this.getStartDate().getDurationTo(this.getEndDate()); 601 }, 602 603 /** Get the total number of trackpoints in this track 604 * @type Number 605 */ 606 getLength: function() { 607 var length = 0; 608 for( var i=0; i < this.segments.length; i++ ) { 609 length += this.segments[i].getLength(); 610 } 611 return length; 612 }, 613 614 /** Checks to see if the startDate is defined. If not then this is 615 * technically a route and presents issues for some 616 * track log databases where timestamps are used to merge old 617 * and new entries. 618 * @type Boolean 619 * @return True if this track has a timestamp 620 */ 621 isDrawable: function() { 622 return (this.getStartDate() != null); 623 }, 624 625 toString: function() { 626 return "Track w/ " + this.getNumSegments() + " segments."; 627 } 628 }; 629 630 /* THIS CLASS NOT NEEDED YET 631 * @class Garmin.Address 632 * Address class reprsents a US postal address.<br> 633 * @constructor 634 635 Garmin.Address = function(){}; 636 Garmin.Address = Class.create(); 637 Garmin.Address.prototype = { 638 initialize: function() { 639 this.streetAddress = null; 640 this.streetAddress2 = null; 641 this.city = null; 642 this.state = null; 643 this.postalCode = null; 644 }, 645 646 toString: function() { 647 return "Address: (" + this.streetAddress + ", " + 648 (this.streetAddress2 ? this.streetAddress2+", " : "") + 649 (this.city ? this.city+", " : "") + 650 (this.state ? this.state+" " : "") + 651 (this.postalCode ? this.postalCode : "") + 652 ")"; 653 } 654 }; 655 */ 656 657 658 /** Used to parse track and/or waypoint data from a number of Xml formats.<br> 659 * Currently only supports tracks from a GPX file. 660 * 661 * @deprecated use Garmin.GpxActivityFactory instead 662 * @class Garmin.GpsDataFactory 663 * @constructor 664 */ 665 Garmin.GpsDataFactory = function(){}; 666 Garmin.GpsDataFactory = Class.create(); 667 Garmin.GpsDataFactory.prototype = { 668 669 initialize: function() { 670 this.tracks = new Array(); 671 this.waypoints = new Array(); 672 }, 673 674 /** Get the tracks parsed by this factory 675 * @type Array<Garmin.Tracks> 676 */ 677 getTracks: function() { 678 return this.tracks; 679 }, 680 681 /** Get the waypoints parsed by this factory 682 * @type Array<Garmin.WayPoint> 683 */ 684 getWaypoints: function() { 685 return this.waypoints; 686 }, 687 688 /** Parse a gpx string and save the tracks found as objects 689 * @param {String} xml string in GPX format 690 */ 691 parseGpxString: function(gpxString) { 692 var gpxDocument = Garmin.XmlConverter.toDocument(gpxString); 693 694 this.parseGpxDocument(gpxDocument); 695 }, 696 697 /** Parse a gpx document and save the tracks and waypoints found 698 * @param {Document} xml document in GPX format 699 */ 700 parseGpxDocument: function(gpxDocument) { 701 this.parseGpxTracks(gpxDocument); 702 this.parseGpxWaypoints(gpxDocument); 703 }, 704 705 /** Parse a GPX xml document for tracks 706 * @param {Document} xml document in GPX format 707 * @type Array<Garmin.Track> 708 */ 709 parseGpxTracks: function(gpxDocument) { 710 var tracks = new Array(); 711 712 var trackNodes = gpxDocument.getElementsByTagName("trk"); 713 714 // triple for-loop fun 715 for( var i=0; i < trackNodes.length; i++ ) { 716 var trk = new Garmin.Track(); 717 718 var trackSegments = trackNodes[i].getElementsByTagName("trkseg"); 719 720 for( var j=0; j < trackSegments.length; j++ ) { 721 var trkseg = new Garmin.TrackSegment(); 722 723 var trackPoints = trackSegments[j].getElementsByTagName("trkpt"); 724 725 for( var k=0; k < trackPoints.length; k++ ) { 726 var trkpt = new Garmin.TrackPoint(); 727 728 var lat = trackPoints[k].getAttribute("lat"); 729 var lng = trackPoints[k].getAttribute("lon"); 730 var eleElement = trackPoints[k].getElementsByTagName("ele"); 731 var ele = (eleElement.length > 0) ? eleElement[0].childNodes[0].nodeValue : null; 732 733 var timeNodes = trackPoints[k].getElementsByTagName("time"); 734 if(timeNodes.length > 0) { 735 var time = timeNodes[0].childNodes[0].nodeValue; 736 trkpt.date = (new Garmin.DateTimeFormat()).parseXsdDateTime(time); 737 } 738 739 trkpt.measurements = { 740 latitude: { 741 value: lat, 742 context: "latitude" 743 }, 744 longitude: { 745 value: lng, 746 context: "longitude" 747 }, 748 elevation: { 749 value: ele, 750 context: "feet" 751 } 752 }; 753 754 trkseg.addTrackPoint(trkpt); 755 } 756 757 trk.addSegment(trkseg); 758 } 759 760 tracks.push(trk); 761 } 762 763 this.tracks = tracks; 764 return tracks; 765 }, 766 767 /** Parse a GPX xml waypoint into a Waypoint object. 768 * @param {Element} xml waypoint in GPX format 769 * @type Garmin.WayPoint 770 */ 771 parseGpxWaypoint: function(waypointNode) { 772 var lat = waypointNode.getAttribute("lat"); 773 var lng = waypointNode.getAttribute("lon"); 774 var name = this._tagValue(waypointNode,"name"); 775 var desc = this._tagValue(waypointNode,"desc"); 776 var ele = this._tagValue(waypointNode,"ele"); 777 var sym = this._tagValue(waypointNode,"sym"); 778 var type = this._tagValue(waypointNode,"type"); 779 var cmt = this._tagValue(waypointNode,"cmt"); 780 781 var wpt = new Garmin.WayPoint(lat, lng, ele, name, null, desc, sym, type, cmt); 782 return wpt; 783 }, 784 785 /** Parse a GPX xml document for waypoints 786 * @param {Document} xml document in GPX format 787 * @type Array<Garmin.WayPoint> 788 */ 789 parseGpxWaypoints: function(gpxDocument) { 790 var waypoints = new Array(); 791 var waypointNodes = gpxDocument.getElementsByTagName("wpt"); 792 for( var i=0; i < waypointNodes.length; i++ ) { 793 var waypointNode = waypointNodes[i]; 794 var wpt = this.parseGpxWaypoint(waypointNode); 795 waypoints.push(wpt); 796 } 797 this.waypoints = waypoints; 798 return waypoints; 799 }, 800 801 /** Take a list of tracks and waypoints and generate a GPX xml string 802 * @param {Array<Garmin.Track>} Tracks 803 * @param {Array<Garmin.WayPoint>} Waypoints 804 * @type String 805 */ 806 produceGpxString: function(tracks, waypoints) { 807 gpxString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>"; 808 809 gpxString += "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" creator=\"Garmin Communicator Plug-In API\" version=\"1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd\">"; 810 811 if(tracks != null) { 812 for( var i=0; i < tracks.length; i++ ) { 813 gpxString += this.produceTrackGpxString(tracks[i]); 814 } 815 } 816 817 if(waypoints != null) { 818 for( var i=0; i < waypoints.length; i++ ) { 819 gpxString += this.produceWaypointGpxString(waypoints[i]); 820 } 821 } 822 gpxString += "</gpx>"; 823 824 return gpxString; 825 }, 826 827 /** Take a track object and generate a GPX xml string (without gpx or xml headers) 828 * @param {Garmin.Track} Track 829 * @type String 830 */ 831 produceTrackGpxString: function(track) { 832 gpxString = "<trk>"; 833 834 for( var i=0; i < track.getNumSegments(); i++ ) { 835 var segment = track.getSegment(i); 836 837 gpxString += "<trkseg>"; 838 for(var j=0; j < segment.getLength(); j++) { 839 var point = segment.getPoint(j); 840 841 gpxString += "<trkpt lat=\"" + point.getLat() + "\" lon=\"" + point.getLng() + "\">"; 842 if(point.getElev()) { 843 gpxString += "<ele>" + point.getElev() + "</ele>"; 844 } 845 if(point.getDate()) { 846 gpxString += "<time>" + point.getDate().getXsdString() + "</time>"; 847 } 848 gpxString += "</trkpt>"; 849 } 850 gpxString += "</trkseg>"; 851 852 } 853 854 gpxString += "</trk>"; 855 856 return gpxString; 857 }, 858 859 /** Take a waypoint object and generate a GPX xml string (without gpx or xml headers) 860 * @param {Garmin.WayPoint} WayPoint 861 * @type String 862 */ 863 produceWaypointGpxString: function(waypoint) { 864 gpxString = "<wpt lat=\"" + waypoint.getLat() + "\" lon=\"" + waypoint.getLng() + "\">"; 865 866 if(waypoint.getElev()) { 867 gpxString += "<ele>" + waypoint.getElev() + "</ele>"; 868 } 869 if(waypoint.getName()) { 870 gpxString += "<name>" + waypoint.getName() + "</name>"; 871 } 872 if(waypoint.getComment()) { 873 gpxString += "<cmt>" + waypoint.getComment() + "</cmt>"; 874 } 875 if(waypoint.getDescription()) { 876 gpxString += "<desc>" + waypoint.getDescription() + "</desc>"; 877 } 878 if(waypoint.getSymbol()) { 879 gpxString += "<sym>" + waypoint.getSymbol() + "</sym>"; 880 } 881 if(waypoint.getAddress()) { 882 gpxString += "<extensions><gpxx:WaypointExtension>" + waypoint.getAddress() + "</gpxx:WaypointExtension></extensions>"; 883 } 884 if(waypoint.getType()) { 885 gpxString += "<type>" + waypoint.getType() + "</type>"; 886 } 887 gpxString += "</wpt>"; 888 889 return gpxString; 890 }, 891 892 /** Utility method to get the value of a child element. 893 * @param {Node} parent DOM node 894 * @param {String} name of child element 895 * @type String value of child element 896 */ 897 _tagValue: function(parentNode, tagName) { 898 var subNode = parentNode.getElementsByTagName(tagName); 899 return subNode.length > 0 ? subNode[0].childNodes[0].nodeValue : null; 900 }, 901 902 /** String representation of instance. 903 * @type String 904 */ 905 toString: function() { 906 return "GpsDataFactory."; 907 } 908 }; 909