├── Gemfile ├── GpxKitTests ├── Empty.gpx ├── EmptyWithMetadata.gpx ├── CLLocationCoordinate+Equatable.swift ├── Route.gpx ├── GpxWriter+Extensions.swift ├── Waypoints.gpx ├── Info.plist ├── TrackInvalidElevation.gpx ├── Track.gpx ├── Track-Multiple.gpx ├── Invalid-Attribute-Value.gpx ├── Invalid-Attribute.gpx ├── GpxWriterTests.swift ├── GpxParserTests.swift └── GarminRoute.gpx ├── GpxKit.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── marc.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── GpxKit.xcscheme └── project.pbxproj ├── GpxKit.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Podfile ├── GpxKit ├── GpxKit.h ├── DateFormatter+Extensions.swift ├── Info.plist ├── Gpx.swift ├── OutputStream+Extensions.swift ├── Gpx+Parser.swift └── GpxWriter.swift ├── Podfile.lock ├── GpxKit.podspec ├── LICENSE ├── .gitignore └── Gemfile.lock /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby '~> 2.6.0' 4 | 5 | gem 'cocoapods' 6 | -------------------------------------------------------------------------------- /GpxKitTests/Empty.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /GpxKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GpxKitTests/EmptyWithMetadata.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Empty with metadata 5 | An empty GPX file 6 | 7 | 8 | -------------------------------------------------------------------------------- /GpxKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /GpxKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '15.0' 2 | use_frameworks! 3 | inhibit_all_warnings! 4 | 5 | workspace 'GpxKit.xcworkspace' 6 | project 'GpxKit' 7 | 8 | target 'GpxKit' do 9 | project 'GpxKit' 10 | 11 | pod 'SWXMLHash', '~> 6' 12 | pod 'RxSwift', '~> 6.5' 13 | 14 | target 'GpxKitTests' do 15 | pod 'RxBlocking', '~> 6.5' 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /GpxKitTests/CLLocationCoordinate+Equatable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import CoreLocation 6 | 7 | extension CLLocationCoordinate2D: Equatable { 8 | 9 | public static func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool { 10 | return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GpxKit/GpxKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | #import 6 | 7 | //! Project version number for GpxKit. 8 | FOUNDATION_EXPORT double GpxKitVersionNumber; 9 | 10 | //! Project version string for GpxKit. 11 | FOUNDATION_EXPORT const unsigned char GpxKitVersionString[]; 12 | 13 | // In this header, you should import all the public headers of your framework using statements like #import 14 | 15 | 16 | -------------------------------------------------------------------------------- /GpxKitTests/Route.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /GpxKitTests/GpxWriter+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import RxBlocking 6 | @testable import GpxKit 7 | 8 | extension GpxWriter { 9 | 10 | func asString() -> String { 11 | let data = try! write(to: OutputStream(toMemory: ())) 12 | .toBlocking() 13 | .single() 14 | .property(forKey: Stream.PropertyKey.dataWrittenToMemoryStreamKey) as! Data 15 | return String(data: data, encoding: String.Encoding.utf8)! 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /GpxKit/DateFormatter+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import Foundation 6 | 7 | extension DateFormatter { 8 | 9 | static let iso8601: DateFormatter = { 10 | let formatter = DateFormatter() 11 | formatter.calendar = Calendar(identifier: .iso8601) 12 | formatter.locale = Locale(identifier: "en_US_POSIX") 13 | formatter.timeZone = TimeZone(secondsFromGMT: 0) 14 | formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" 15 | return formatter 16 | }() 17 | } 18 | -------------------------------------------------------------------------------- /GpxKitTests/Waypoints.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test file by Patrick 5 | A test file from cycleseven.org 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RxBlocking (6.5.0): 3 | - RxSwift (= 6.5.0) 4 | - RxSwift (6.5.0) 5 | - SWXMLHash (6.0.0) 6 | 7 | DEPENDENCIES: 8 | - RxBlocking (~> 6.5) 9 | - RxSwift (~> 6.5) 10 | - SWXMLHash (~> 6) 11 | 12 | SPEC REPOS: 13 | trunk: 14 | - RxBlocking 15 | - RxSwift 16 | - SWXMLHash 17 | 18 | SPEC CHECKSUMS: 19 | RxBlocking: 04b5fd28bb5ea49f7d64b80db8bbfe50d9cc1c7d 20 | RxSwift: 5710a9e6b17f3c3d6e40d6e559b9fa1e813b2ef8 21 | SWXMLHash: 9d851ed3edf48ec2bd0db98f0cda0ad4136d75e3 22 | 23 | PODFILE CHECKSUM: aff4d100925380e9d53938a970b4a8adfc304234 24 | 25 | COCOAPODS: 1.12.1 26 | -------------------------------------------------------------------------------- /GpxKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "GpxKit" 3 | s.version = "3.0.0" 4 | s.license = "MIT" 5 | s.summary = "Swift GPX parser and writer" 6 | s.homepage = "https://github.com/beeline/GpxKit" 7 | s.author = { "marcbaldwin" => "marc.baldwin88@gmail.com" } 8 | s.source = { :git => "https://github.com/beeline/GpxKit.git", :tag => s.version } 9 | s.source_files = "GpxKit/*.swift" 10 | s.ios.deployment_target = '15.0' 11 | s.swift_version = '5' 12 | s.default_subspec = "Core" 13 | 14 | s.subspec "Core" do |ss| 15 | ss.framework = "Foundation" 16 | ss.dependency "SWXMLHash", '~> 6' 17 | ss.dependency "RxSwift", '~> 6.5' 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /GpxKit.xcodeproj/xcuserdata/marc.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | GpxKit.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4933266C1F7003A2001B928C 16 | 17 | primary 18 | 19 | 20 | 493326751F7003A3001B928C 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /GpxKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /GpxKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /GpxKitTests/TrackInvalidElevation.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | s 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2.22 14 | 15 | 16 | 17 | 3.333 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /GpxKitTests/Track.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 0.0 7 | 8 | 9 | 10 | 1.1 11 | 12 | 13 | 14 | 2.22 15 | 16 | 17 | 18 | 3.333 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /GpxKit/Gpx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import CoreLocation 6 | 7 | public struct Gpx { 8 | public let creator: String 9 | public let metadata: Metadata? 10 | public let waypoints: [Point] 11 | public let route: [Point] 12 | public let tracks: [Track] 13 | } 14 | 15 | public struct Track { 16 | public let segments: [[Point]] 17 | } 18 | 19 | public struct Metadata { 20 | public let name: String? 21 | public let description: String? 22 | } 23 | 24 | public struct Point { 25 | public let coordinate: CLLocationCoordinate2D 26 | public let elevation: Double? 27 | public let time: Date? 28 | 29 | public init(lat: Double, lon: Double, elevation: Double? = nil, time: Date? = nil) { 30 | self.init(CLLocationCoordinate2DMake(lat, lon), elevation: elevation, time: time) 31 | } 32 | 33 | public init(_ coordinate: CLLocationCoordinate2D, elevation: Double? = nil, time: Date? = nil) { 34 | self.coordinate = coordinate 35 | self.elevation = elevation 36 | self.time = time 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Marc Baldwin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /GpxKitTests/Track-Multiple.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 0.0 7 | 8 | 9 | 10 | 1.1 11 | 12 | 13 | 14 | 2.22 15 | 16 | 17 | 18 | 3.333 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | # OSX 6 | .DS_Store 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData/ 11 | .bundle/ 12 | vendor/ 13 | .build-sdk/ 14 | *.strings 15 | translations.intermediate.csv 16 | 17 | ## Various settings 18 | *.pbxuser 19 | !default.pbxuser 20 | *.mode1v3 21 | !default.mode1v3 22 | *.mode2v3 23 | !default.mode2v3 24 | *.perspectivev3 25 | !default.perspectivev3 26 | xcuserdata/ 27 | 28 | ## Other 29 | *.xccheckout 30 | *.moved-aside 31 | *.xcuserstate 32 | *.xcscmblueprint 33 | 34 | ## Obj-C/Swift specific 35 | *.hmap 36 | *.ipa 37 | 38 | ## Playgrounds 39 | timeline.xctimeline 40 | playground.xcworkspace 41 | 42 | # Swift Package Manager 43 | # 44 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 45 | # Packages/ 46 | .build/ 47 | 48 | # CocoaPods 49 | # 50 | # We recommend against adding the Pods directory to your .gitignore. However 51 | # you should judge for yourself, the pros and cons are mentioned at: 52 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 53 | # 54 | Pods/ 55 | 56 | # Carthage 57 | # 58 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 59 | # Carthage/Checkouts 60 | 61 | Carthage/Build 62 | 63 | # fastlane 64 | # 65 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 66 | # screenshots whenever they are needed. 67 | # For more information about the recommended setup visit: 68 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 69 | 70 | fastlane/report.xml 71 | fastlane/screenshots 72 | -------------------------------------------------------------------------------- /GpxKit/OutputStream+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | extension OutputStream { 6 | 7 | @discardableResult 8 | func writeXmlDeclaration() -> OutputStream { 9 | write("\n") 10 | return self 11 | } 12 | 13 | @discardableResult 14 | func write(openTag name: String, attributes: [(String, String)] = [], newline: Bool = false, indent indentLevel: Int = 0) -> OutputStream { 15 | let attributes = attributes.map { " \($0.xmlEscape())=\"\($1.xmlEscape())\"" }.joined() 16 | let suffix = newline ? "\n" : "" 17 | write("\(indent(indentLevel))<\(name.xmlEscape())\(attributes)>\(suffix)") 18 | return self 19 | } 20 | 21 | @discardableResult 22 | func write(closeTag name: String, newline: Bool = false, indent indentLevel: Int = 0) -> OutputStream { 23 | let suffix = newline ? "\n" : "" 24 | write("\(indent(indentLevel))\(suffix)") 25 | return self 26 | } 27 | 28 | @discardableResult 29 | func write(value: String, newline: Bool = false) -> OutputStream { 30 | let suffix = newline ? "\n" : "" 31 | write("\(value.xmlEscape())\(suffix)") 32 | return self 33 | } 34 | 35 | private func write(_ data: String) { 36 | write(data, maxLength: data.lengthOfBytes(using: String.Encoding.utf8)) 37 | } 38 | 39 | private func indent(_ level: Int) -> String { 40 | return String(repeating: " ", count: level) 41 | } 42 | 43 | } 44 | 45 | private extension String { 46 | 47 | func xmlEscape() -> String { 48 | return replacingOccurrences(of: "&", with: "&") 49 | .replacingOccurrences(of: "\"", with: """) 50 | .replacingOccurrences(of: ">", with: ">") 51 | .replacingOccurrences(of: "<", with: "<") 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /GpxKitTests/Invalid-Attribute-Value.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bulbrarrow 5 | 6 | Marc Baldwin 7 | 8 | 9 | 10 | 11 | 12 | Bulbrarrow 13 | 14 | Ride 15 | 16 | 17 | 40.0 18 | 19 | 20 | 40.0 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /GpxKitTests/Invalid-Attribute.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bulbrarrow 5 | 6 | Marc Baldwin 7 | 8 | 9 | 10 | 11 | 12 | Bulbrarrow 13 | 14 | Ride 15 | 16 | 17 | 40.0 18 | 19 | 20 | 40.0 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /GpxKit/Gpx+Parser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import CoreLocation 6 | import SWXMLHash 7 | 8 | public extension Gpx { 9 | 10 | init(data: Data) throws { 11 | let gpx = XMLHash.parse(data)["gpx"] 12 | 13 | self.creator = gpx["creator"].element?.text ?? "" 14 | 15 | self.metadata = gpx["metadata"].metadata() 16 | 17 | self.waypoints = try gpx["wpt"].all.map { waypoint in 18 | try waypoint.point() 19 | } 20 | 21 | self.route = try gpx["rte"]["rtept"].all.map { routePoint in 22 | try routePoint.point() 23 | } 24 | 25 | self.tracks = try gpx["trk"].all.map { track in 26 | Track(segments: 27 | try track["trkseg"].all.map { trackSegment in 28 | try trackSegment["trkpt"].all.map { trackPoint in 29 | try trackPoint.point() 30 | } 31 | } 32 | ) 33 | } 34 | } 35 | } 36 | 37 | fileprivate extension XMLIndexer { 38 | 39 | func metadata() -> Metadata? { 40 | guard element != nil else { return nil } 41 | let name = self["name"].element?.text 42 | let description = self["description"].element?.text 43 | return Metadata(name: name, description: description) 44 | } 45 | 46 | func point() throws -> Point { 47 | guard let element = element else { throw IndexingError.error } 48 | let latitude = try element.attributeValue(by: "lat") 49 | let longitude = try element.attributeValue(by: "lon") 50 | let elevation = self["ele"].element?.text 51 | let time = self["time"].element?.text 52 | return Point( 53 | CLLocationCoordinate2D(latitude: latitude, longitude: longitude), 54 | elevation: elevation != nil ? Double(elevation!) : nil, 55 | time: time != nil ? DateFormatter.iso8601.date(from: time!) : nil 56 | ) 57 | } 58 | 59 | } 60 | 61 | fileprivate extension XMLElement { 62 | 63 | func attributeValue(by name: String) throws -> Double { 64 | guard let attribute = attribute(by: name) else { 65 | throw IndexingError.attribute(attr: name) 66 | } 67 | guard let value = Double(attribute.text) else { 68 | throw IndexingError.attributeValue(attr: name, value: attribute.text) 69 | } 70 | return value 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (6.1.7.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.5) 13 | public_suffix (>= 2.0.2, < 6.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.12.1) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.12.1) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 1.6.0, < 2.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.6.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 2.3.0, < 3.0) 36 | xcodeproj (>= 1.21.0, < 2.0) 37 | cocoapods-core (1.12.1) 38 | activesupport (>= 5.0, < 8) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (1.6.3) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.2.2) 58 | escape (0.0.4) 59 | ethon (0.16.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.15.5) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.14.1) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.3) 69 | minitest (5.20.0) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.7) 75 | rexml (3.2.6) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.0) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.6) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.22.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.6.11) 89 | 90 | PLATFORMS 91 | arm64-darwin 92 | 93 | DEPENDENCIES 94 | cocoapods 95 | 96 | RUBY VERSION 97 | ruby 2.6.10p210 98 | 99 | BUNDLED WITH 100 | 2.3.24 101 | -------------------------------------------------------------------------------- /GpxKitTests/GpxWriterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import XCTest 6 | import RxSwift 7 | import CoreLocation 8 | @testable import GpxKit 9 | 10 | class GpxWriterTests: XCTestCase { 11 | 12 | func test_write_gpx_empty() { 13 | XCTAssertEqual( 14 | gpxFile("Empty"), 15 | GpxWriter( 16 | creator: "GpxKit" 17 | ).asString() 18 | ) 19 | } 20 | 21 | func test_write_gpx_metadata() { 22 | XCTAssertEqual( 23 | gpxFile("EmptyWithMetadata"), 24 | GpxWriter( 25 | creator: "GpxKit", 26 | metadata: Metadata(name: "Empty with metadata", description: "An empty GPX file") 27 | ).asString() 28 | ) 29 | } 30 | 31 | func test_write_gpx_waypoints() { 32 | XCTAssertEqual( 33 | gpxFile("Waypoints"), 34 | GpxWriter( 35 | creator: "RouteConverter", 36 | metadata: Metadata(name: "Test file by Patrick", description: "A test file from cycleseven.org"), 37 | waypoints: Observable.from([ 38 | Point(lat: 54.9328621088893, lon: 9.86062421614008), 39 | Point(lat: 54.9329323732085, lon: 9.86092208681491), 40 | Point(lat: 54.9332774352119, lon: 9.86187816543752), 41 | Point(lat: 54.9334232616792, lon: 9.86243984967986) 42 | ]) 43 | ).asString() 44 | ) 45 | } 46 | 47 | func test_write_gpx_route() { 48 | XCTAssertEqual( 49 | gpxFile("Route"), 50 | GpxWriter( 51 | creator: "GpxKit", 52 | route: Observable.from([ 53 | Point(lat: 54.9328621088893, lon: 9.86062421614008), 54 | Point(lat: 54.9329323732085, lon: 9.86092208681491), 55 | Point(lat: 54.9332774352119, lon: 9.86187816543752), 56 | Point(lat: 54.9334232616792, lon: 9.86243984967986) 57 | ]) 58 | ).asString() 59 | ) 60 | } 61 | 62 | func test_write_gpx_track() { 63 | XCTAssertEqual( 64 | gpxFile("Track"), 65 | GpxWriter( 66 | creator: "GpxKit", 67 | track: Observable.just(Observable.from([ 68 | Point( 69 | lat: 54.9328621088893, 70 | lon: 9.86062421614008, 71 | elevation: 0, 72 | time: Date(timeIntervalSince1970: 1505900660) 73 | ), 74 | Point( 75 | lat: 54.9329323732085, 76 | lon: 9.86092208681491, 77 | elevation: 1.1, 78 | time: Date(timeIntervalSince1970: 1505900661) 79 | ), 80 | Point( 81 | lat: 54.9332774352119, 82 | lon: 9.86187816543752, 83 | elevation: 2.22, 84 | time: Date(timeIntervalSince1970: 1505900662) 85 | ), 86 | Point( 87 | lat: 54.9334232616792, 88 | lon: 9.86243984967986, 89 | elevation: 3.333, 90 | time: Date(timeIntervalSince1970: 1505900663) 91 | ) 92 | ])) 93 | ).asString() 94 | ) 95 | } 96 | 97 | private func gpxFile(_ name: String) -> String { 98 | let url = Bundle(for: GpxParserTests.self).url(forResource: name, withExtension: "gpx") 99 | let data = try! Data(contentsOf: url!) 100 | return String(data: data, encoding: String.Encoding.utf8)! 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /GpxKit.xcodeproj/xcuserdata/marc.xcuserdatad/xcschemes/GpxKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /GpxKit/GpxWriter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import CoreLocation 6 | import RxSwift 7 | 8 | fileprivate typealias XmlWrite = (OutputStream) -> Void 9 | 10 | public class GpxWriter : NSObject { 11 | 12 | private let writeOperations: Observable 13 | 14 | public init( 15 | creator: String, 16 | metadata: Metadata? = nil, 17 | waypoints: Observable? = nil, 18 | route: Observable? = nil, 19 | track: Observable>? = nil 20 | ) { 21 | self.writeOperations = Observable 22 | .from([ 23 | { $0.writeXmlDeclaration() }, 24 | { $0.write( 25 | openTag: "gpx", 26 | attributes: [("xmlns", "http://www.topografix.com/GPX/1/1"), ("version", "1.1"), ("creator", creator)], 27 | newline: true 28 | ) }, 29 | ]) 30 | .concat(writeMetadata(metadata, indent: 1)) 31 | .concat(writeWaypoints(waypoints, indent: 1)) 32 | .concat(writeRoute(route, indent: 1)) 33 | .concat(writeTrack(track, indent: 1)) 34 | .concat(Observable.just { $0.write(closeTag: "gpx", newline: true) }) 35 | super.init() 36 | } 37 | 38 | public func write(to stream: T) -> Observable { 39 | return writeOperations 40 | .startWith { $0.open() } 41 | .concat(Observable.just { $0.close() }) 42 | .reduce(stream) { stream, operation -> T in 43 | operation(stream) 44 | return stream 45 | } 46 | } 47 | 48 | } 49 | 50 | private func writePoint(point: Point, tag: String, indent: Int = 0) -> XmlWrite { 51 | return { stream in 52 | stream.write( 53 | openTag: tag, 54 | attributes: [("lat", "\(point.coordinate.latitude)"), ("lon", "\(point.coordinate.longitude)")], 55 | newline: true, 56 | indent: indent 57 | ) 58 | if let elevation = point.elevation { 59 | stream 60 | .write(openTag: "ele", indent: indent + 1) 61 | .write(value: "\(elevation)") 62 | .write(closeTag: "ele", newline: true) 63 | } 64 | if let time = point.time { 65 | stream 66 | .write(openTag: "time", indent: indent + 1) 67 | .write(value: DateFormatter.iso8601.string(from: time)) 68 | .write(closeTag: "time", newline: true) 69 | } 70 | stream.write( 71 | closeTag: tag, 72 | newline: true, 73 | indent: indent 74 | ) 75 | } 76 | } 77 | 78 | private func writeMetadata(_ metadata: Metadata?, indent: Int = 0) -> Observable { 79 | guard let metadata = metadata else { return Observable.empty() } 80 | return Observable.just { stream in 81 | stream.write(openTag: "metadata", newline: true, indent: indent) 82 | if let value = metadata.name { 83 | stream 84 | .write(openTag: "name", indent: indent + 1) 85 | .write(value: value) 86 | .write(closeTag: "name", newline: true) 87 | } 88 | if let value = metadata.description { 89 | stream 90 | .write(openTag: "description", indent: indent + 1) 91 | .write(value: value) 92 | .write(closeTag: "description", newline: true) 93 | } 94 | stream.write(closeTag: "metadata", newline: true, indent: indent) 95 | } 96 | } 97 | 98 | private func writeWaypoints(_ waypoints: Observable?, indent: Int = 0) -> Observable { 99 | guard let waypoints = waypoints else { return Observable.empty() } 100 | return waypoints.map { writePoint(point: $0, tag: "wpt", indent: indent) } 101 | } 102 | 103 | private func writeRoute(_ route: Observable?, indent: Int = 0) -> Observable { 104 | guard let route = route else { return Observable.empty() } 105 | return Observable.just { $0.write(openTag: "rte", newline: true, indent: indent) } 106 | .concat(route.map { writePoint(point: $0, tag: "rtept", indent: indent + 1) }) 107 | .concat(Observable.just { $0.write(closeTag: "rte", newline: true, indent: indent) }) 108 | } 109 | 110 | private func writeTrack(_ track: Observable>?, indent: Int = 0) -> Observable { 111 | guard let track = track else { return Observable.empty() } 112 | return Observable.just { $0.write(openTag: "trk", newline: true, indent: indent) } 113 | .concat( 114 | Observable.just { $0.write(openTag: "trkseg", newline: true, indent: indent + 1) } 115 | .concat( 116 | track.concatMap { 117 | $0.map { writePoint(point: $0, tag: "trkpt", indent: indent + 2) } 118 | } 119 | ) 120 | .concat(Observable.just { $0.write(closeTag: "trkseg", newline: true, indent: indent + 1) }) 121 | ) 122 | .concat(Observable.just { $0.write(closeTag: "trk", newline: true, indent: indent) }) 123 | } 124 | 125 | -------------------------------------------------------------------------------- /GpxKitTests/GpxParserTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Beeline. All rights reserved. 3 | // 4 | 5 | import XCTest 6 | import CoreLocation 7 | @testable import GpxKit 8 | 9 | class GpxParserTests: XCTestCase { 10 | 11 | func test_parse_gpx_route() { 12 | let gpx = try! parse(name: "GarminRoute") 13 | 14 | XCTAssertEqual(gpx.route.count, 118) 15 | 16 | XCTAssertEqual(gpx.route[0].coordinate.latitude, 49.933832287788391) 17 | XCTAssertEqual(gpx.route[0].coordinate.longitude, 1.088794218376279) 18 | XCTAssertEqual(gpx.route[0].time, Date(timeIntervalSince1970: 1311371614)) 19 | 20 | XCTAssertEqual(gpx.route[1].coordinate.latitude, 49.934062957763672) 21 | XCTAssertEqual(gpx.route[1].coordinate.longitude, 1.089534759521484) 22 | XCTAssertEqual(gpx.route[1].time, nil) 23 | } 24 | 25 | func test_parse_gpx_track() { 26 | let gpx = try! parse(name: "StravaTrack") 27 | 28 | XCTAssertEqual(gpx.tracks.count, 1) 29 | let track = gpx.tracks[0] 30 | XCTAssertEqual(track.segments[0].count, 1752) 31 | 32 | XCTAssertEqual(track.segments[0][0].coordinate.latitude, 50.732060000000004) 33 | XCTAssertEqual(track.segments[0][0].coordinate.longitude, -1.8740900000000003) 34 | 35 | XCTAssertEqual(track.segments[0][1].coordinate.latitude, 50.731970000000004) 36 | XCTAssertEqual(track.segments[0][1].coordinate.longitude, -1.87399) 37 | } 38 | 39 | func test_parse_gpx_waypoints() { 40 | let gpx = try! parse(name: "Waypoints") 41 | 42 | XCTAssertEqual(gpx.waypoints.count, 4) 43 | 44 | XCTAssertEqual(gpx.waypoints[0].coordinate.latitude, 54.9328621088893) 45 | XCTAssertEqual(gpx.waypoints[0].coordinate.longitude, 9.86062421614008) 46 | 47 | XCTAssertEqual(gpx.waypoints[1].coordinate.latitude, 54.9329323732085) 48 | XCTAssertEqual(gpx.waypoints[1].coordinate.longitude, 9.86092208681491) 49 | 50 | XCTAssertEqual(gpx.waypoints[2].coordinate.latitude, 54.9332774352119) 51 | XCTAssertEqual(gpx.waypoints[2].coordinate.longitude, 9.86187816543752) 52 | 53 | XCTAssertEqual(gpx.waypoints[3].coordinate.latitude, 54.9334232616792) 54 | XCTAssertEqual(gpx.waypoints[3].coordinate.longitude, 9.86243984967986) 55 | } 56 | 57 | func test_parse_gpx_with_multiple_tracks() { 58 | let gpx = try! parse(name: "Track-Multiple") 59 | 60 | XCTAssertEqual(gpx.tracks.count, 2) 61 | 62 | let track1 = gpx.tracks[0] 63 | XCTAssertEqual(track1.segments[0].count, 4) 64 | 65 | XCTAssertEqual(track1.segments[0][0].coordinate, CLLocationCoordinate2D(latitude: 54.9328621088893, longitude: 9.86062421614008)) 66 | XCTAssertEqual(track1.segments[0][0].elevation, 0.0) 67 | 68 | XCTAssertEqual(track1.segments[0][1].coordinate, CLLocationCoordinate2D(latitude: 54.9329323732085, longitude: 9.86092208681491)) 69 | XCTAssertEqual(track1.segments[0][1].elevation, 1.1) 70 | 71 | XCTAssertEqual(track1.segments[0][2].coordinate, CLLocationCoordinate2D(latitude: 54.9332774352119, longitude: 9.86187816543752)) 72 | XCTAssertEqual(track1.segments[0][2].elevation, 2.22) 73 | 74 | XCTAssertEqual(track1.segments[0][3].coordinate, CLLocationCoordinate2D(latitude: 54.9334232616792, longitude: 9.86243984967986)) 75 | XCTAssertEqual(track1.segments[0][3].elevation, 3.333) 76 | 77 | let track2 = gpx.tracks[1] 78 | XCTAssertEqual(track2.segments[0].count, 3) 79 | 80 | XCTAssertEqual(track2.segments[0][0].coordinate, CLLocationCoordinate2D(latitude: 49.933832287788391, longitude: 1.088794218376279)) 81 | XCTAssertEqual(track2.segments[0][0].elevation, nil) 82 | 83 | XCTAssertEqual(track2.segments[0][1].coordinate, CLLocationCoordinate2D(latitude: 49.933706223964691, longitude: 1.091079125180841)) 84 | XCTAssertEqual(track2.segments[0][1].elevation, nil) 85 | 86 | XCTAssertEqual(track2.segments[0][2].coordinate, CLLocationCoordinate2D(latitude: 49.934062957763672, longitude: 1.092946529388428)) 87 | XCTAssertEqual(track2.segments[0][2].elevation, nil) 88 | } 89 | 90 | func test_parse_gpx_metadata() { 91 | let gpx = try! parse(name: "Waypoints") 92 | 93 | XCTAssertEqual(gpx.metadata!.name, "Test file by Patrick") 94 | XCTAssertEqual(gpx.metadata!.description, "A test file from cycleseven.org") 95 | } 96 | 97 | func test_parse_gpx_with_invalid_attribute() { 98 | do { 99 | _ = try parse(name: "Invalid-Attribute") 100 | XCTFail() 101 | } catch { 102 | // Pass 103 | } 104 | } 105 | 106 | func test_parse_gpx_with_invalid_attribute_value() { 107 | do { 108 | _ = try parse(name: "Invalid-Attribute-Value") 109 | XCTFail() 110 | } catch { 111 | // Pass 112 | } 113 | } 114 | 115 | func test_parse_gpx_track_with_elevation() { 116 | let gpx = try! parse(name: "Track") 117 | 118 | XCTAssertEqual(gpx.tracks.count, 1) 119 | 120 | let track = gpx.tracks[0] 121 | XCTAssertEqual(track.segments[0].count, 4) 122 | 123 | XCTAssertEqual(track.segments[0][0].coordinate, CLLocationCoordinate2D(latitude: 54.9328621088893, longitude: 9.86062421614008)) 124 | XCTAssertEqual(track.segments[0][0].elevation, 0.0) 125 | 126 | XCTAssertEqual(track.segments[0][1].coordinate, CLLocationCoordinate2D(latitude: 54.9329323732085, longitude: 9.86092208681491)) 127 | XCTAssertEqual(track.segments[0][1].elevation, 1.1) 128 | 129 | XCTAssertEqual(track.segments[0][2].coordinate, CLLocationCoordinate2D(latitude: 54.9332774352119, longitude: 9.86187816543752)) 130 | XCTAssertEqual(track.segments[0][2].elevation, 2.22) 131 | 132 | XCTAssertEqual(track.segments[0][3].coordinate, CLLocationCoordinate2D(latitude: 54.9334232616792, longitude: 9.86243984967986)) 133 | XCTAssertEqual(track.segments[0][3].elevation, 3.333) 134 | } 135 | 136 | func test_parse_gpx_track_with_invalid_elevation() { 137 | let gpx = try! parse(name: "TrackInvalidElevation") 138 | 139 | XCTAssertEqual(gpx.tracks.count, 1) 140 | 141 | let track = gpx.tracks[0] 142 | XCTAssertEqual(track.segments[0].count, 4) 143 | 144 | XCTAssertEqual(track.segments[0][0].coordinate, CLLocationCoordinate2D(latitude: 54.9328621088893, longitude: 9.86062421614008)) 145 | XCTAssertEqual(track.segments[0][0].elevation, nil) 146 | 147 | XCTAssertEqual(track.segments[0][1].coordinate, CLLocationCoordinate2D(latitude: 54.9329323732085, longitude: 9.86092208681491)) 148 | XCTAssertEqual(track.segments[0][1].elevation, nil) 149 | 150 | XCTAssertEqual(track.segments[0][2].coordinate, CLLocationCoordinate2D(latitude: 54.9332774352119, longitude: 9.86187816543752)) 151 | XCTAssertEqual(track.segments[0][2].elevation, 2.22) 152 | 153 | XCTAssertEqual(track.segments[0][3].coordinate, CLLocationCoordinate2D(latitude: 54.9334232616792, longitude: 9.86243984967986)) 154 | XCTAssertEqual(track.segments[0][3].elevation, 3.333) 155 | } 156 | 157 | private func parse(name: String) throws -> Gpx { 158 | let url = Bundle(for: GpxParserTests.self).url(forResource: name, withExtension: "gpx") 159 | let data = try! Data(contentsOf: url!) 160 | return try Gpx(data: data) 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /GpxKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 492D155C1FA8F70D0013DB7D /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 492D155B1FA8F70D0013DB7D /* DateFormatter+Extensions.swift */; }; 11 | 493326771F7003A3001B928C /* GpxKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4933266D1F7003A2001B928C /* GpxKit.framework */; }; 12 | 4933267C1F7003A3001B928C /* GpxParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4933267B1F7003A3001B928C /* GpxParserTests.swift */; }; 13 | 4933267E1F7003A3001B928C /* GpxKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 493326701F7003A2001B928C /* GpxKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 493326881F7003B5001B928C /* Gpx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493326871F7003B5001B928C /* Gpx.swift */; }; 15 | 4933268C1F70046E001B928C /* Gpx+Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4933268B1F70046E001B928C /* Gpx+Parser.swift */; }; 16 | 4933268E1F7009FD001B928C /* StravaTrack.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 4933268D1F7009FD001B928C /* StravaTrack.gpx */; }; 17 | 4996A07B1F70106300A0BE9D /* Invalid-Attribute.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 4996A07A1F70106300A0BE9D /* Invalid-Attribute.gpx */; }; 18 | 4996A07D1F70154200A0BE9D /* GarminRoute.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 4996A07C1F70154200A0BE9D /* GarminRoute.gpx */; }; 19 | 4996A0811F701D4100A0BE9D /* Invalid-Attribute-Value.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 4996A0801F701D4100A0BE9D /* Invalid-Attribute-Value.gpx */; }; 20 | 49C08B0B21187B340053B8C4 /* Track-Multiple.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 49C08B0A21187B340053B8C4 /* Track-Multiple.gpx */; }; 21 | 49C08B0D21188C270053B8C4 /* CLLocationCoordinate+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C08B0C21188C270053B8C4 /* CLLocationCoordinate+Equatable.swift */; }; 22 | 615208401FA2110600B0DCB7 /* Route.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 6152083F1FA2110600B0DCB7 /* Route.gpx */; }; 23 | 615208421FA21AA300B0DCB7 /* Track.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 615208411FA21AA300B0DCB7 /* Track.gpx */; }; 24 | 616233321FA0BE9300A52420 /* Waypoints.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 616233311FA0BE9300A52420 /* Waypoints.gpx */; }; 25 | 616233341FA0C6E000A52420 /* GpxWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616233331FA0C6E000A52420 /* GpxWriterTests.swift */; }; 26 | 616233361FA0C74000A52420 /* GpxWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616233351FA0C74000A52420 /* GpxWriter.swift */; }; 27 | 616233391FA0F26900A52420 /* GpxWriter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616233381FA0F26900A52420 /* GpxWriter+Extensions.swift */; }; 28 | 6162333B1FA1DC7300A52420 /* Empty.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 6162333A1FA1DC7300A52420 /* Empty.gpx */; }; 29 | 6162333F1FA1E1A400A52420 /* OutputStream+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6162333E1FA1E1A400A52420 /* OutputStream+Extensions.swift */; }; 30 | 616233421FA1E9F800A52420 /* EmptyWithMetadata.gpx in Resources */ = {isa = PBXBuildFile; fileRef = 616233411FA1E9F800A52420 /* EmptyWithMetadata.gpx */; }; 31 | 8AC4DDE44653A3A3A179940E /* Pods_GpxKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 156172C678D2BE106A871A1F /* Pods_GpxKit.framework */; }; 32 | AC70C5B0F2E1FBCA717BCEBB /* Pods_GpxKit_GpxKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9CBAC50044AB8884AE57313 /* Pods_GpxKit_GpxKitTests.framework */; }; 33 | F169505E205D273F00BD3355 /* TrackInvalidElevation.gpx in Resources */ = {isa = PBXBuildFile; fileRef = F169505D205D273F00BD3355 /* TrackInvalidElevation.gpx */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | 493326781F7003A3001B928C /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 493326641F7003A2001B928C /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 4933266C1F7003A2001B928C; 42 | remoteInfo = GpxKit; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 037506C9396B194DF33797A8 /* Pods-GpxKit-GpxKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKit-GpxKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKit-GpxKitTests/Pods-GpxKit-GpxKitTests.release.xcconfig"; sourceTree = ""; }; 48 | 05E34298ECD04DB1EF2E39BB /* Pods-GpxKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKit/Pods-GpxKit.debug.xcconfig"; sourceTree = ""; }; 49 | 156172C678D2BE106A871A1F /* Pods_GpxKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GpxKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 21B16DDC2EAAE95A0D5AFD88 /* Pods-GpxKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKitTests/Pods-GpxKitTests.debug.xcconfig"; sourceTree = ""; }; 51 | 492D155B1FA8F70D0013DB7D /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; 52 | 4933266D1F7003A2001B928C /* GpxKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GpxKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 493326701F7003A2001B928C /* GpxKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GpxKit.h; sourceTree = ""; }; 54 | 493326711F7003A2001B928C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 493326761F7003A3001B928C /* GpxKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GpxKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 4933267B1F7003A3001B928C /* GpxParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GpxParserTests.swift; sourceTree = ""; }; 57 | 4933267D1F7003A3001B928C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 493326871F7003B5001B928C /* Gpx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Gpx.swift; sourceTree = ""; }; 59 | 4933268B1F70046E001B928C /* Gpx+Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Gpx+Parser.swift"; sourceTree = ""; }; 60 | 4933268D1F7009FD001B928C /* StravaTrack.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = StravaTrack.gpx; sourceTree = ""; }; 61 | 4996A07A1F70106300A0BE9D /* Invalid-Attribute.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Invalid-Attribute.gpx"; sourceTree = ""; }; 62 | 4996A07C1F70154200A0BE9D /* GarminRoute.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = GarminRoute.gpx; sourceTree = ""; }; 63 | 4996A0801F701D4100A0BE9D /* Invalid-Attribute-Value.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Invalid-Attribute-Value.gpx"; sourceTree = ""; }; 64 | 49C08B0A21187B340053B8C4 /* Track-Multiple.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Track-Multiple.gpx"; sourceTree = ""; }; 65 | 49C08B0C21188C270053B8C4 /* CLLocationCoordinate+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CLLocationCoordinate+Equatable.swift"; sourceTree = ""; }; 66 | 6152083F1FA2110600B0DCB7 /* Route.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Route.gpx; sourceTree = ""; }; 67 | 615208411FA21AA300B0DCB7 /* Track.gpx */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Track.gpx; sourceTree = ""; }; 68 | 616233311FA0BE9300A52420 /* Waypoints.gpx */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Waypoints.gpx; sourceTree = ""; }; 69 | 616233331FA0C6E000A52420 /* GpxWriterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GpxWriterTests.swift; sourceTree = ""; }; 70 | 616233351FA0C74000A52420 /* GpxWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GpxWriter.swift; sourceTree = ""; }; 71 | 616233381FA0F26900A52420 /* GpxWriter+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GpxWriter+Extensions.swift"; sourceTree = ""; }; 72 | 6162333A1FA1DC7300A52420 /* Empty.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Empty.gpx; sourceTree = ""; }; 73 | 6162333E1FA1E1A400A52420 /* OutputStream+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OutputStream+Extensions.swift"; sourceTree = ""; }; 74 | 616233411FA1E9F800A52420 /* EmptyWithMetadata.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = EmptyWithMetadata.gpx; sourceTree = ""; }; 75 | B9CBAC50044AB8884AE57313 /* Pods_GpxKit_GpxKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GpxKit_GpxKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | C32969201F097FCD02DD7D75 /* Pods-GpxKit-GpxKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKit-GpxKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKit-GpxKitTests/Pods-GpxKit-GpxKitTests.debug.xcconfig"; sourceTree = ""; }; 77 | CBDE30710EB582671DEAB5BA /* Pods-GpxKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKitTests/Pods-GpxKitTests.release.xcconfig"; sourceTree = ""; }; 78 | E6B3CA0DE6FC6B84CC87CA2E /* Pods-GpxKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GpxKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-GpxKit/Pods-GpxKit.release.xcconfig"; sourceTree = ""; }; 79 | F169505D205D273F00BD3355 /* TrackInvalidElevation.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = TrackInvalidElevation.gpx; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 493326691F7003A2001B928C /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | 8AC4DDE44653A3A3A179940E /* Pods_GpxKit.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 493326731F7003A3001B928C /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | 493326771F7003A3001B928C /* GpxKit.framework in Frameworks */, 96 | AC70C5B0F2E1FBCA717BCEBB /* Pods_GpxKit_GpxKitTests.framework in Frameworks */, 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | /* End PBXFrameworksBuildPhase section */ 101 | 102 | /* Begin PBXGroup section */ 103 | 493326631F7003A2001B928C = { 104 | isa = PBXGroup; 105 | children = ( 106 | 4933266F1F7003A2001B928C /* GpxKit */, 107 | 4933267A1F7003A3001B928C /* GpxKitTests */, 108 | 4933266E1F7003A2001B928C /* Products */, 109 | 508FB73B7ED71C3B7EC48B5C /* Pods */, 110 | 67D235027B0517657110A903 /* Frameworks */, 111 | ); 112 | sourceTree = ""; 113 | }; 114 | 4933266E1F7003A2001B928C /* Products */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 4933266D1F7003A2001B928C /* GpxKit.framework */, 118 | 493326761F7003A3001B928C /* GpxKitTests.xctest */, 119 | ); 120 | name = Products; 121 | sourceTree = ""; 122 | }; 123 | 4933266F1F7003A2001B928C /* GpxKit */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 4933268A1F70045A001B928C /* Source */, 127 | 493326891F70044A001B928C /* Supporting Files */, 128 | ); 129 | path = GpxKit; 130 | sourceTree = ""; 131 | }; 132 | 4933267A1F7003A3001B928C /* GpxKitTests */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 4933267D1F7003A3001B928C /* Info.plist */, 136 | 616233371FA0F25500A52420 /* Extensions */, 137 | 4996A07E1F70154600A0BE9D /* Gpx Files */, 138 | 4996A07F1F70155800A0BE9D /* Tests */, 139 | ); 140 | path = GpxKitTests; 141 | sourceTree = ""; 142 | }; 143 | 493326891F70044A001B928C /* Supporting Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 493326701F7003A2001B928C /* GpxKit.h */, 147 | 493326711F7003A2001B928C /* Info.plist */, 148 | ); 149 | name = "Supporting Files"; 150 | sourceTree = ""; 151 | }; 152 | 4933268A1F70045A001B928C /* Source */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 493326871F7003B5001B928C /* Gpx.swift */, 156 | 4933268B1F70046E001B928C /* Gpx+Parser.swift */, 157 | 616233351FA0C74000A52420 /* GpxWriter.swift */, 158 | 616233401FA1E2AE00A52420 /* Extensions */, 159 | ); 160 | name = Source; 161 | sourceTree = ""; 162 | }; 163 | 4996A07E1F70154600A0BE9D /* Gpx Files */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 6162333A1FA1DC7300A52420 /* Empty.gpx */, 167 | 616233411FA1E9F800A52420 /* EmptyWithMetadata.gpx */, 168 | 4996A07C1F70154200A0BE9D /* GarminRoute.gpx */, 169 | 4996A0801F701D4100A0BE9D /* Invalid-Attribute-Value.gpx */, 170 | 4996A07A1F70106300A0BE9D /* Invalid-Attribute.gpx */, 171 | 6152083F1FA2110600B0DCB7 /* Route.gpx */, 172 | 4933268D1F7009FD001B928C /* StravaTrack.gpx */, 173 | 49C08B0A21187B340053B8C4 /* Track-Multiple.gpx */, 174 | 615208411FA21AA300B0DCB7 /* Track.gpx */, 175 | F169505D205D273F00BD3355 /* TrackInvalidElevation.gpx */, 176 | 616233311FA0BE9300A52420 /* Waypoints.gpx */, 177 | ); 178 | name = "Gpx Files"; 179 | sourceTree = ""; 180 | }; 181 | 4996A07F1F70155800A0BE9D /* Tests */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 4933267B1F7003A3001B928C /* GpxParserTests.swift */, 185 | 616233331FA0C6E000A52420 /* GpxWriterTests.swift */, 186 | ); 187 | name = Tests; 188 | sourceTree = ""; 189 | }; 190 | 508FB73B7ED71C3B7EC48B5C /* Pods */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 05E34298ECD04DB1EF2E39BB /* Pods-GpxKit.debug.xcconfig */, 194 | E6B3CA0DE6FC6B84CC87CA2E /* Pods-GpxKit.release.xcconfig */, 195 | 21B16DDC2EAAE95A0D5AFD88 /* Pods-GpxKitTests.debug.xcconfig */, 196 | CBDE30710EB582671DEAB5BA /* Pods-GpxKitTests.release.xcconfig */, 197 | C32969201F097FCD02DD7D75 /* Pods-GpxKit-GpxKitTests.debug.xcconfig */, 198 | 037506C9396B194DF33797A8 /* Pods-GpxKit-GpxKitTests.release.xcconfig */, 199 | ); 200 | name = Pods; 201 | sourceTree = ""; 202 | }; 203 | 616233371FA0F25500A52420 /* Extensions */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 49C08B0C21188C270053B8C4 /* CLLocationCoordinate+Equatable.swift */, 207 | 616233381FA0F26900A52420 /* GpxWriter+Extensions.swift */, 208 | ); 209 | name = Extensions; 210 | sourceTree = ""; 211 | }; 212 | 616233401FA1E2AE00A52420 /* Extensions */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 492D155B1FA8F70D0013DB7D /* DateFormatter+Extensions.swift */, 216 | 6162333E1FA1E1A400A52420 /* OutputStream+Extensions.swift */, 217 | ); 218 | name = Extensions; 219 | sourceTree = ""; 220 | }; 221 | 67D235027B0517657110A903 /* Frameworks */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | 156172C678D2BE106A871A1F /* Pods_GpxKit.framework */, 225 | B9CBAC50044AB8884AE57313 /* Pods_GpxKit_GpxKitTests.framework */, 226 | ); 227 | name = Frameworks; 228 | sourceTree = ""; 229 | }; 230 | /* End PBXGroup section */ 231 | 232 | /* Begin PBXHeadersBuildPhase section */ 233 | 4933266A1F7003A2001B928C /* Headers */ = { 234 | isa = PBXHeadersBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | 4933267E1F7003A3001B928C /* GpxKit.h in Headers */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXHeadersBuildPhase section */ 242 | 243 | /* Begin PBXNativeTarget section */ 244 | 4933266C1F7003A2001B928C /* GpxKit */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 493326811F7003A3001B928C /* Build configuration list for PBXNativeTarget "GpxKit" */; 247 | buildPhases = ( 248 | 8126715F9282735420C35D73 /* [CP] Check Pods Manifest.lock */, 249 | 493326681F7003A2001B928C /* Sources */, 250 | 493326691F7003A2001B928C /* Frameworks */, 251 | 4933266A1F7003A2001B928C /* Headers */, 252 | 4933266B1F7003A2001B928C /* Resources */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | ); 258 | name = GpxKit; 259 | productName = GpxKit; 260 | productReference = 4933266D1F7003A2001B928C /* GpxKit.framework */; 261 | productType = "com.apple.product-type.framework"; 262 | }; 263 | 493326751F7003A3001B928C /* GpxKitTests */ = { 264 | isa = PBXNativeTarget; 265 | buildConfigurationList = 493326841F7003A3001B928C /* Build configuration list for PBXNativeTarget "GpxKitTests" */; 266 | buildPhases = ( 267 | 76212E313645D2CCC8898C53 /* [CP] Check Pods Manifest.lock */, 268 | 493326721F7003A3001B928C /* Sources */, 269 | 493326731F7003A3001B928C /* Frameworks */, 270 | 493326741F7003A3001B928C /* Resources */, 271 | 31CEAC8838A93C92348B84AA /* [CP] Embed Pods Frameworks */, 272 | ); 273 | buildRules = ( 274 | ); 275 | dependencies = ( 276 | 493326791F7003A3001B928C /* PBXTargetDependency */, 277 | ); 278 | name = GpxKitTests; 279 | productName = GpxKitTests; 280 | productReference = 493326761F7003A3001B928C /* GpxKitTests.xctest */; 281 | productType = "com.apple.product-type.bundle.unit-test"; 282 | }; 283 | /* End PBXNativeTarget section */ 284 | 285 | /* Begin PBXProject section */ 286 | 493326641F7003A2001B928C /* Project object */ = { 287 | isa = PBXProject; 288 | attributes = { 289 | LastSwiftUpdateCheck = 0830; 290 | LastUpgradeCheck = 0900; 291 | ORGANIZATIONNAME = Beeline; 292 | TargetAttributes = { 293 | 4933266C1F7003A2001B928C = { 294 | CreatedOnToolsVersion = 8.3.3; 295 | LastSwiftMigration = 1240; 296 | ProvisioningStyle = Automatic; 297 | }; 298 | 493326751F7003A3001B928C = { 299 | CreatedOnToolsVersion = 8.3.3; 300 | DevelopmentTeam = HYV9U93759; 301 | LastSwiftMigration = 1240; 302 | ProvisioningStyle = Automatic; 303 | }; 304 | }; 305 | }; 306 | buildConfigurationList = 493326671F7003A2001B928C /* Build configuration list for PBXProject "GpxKit" */; 307 | compatibilityVersion = "Xcode 3.2"; 308 | developmentRegion = English; 309 | hasScannedForEncodings = 0; 310 | knownRegions = ( 311 | English, 312 | en, 313 | ); 314 | mainGroup = 493326631F7003A2001B928C; 315 | productRefGroup = 4933266E1F7003A2001B928C /* Products */; 316 | projectDirPath = ""; 317 | projectRoot = ""; 318 | targets = ( 319 | 4933266C1F7003A2001B928C /* GpxKit */, 320 | 493326751F7003A3001B928C /* GpxKitTests */, 321 | ); 322 | }; 323 | /* End PBXProject section */ 324 | 325 | /* Begin PBXResourcesBuildPhase section */ 326 | 4933266B1F7003A2001B928C /* Resources */ = { 327 | isa = PBXResourcesBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | }; 333 | 493326741F7003A3001B928C /* Resources */ = { 334 | isa = PBXResourcesBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | 4933268E1F7009FD001B928C /* StravaTrack.gpx in Resources */, 338 | 4996A07D1F70154200A0BE9D /* GarminRoute.gpx in Resources */, 339 | 4996A0811F701D4100A0BE9D /* Invalid-Attribute-Value.gpx in Resources */, 340 | 616233421FA1E9F800A52420 /* EmptyWithMetadata.gpx in Resources */, 341 | 6162333B1FA1DC7300A52420 /* Empty.gpx in Resources */, 342 | 615208401FA2110600B0DCB7 /* Route.gpx in Resources */, 343 | 615208421FA21AA300B0DCB7 /* Track.gpx in Resources */, 344 | 4996A07B1F70106300A0BE9D /* Invalid-Attribute.gpx in Resources */, 345 | 616233321FA0BE9300A52420 /* Waypoints.gpx in Resources */, 346 | 49C08B0B21187B340053B8C4 /* Track-Multiple.gpx in Resources */, 347 | F169505E205D273F00BD3355 /* TrackInvalidElevation.gpx in Resources */, 348 | ); 349 | runOnlyForDeploymentPostprocessing = 0; 350 | }; 351 | /* End PBXResourcesBuildPhase section */ 352 | 353 | /* Begin PBXShellScriptBuildPhase section */ 354 | 31CEAC8838A93C92348B84AA /* [CP] Embed Pods Frameworks */ = { 355 | isa = PBXShellScriptBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | ); 359 | inputPaths = ( 360 | "${PODS_ROOT}/Target Support Files/Pods-GpxKit-GpxKitTests/Pods-GpxKit-GpxKitTests-frameworks.sh", 361 | "${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework", 362 | "${BUILT_PRODUCTS_DIR}/SWXMLHash/SWXMLHash.framework", 363 | "${BUILT_PRODUCTS_DIR}/RxBlocking/RxBlocking.framework", 364 | ); 365 | name = "[CP] Embed Pods Frameworks"; 366 | outputPaths = ( 367 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework", 368 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SWXMLHash.framework", 369 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxBlocking.framework", 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | shellPath = /bin/sh; 373 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GpxKit-GpxKitTests/Pods-GpxKit-GpxKitTests-frameworks.sh\"\n"; 374 | showEnvVarsInLog = 0; 375 | }; 376 | 76212E313645D2CCC8898C53 /* [CP] Check Pods Manifest.lock */ = { 377 | isa = PBXShellScriptBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | inputPaths = ( 382 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 383 | "${PODS_ROOT}/Manifest.lock", 384 | ); 385 | name = "[CP] Check Pods Manifest.lock"; 386 | outputPaths = ( 387 | "$(DERIVED_FILE_DIR)/Pods-GpxKit-GpxKitTests-checkManifestLockResult.txt", 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | shellPath = /bin/sh; 391 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 392 | showEnvVarsInLog = 0; 393 | }; 394 | 8126715F9282735420C35D73 /* [CP] Check Pods Manifest.lock */ = { 395 | isa = PBXShellScriptBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | ); 399 | inputPaths = ( 400 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 401 | "${PODS_ROOT}/Manifest.lock", 402 | ); 403 | name = "[CP] Check Pods Manifest.lock"; 404 | outputPaths = ( 405 | "$(DERIVED_FILE_DIR)/Pods-GpxKit-checkManifestLockResult.txt", 406 | ); 407 | runOnlyForDeploymentPostprocessing = 0; 408 | shellPath = /bin/sh; 409 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 410 | showEnvVarsInLog = 0; 411 | }; 412 | /* End PBXShellScriptBuildPhase section */ 413 | 414 | /* Begin PBXSourcesBuildPhase section */ 415 | 493326681F7003A2001B928C /* Sources */ = { 416 | isa = PBXSourcesBuildPhase; 417 | buildActionMask = 2147483647; 418 | files = ( 419 | 6162333F1FA1E1A400A52420 /* OutputStream+Extensions.swift in Sources */, 420 | 4933268C1F70046E001B928C /* Gpx+Parser.swift in Sources */, 421 | 493326881F7003B5001B928C /* Gpx.swift in Sources */, 422 | 616233361FA0C74000A52420 /* GpxWriter.swift in Sources */, 423 | 492D155C1FA8F70D0013DB7D /* DateFormatter+Extensions.swift in Sources */, 424 | ); 425 | runOnlyForDeploymentPostprocessing = 0; 426 | }; 427 | 493326721F7003A3001B928C /* Sources */ = { 428 | isa = PBXSourcesBuildPhase; 429 | buildActionMask = 2147483647; 430 | files = ( 431 | 616233391FA0F26900A52420 /* GpxWriter+Extensions.swift in Sources */, 432 | 616233341FA0C6E000A52420 /* GpxWriterTests.swift in Sources */, 433 | 49C08B0D21188C270053B8C4 /* CLLocationCoordinate+Equatable.swift in Sources */, 434 | 4933267C1F7003A3001B928C /* GpxParserTests.swift in Sources */, 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | /* End PBXSourcesBuildPhase section */ 439 | 440 | /* Begin PBXTargetDependency section */ 441 | 493326791F7003A3001B928C /* PBXTargetDependency */ = { 442 | isa = PBXTargetDependency; 443 | target = 4933266C1F7003A2001B928C /* GpxKit */; 444 | targetProxy = 493326781F7003A3001B928C /* PBXContainerItemProxy */; 445 | }; 446 | /* End PBXTargetDependency section */ 447 | 448 | /* Begin XCBuildConfiguration section */ 449 | 4933267F1F7003A3001B928C /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | ALWAYS_SEARCH_USER_PATHS = NO; 453 | CLANG_ANALYZER_NONNULL = YES; 454 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 455 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 456 | CLANG_CXX_LIBRARY = "libc++"; 457 | CLANG_ENABLE_MODULES = YES; 458 | CLANG_ENABLE_OBJC_ARC = YES; 459 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 460 | CLANG_WARN_BOOL_CONVERSION = YES; 461 | CLANG_WARN_COMMA = YES; 462 | CLANG_WARN_CONSTANT_CONVERSION = YES; 463 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 464 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 465 | CLANG_WARN_EMPTY_BODY = YES; 466 | CLANG_WARN_ENUM_CONVERSION = YES; 467 | CLANG_WARN_INFINITE_RECURSION = YES; 468 | CLANG_WARN_INT_CONVERSION = YES; 469 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 470 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 471 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 472 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 473 | CLANG_WARN_STRICT_PROTOTYPES = YES; 474 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 475 | CLANG_WARN_UNREACHABLE_CODE = YES; 476 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 477 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 478 | COPY_PHASE_STRIP = NO; 479 | CURRENT_PROJECT_VERSION = 1; 480 | DEBUG_INFORMATION_FORMAT = dwarf; 481 | ENABLE_STRICT_OBJC_MSGSEND = YES; 482 | ENABLE_TESTABILITY = YES; 483 | GCC_C_LANGUAGE_STANDARD = gnu99; 484 | GCC_DYNAMIC_NO_PIC = NO; 485 | GCC_NO_COMMON_BLOCKS = YES; 486 | GCC_OPTIMIZATION_LEVEL = 0; 487 | GCC_PREPROCESSOR_DEFINITIONS = ( 488 | "DEBUG=1", 489 | "$(inherited)", 490 | ); 491 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 492 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 493 | GCC_WARN_UNDECLARED_SELECTOR = YES; 494 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 495 | GCC_WARN_UNUSED_FUNCTION = YES; 496 | GCC_WARN_UNUSED_VARIABLE = YES; 497 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 498 | MTL_ENABLE_DEBUG_INFO = YES; 499 | ONLY_ACTIVE_ARCH = YES; 500 | SDKROOT = iphoneos; 501 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 502 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 503 | TARGETED_DEVICE_FAMILY = "1,2"; 504 | VERSIONING_SYSTEM = "apple-generic"; 505 | VERSION_INFO_PREFIX = ""; 506 | }; 507 | name = Debug; 508 | }; 509 | 493326801F7003A3001B928C /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ALWAYS_SEARCH_USER_PATHS = NO; 513 | CLANG_ANALYZER_NONNULL = YES; 514 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 515 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 516 | CLANG_CXX_LIBRARY = "libc++"; 517 | CLANG_ENABLE_MODULES = YES; 518 | CLANG_ENABLE_OBJC_ARC = YES; 519 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 520 | CLANG_WARN_BOOL_CONVERSION = YES; 521 | CLANG_WARN_COMMA = YES; 522 | CLANG_WARN_CONSTANT_CONVERSION = YES; 523 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 524 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 525 | CLANG_WARN_EMPTY_BODY = YES; 526 | CLANG_WARN_ENUM_CONVERSION = YES; 527 | CLANG_WARN_INFINITE_RECURSION = YES; 528 | CLANG_WARN_INT_CONVERSION = YES; 529 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 530 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 531 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 532 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 533 | CLANG_WARN_STRICT_PROTOTYPES = YES; 534 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 535 | CLANG_WARN_UNREACHABLE_CODE = YES; 536 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 537 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 538 | COPY_PHASE_STRIP = NO; 539 | CURRENT_PROJECT_VERSION = 1; 540 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 541 | ENABLE_NS_ASSERTIONS = NO; 542 | ENABLE_STRICT_OBJC_MSGSEND = YES; 543 | GCC_C_LANGUAGE_STANDARD = gnu99; 544 | GCC_NO_COMMON_BLOCKS = YES; 545 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 546 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 547 | GCC_WARN_UNDECLARED_SELECTOR = YES; 548 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 549 | GCC_WARN_UNUSED_FUNCTION = YES; 550 | GCC_WARN_UNUSED_VARIABLE = YES; 551 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 552 | MTL_ENABLE_DEBUG_INFO = NO; 553 | SDKROOT = iphoneos; 554 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 555 | TARGETED_DEVICE_FAMILY = "1,2"; 556 | VALIDATE_PRODUCT = YES; 557 | VERSIONING_SYSTEM = "apple-generic"; 558 | VERSION_INFO_PREFIX = ""; 559 | }; 560 | name = Release; 561 | }; 562 | 493326821F7003A3001B928C /* Debug */ = { 563 | isa = XCBuildConfiguration; 564 | baseConfigurationReference = 05E34298ECD04DB1EF2E39BB /* Pods-GpxKit.debug.xcconfig */; 565 | buildSettings = { 566 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 567 | CLANG_ENABLE_MODULES = YES; 568 | CODE_SIGN_IDENTITY = ""; 569 | DEFINES_MODULE = YES; 570 | DEVELOPMENT_TEAM = ""; 571 | DYLIB_COMPATIBILITY_VERSION = 1; 572 | DYLIB_CURRENT_VERSION = 1; 573 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 574 | INFOPLIST_FILE = GpxKit/Info.plist; 575 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 576 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 578 | MARKETING_VERSION = 2.0.0; 579 | PRODUCT_BUNDLE_IDENTIFIER = co.beeline.GpxKit; 580 | PRODUCT_NAME = "$(TARGET_NAME)"; 581 | SKIP_INSTALL = YES; 582 | SUPPORTS_MACCATALYST = NO; 583 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 584 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 585 | SWIFT_VERSION = 5.0; 586 | TARGETED_DEVICE_FAMILY = "1,2"; 587 | }; 588 | name = Debug; 589 | }; 590 | 493326831F7003A3001B928C /* Release */ = { 591 | isa = XCBuildConfiguration; 592 | baseConfigurationReference = E6B3CA0DE6FC6B84CC87CA2E /* Pods-GpxKit.release.xcconfig */; 593 | buildSettings = { 594 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 595 | CLANG_ENABLE_MODULES = YES; 596 | CODE_SIGN_IDENTITY = ""; 597 | DEFINES_MODULE = YES; 598 | DEVELOPMENT_TEAM = ""; 599 | DYLIB_COMPATIBILITY_VERSION = 1; 600 | DYLIB_CURRENT_VERSION = 1; 601 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 602 | INFOPLIST_FILE = GpxKit/Info.plist; 603 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 604 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 605 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 606 | MARKETING_VERSION = 2.0.0; 607 | PRODUCT_BUNDLE_IDENTIFIER = co.beeline.GpxKit; 608 | PRODUCT_NAME = "$(TARGET_NAME)"; 609 | SKIP_INSTALL = YES; 610 | SUPPORTS_MACCATALYST = NO; 611 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 612 | SWIFT_VERSION = 5.0; 613 | TARGETED_DEVICE_FAMILY = "1,2"; 614 | }; 615 | name = Release; 616 | }; 617 | 493326851F7003A3001B928C /* Debug */ = { 618 | isa = XCBuildConfiguration; 619 | baseConfigurationReference = C32969201F097FCD02DD7D75 /* Pods-GpxKit-GpxKitTests.debug.xcconfig */; 620 | buildSettings = { 621 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 622 | DEVELOPMENT_TEAM = HYV9U93759; 623 | INFOPLIST_FILE = GpxKitTests/Info.plist; 624 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 625 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 626 | PRODUCT_BUNDLE_IDENTIFIER = co.beeline.GpxKitTests; 627 | PRODUCT_NAME = "$(TARGET_NAME)"; 628 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 629 | SWIFT_VERSION = 5.0; 630 | }; 631 | name = Debug; 632 | }; 633 | 493326861F7003A3001B928C /* Release */ = { 634 | isa = XCBuildConfiguration; 635 | baseConfigurationReference = 037506C9396B194DF33797A8 /* Pods-GpxKit-GpxKitTests.release.xcconfig */; 636 | buildSettings = { 637 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 638 | DEVELOPMENT_TEAM = HYV9U93759; 639 | INFOPLIST_FILE = GpxKitTests/Info.plist; 640 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 641 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 642 | PRODUCT_BUNDLE_IDENTIFIER = co.beeline.GpxKitTests; 643 | PRODUCT_NAME = "$(TARGET_NAME)"; 644 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 645 | SWIFT_VERSION = 5.0; 646 | }; 647 | name = Release; 648 | }; 649 | /* End XCBuildConfiguration section */ 650 | 651 | /* Begin XCConfigurationList section */ 652 | 493326671F7003A2001B928C /* Build configuration list for PBXProject "GpxKit" */ = { 653 | isa = XCConfigurationList; 654 | buildConfigurations = ( 655 | 4933267F1F7003A3001B928C /* Debug */, 656 | 493326801F7003A3001B928C /* Release */, 657 | ); 658 | defaultConfigurationIsVisible = 0; 659 | defaultConfigurationName = Release; 660 | }; 661 | 493326811F7003A3001B928C /* Build configuration list for PBXNativeTarget "GpxKit" */ = { 662 | isa = XCConfigurationList; 663 | buildConfigurations = ( 664 | 493326821F7003A3001B928C /* Debug */, 665 | 493326831F7003A3001B928C /* Release */, 666 | ); 667 | defaultConfigurationIsVisible = 0; 668 | defaultConfigurationName = Release; 669 | }; 670 | 493326841F7003A3001B928C /* Build configuration list for PBXNativeTarget "GpxKitTests" */ = { 671 | isa = XCConfigurationList; 672 | buildConfigurations = ( 673 | 493326851F7003A3001B928C /* Debug */, 674 | 493326861F7003A3001B928C /* Release */, 675 | ); 676 | defaultConfigurationIsVisible = 0; 677 | defaultConfigurationName = Release; 678 | }; 679 | /* End XCConfigurationList section */ 680 | }; 681 | rootObject = 493326641F7003A2001B928C /* Project object */; 682 | } 683 | -------------------------------------------------------------------------------- /GpxKitTests/GarminRoute.gpx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Garmin International 6 | 7 | 8 | 9 | 10 | 11 | 12 | DieppeParis1 13 | 14 | 15 | false 16 | Magenta 17 | 18 | 19 | 20 | 21 | Haute-Normandie 22 | Haute-Normandie 23 | Haute-Normandie 24 | Waypoint 25 | 26 | 27 | Direct 28 | 29 | 30 | 1C00E1D0FC03B3005D000D2300002D8235C6 31 | 32 | 33 | 34 | 35 | Road521 36 | Road Road 37 | Road Road 38 | Waypoint 39 | 40 | 41 | Direct 42 | 43 | 44 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 45 | 46 | 47 | 48 | 49 | Road161 50 | Road Road 51 | Road Road 52 | Waypoint 53 | 54 | 55 | Direct 56 | 57 | 58 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 59 | 60 | 61 | 62 | 63 | 64 | land10 65 | land 66 | land 67 | Waypoint 68 | 69 | 70 | Direct 71 | 72 | 73 | 8100E1D0FC03048050000323000027829FC6 74 | 75 | 76 | 77 | 78 | 79 | trunk and Roundabout 80 | trunk and Roundabout 81 | trunk and Roundabout 82 | Waypoint 83 | 84 | 85 | Direct 86 | 87 | 88 | 0280E1D0FC039C005D000F2300003882F7C6 89 | 90 | 91 | 92 | 93 | 94 | trunk and Quai de la Marne and Roundabout 95 | trunk and Quai de la Marne and Roundabout 96 | trunk and Quai de la Marne and Roundabout 97 | Waypoint 98 | 99 | 100 | Direct 101 | 102 | 103 | 0280E1D0FC039C005D000F2300003182FCC6 104 | 105 | 106 | 107 | 108 | Road221 109 | Road Road 110 | Road Road 111 | Waypoint 112 | 113 | 114 | Direct 115 | 116 | 117 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 118 | 119 | 120 | 121 | 122 | Road310 123 | Road Road 124 | Road Road 125 | Waypoint 126 | 127 | 128 | Direct 129 | 130 | 131 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 132 | 133 | 134 | 135 | 136 | 137 | Quai de la Marne1 138 | Quai de la Marne 139 | Quai de la Marne 140 | Waypoint 141 | 142 | 143 | Direct 144 | 145 | 146 | 05C0E1D0FC0379005D000F230000F0810BC6 147 | 148 | 149 | 150 | 151 | Road49 152 | Road Road 153 | Road Road 154 | Waypoint 155 | 156 | 157 | Direct 158 | 159 | 160 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 161 | 162 | 163 | 164 | 165 | 166 | Quai de la Marne2 167 | Quai de la Marne 168 | Quai de la Marne 169 | Waypoint 170 | 171 | 172 | Direct 173 | 174 | 175 | 0500E1D0FC037A005D000D230000EB81E4C5 176 | 177 | 178 | 179 | 180 | 181 | Quai de la Marne4 182 | Quai de la Marne 183 | Quai de la Marne 184 | Waypoint 185 | 186 | 187 | Direct 188 | 189 | 190 | 0500E1D0FC0378005D000F230000DD81C8C5 191 | 192 | 193 | 194 | 195 | 196 | Quai de la Marne3 197 | Quai de la Marne 198 | Quai de la Marne 199 | Waypoint 200 | 201 | 202 | Direct 203 | 204 | 205 | 0540E1D0FC0378005D000F230000D281C3C5 206 | 207 | 208 | 209 | 210 | Quai de la Marne and Place Du Petit Paris1 211 | Quai de la Marne and Place Du Petit Paris Quai de la Marne and Place Du Petit Paris 212 | Quai de la Marne and Place Du Petit Paris Quai de la Marne and Place Du Petit Paris 213 | Waypoint 214 | 215 | 216 | Direct 217 | 218 | 219 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 220 | 221 | 222 | 223 | 224 | 2 Quai de la Somme1 225 | 2 Quai de la Somme 2 Quai de la Somme 226 | 2 Quai de la Somme 2 Quai de la Somme 227 | Waypoint 228 | 229 | 230 | Direct 231 | 232 | 233 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 234 | 235 | 236 | 237 | 238 | 239 | Quai de la Somme2 240 | Quai de la Somme 241 | Quai de la Somme 242 | Waypoint 243 | 244 | 245 | Direct 246 | 247 | 248 | 0500E1D0FC0381005D000D2300002381A5C5 249 | 250 | 251 | 252 | 253 | 254 | Quai de la Somme1 255 | Quai de la Somme 256 | Quai de la Somme 257 | Waypoint 258 | 259 | 260 | Direct 261 | 262 | 263 | 0500E1D0FC0381005D000D2300000B819FC5 264 | 265 | 266 | 267 | 268 | 269 | Grande Rue Du Pollet and Quai de la Somme1 270 | Grande Rue Du Pollet and Quai de la Somme 271 | Grande Rue Du Pollet and Quai de la Somme 272 | Waypoint 273 | 274 | 275 | Direct 276 | 277 | 278 | 0400E1D0FC038B005D000F230000FE80A5C5 279 | 280 | 281 | 282 | 283 | 284 | Grande Rue Du Pollet and Quai de la Somme 285 | Grande Rue Du Pollet and Quai de la Somme 286 | Grande Rue Du Pollet and Quai de la Somme 287 | Waypoint 288 | 289 | 290 | Direct 291 | 292 | 293 | 0480E1D0FC038A005D000F230000FC80B6C5 294 | 295 | 296 | 297 | 298 | 299 | Grande Rue Du Pollet and Rue Joseph Brunel 300 | Grande Rue Du Pollet and Rue Joseph Brunel 301 | Grande Rue Du Pollet and Rue Joseph Brunel 302 | Waypoint 303 | 304 | 305 | Direct 306 | 307 | 308 | 0480E1D0FC038A005D000F230000FE80C6C5 309 | 310 | 311 | 312 | 313 | 314 | Rue Maurice Levasseur and Rue Joseph Brunel and Quai de la Somme and Rue Charles Blound 315 | Rue Maurice Levasseur and Rue Joseph Brunel and Quai de la Somme and Rue Charles Blound 316 | Rue Maurice Levasseur and Rue Joseph Brunel and Quai de la Somme and Rue Charles Blound 317 | Waypoint 318 | 319 | 320 | Direct 321 | 322 | 323 | 0480E1D0FC0393005D000F230000B980F2C5 324 | 325 | 326 | 327 | 328 | 329 | Rue Maurice Levasseur 330 | Rue Maurice Levasseur 331 | Rue Maurice Levasseur 332 | Waypoint 333 | 334 | 335 | Direct 336 | 337 | 338 | 0400E1D0FC0393005D000D230000BB8006C6 339 | 340 | 341 | 342 | 343 | 344 | Rue Maurice Levasseur1 345 | Rue Maurice Levasseur 346 | Rue Maurice Levasseur 347 | Waypoint 348 | 349 | 350 | Direct 351 | 352 | 353 | 0400E1D0FC0393005D000D230000BB8022C6 354 | 355 | 356 | 357 | 358 | 9 Rue Bonne-Nouvelle1 359 | 9 Rue Bonne-Nouvelle 9 Rue Bonne-Nouvelle 360 | 9 Rue Bonne-Nouvelle 9 Rue Bonne-Nouvelle 361 | Waypoint 362 | 363 | 364 | Direct 365 | 366 | 367 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 368 | 369 | 370 | 371 | 372 | 373 | Route Bonne Nouvelle 374 | Route Bonne Nouvelle 375 | Route Bonne Nouvelle 376 | Waypoint 377 | 378 | 379 | Direct 380 | 381 | 382 | 0400E1D0FC0358005A000D230000818086C6 383 | 384 | 385 | 386 | 387 | Route de Bonne-Nouvelle and Cours Bourbon and Rue de L'Ancien Port 388 | Route de Bonne-Nouvelle and Cours Bourbon and Rue de L'Ancien Port Route de Bonne-Nouvelle and Cours Bourbon and Rue de L'Ancien Port 389 | Route de Bonne-Nouvelle and Cours Bourbon and Rue de L'Ancien Port Route de Bonne-Nouvelle and Cours Bourbon and Rue de L'Ancien Port 390 | Waypoint 391 | 392 | 393 | Direct 394 | 395 | 396 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 397 | 398 | 399 | 400 | 401 | Rue de L'Ancien Port1 402 | Rue de L'Ancien Port Rue de L'Ancien Port 403 | Rue de L'Ancien Port Rue de L'Ancien Port 404 | Waypoint 405 | 406 | 407 | Direct 408 | 409 | 410 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 411 | 412 | 413 | 414 | 415 | D485 and Rue de L'Ancien Port1 416 | D485 and Rue de L'Ancien Port D485 and Rue de L'Ancien Port 417 | D485 and Rue de L'Ancien Port D485 and Rue de L'Ancien Port 418 | Waypoint 419 | 420 | 421 | Direct 422 | 423 | 424 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 425 | 426 | 427 | 428 | 429 | 430 | Rue Des Salines (D 1) 431 | Rue Des Salines (D 1) 432 | Rue Des Salines (D 1) 433 | Waypoint 434 | 435 | 436 | Direct 437 | 438 | 439 | 0300E1D0FC0342005F000D230000497D8ACA 440 | 441 | 442 | 443 | 444 | Grande Rue Des Salines3 445 | Grande Rue Des Salines Grande Rue Des Salines 446 | Grande Rue Des Salines Grande Rue Des Salines 447 | Waypoint 448 | 449 | 450 | Direct 451 | 452 | 453 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 454 | 455 | 456 | 457 | 458 | Grande Rue Des Salines11 459 | Grande Rue Des Salines Grande Rue Des Salines 460 | Grande Rue Des Salines Grande Rue Des Salines 461 | Waypoint 462 | 463 | 464 | Direct 465 | 466 | 467 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 468 | 469 | 470 | 471 | 472 | 473 | Rue Des Salines (D 1)1 474 | Rue Des Salines (D 1) 475 | Rue Des Salines (D 1) 476 | Waypoint 477 | 478 | 479 | Direct 480 | 481 | 482 | 0300E1D0FC0342005F000D2300005A7CD3CC 483 | 484 | 485 | 486 | 487 | Grande Rue Des Salines21 488 | Grande Rue Des Salines Grande Rue Des Salines 489 | Grande Rue Des Salines Grande Rue Des Salines 490 | Waypoint 491 | 492 | 493 | Direct 494 | 495 | 496 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 497 | 498 | 499 | 500 | 501 | 502 | primary and residential and Roundabout 503 | primary and residential and Roundabout 504 | primary and residential and Roundabout 505 | Waypoint 506 | 507 | 508 | Direct 509 | 510 | 511 | 0300E1D0FC036A005F000F230000317CD1CD 512 | 513 | 514 | 515 | 516 | Rue Saint-Martin1 517 | Rue Saint-Martin Rue Saint-Martin 518 | Rue Saint-Martin Rue Saint-Martin 519 | Waypoint 520 | 521 | 522 | Direct 523 | 524 | 525 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 526 | 527 | 528 | 529 | 530 | 531 | Rue Henri Iv (D 1) and Rue de L'Abbé Malais 532 | Rue Henri Iv (D 1) and Rue de L'Abbé Malais 533 | Rue Henri Iv (D 1) and Rue de L'Abbé Malais 534 | Waypoint 535 | 536 | 537 | Direct 538 | 539 | 540 | 0380E1D0FC0344005F000F230000247CCBCF 541 | 542 | 543 | 544 | 545 | 546 | Rue Henri Iv (D 1) and Rue de la Forêt 547 | Rue Henri Iv (D 1) and Rue de la Forêt 548 | Rue Henri Iv (D 1) and Rue de la Forêt 549 | Waypoint 550 | 551 | 552 | Direct 553 | 554 | 555 | 0340E1D0FC0359005F000F230000D07BEBCF 556 | 557 | 558 | 559 | 560 | D13 561 | D1 D1 562 | D1 D1 563 | Waypoint 564 | 565 | 566 | Direct 567 | 568 | 569 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 570 | 571 | 572 | 573 | 574 | D111 575 | D1 D1 576 | D1 D1 577 | Waypoint 578 | 579 | 580 | Direct 581 | 582 | 583 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 584 | 585 | 586 | 587 | 588 | 589 | Route de Dieppe (D 1) 590 | Route de Dieppe (D 1) 591 | Route de Dieppe (D 1) 592 | Waypoint 593 | 594 | 595 | Direct 596 | 597 | 598 | 0300E1D0FC0343005F000D230000007BBACE 599 | 600 | 601 | 602 | 603 | Route de Martin Église and D1 604 | Route de Martin Église and D1 Route de Martin Église and D1 605 | Route de Martin Église and D1 Route de Martin Église and D1 606 | Waypoint 607 | 608 | 609 | Direct 610 | 611 | 612 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 613 | 614 | 615 | 616 | 617 | Route de Martin Église and Rue Jean-Baptiste Clément 618 | Route de Martin Église and Rue Jean-Baptiste Clément Route de Martin Église and Rue Jean-Baptiste Clément 619 | Route de Martin Église and Rue Jean-Baptiste Clément Route de Martin Église and Rue Jean-Baptiste Clément 620 | Waypoint 621 | 622 | 623 | Direct 624 | 625 | 626 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 627 | 628 | 629 | 630 | 631 | Route de Martin Église and D1 and D54 632 | Route de Martin Église and D1 and D54 Route de Martin Église and D1 and D54 633 | Route de Martin Église and D1 and D54 Route de Martin Église and D1 and D54 634 | Waypoint 635 | 636 | 637 | Direct 638 | 639 | 640 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 641 | 642 | 643 | 644 | 645 | 646 | Rond-Point Des Fusillés 647 | Rond-Point Des Fusillés 648 | Rond-Point Des Fusillés 649 | Waypoint 650 | 651 | 652 | Direct 653 | 654 | 655 | 0300E1D0FC038B005F000D230000DA78CACF 656 | 657 | 658 | 659 | 660 | 661 | Rue Verdier Monetti (D 54) 662 | Waypoint 663 | 664 | 665 | Direct 666 | 667 | 668 | 0400E1D0FC03A1005F000D230000B2786CCF 669 | 670 | 671 | 672 | 673 | 674 | 29 Rue Verdier Monetti 675 | Waypoint 676 | 677 | 678 | Direct 679 | 680 | 681 | 0000752551006D3F03000101000039230000 682 | 683 | 684 | 685 | 686 | 687 | Route de Dieppe (D 1)1 688 | Route de Dieppe (D 1) 689 | Route de Dieppe (D 1) 690 | Waypoint 691 | 692 | 693 | Direct 694 | 695 | 696 | 0300E1D0FC038B0050000D230000A87833D0 697 | 698 | 699 | 700 | 701 | 702 | Chemin Des Prairies 703 | Waypoint 704 | 705 | 706 | Direct 707 | 708 | 709 | 0500E1D0FC038F0050000D2300001D78AACE 710 | 711 | 712 | 713 | 714 | D121 715 | D1 D1 716 | D1 D1 717 | Waypoint 718 | 719 | 720 | Direct 721 | 722 | 723 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 724 | 725 | 726 | 727 | 728 | 729 | Railroad6 730 | Waypoint 731 | 732 | 733 | Direct 734 | 735 | 736 | 140075255100010020010D2300009477AFCF 737 | 738 | 739 | 740 | 741 | 742 | Road39 743 | Waypoint 744 | 745 | 746 | Direct 747 | 748 | 749 | 060075255100030020010D230000627796D0 750 | 751 | 752 | 753 | 754 | 755 | Track6 756 | Waypoint 757 | 758 | 759 | Direct 760 | 761 | 762 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 763 | 764 | 765 | 766 | 767 | 768 | Road40 769 | Waypoint 770 | 771 | 772 | Direct 773 | 774 | 775 | 0600752551000D001F010D2300001D773BD1 776 | 777 | 778 | 779 | 780 | 781 | Road44 782 | Waypoint 783 | 784 | 785 | Direct 786 | 787 | 788 | 0600752551000D001F010D230000267709D2 789 | 790 | 791 | 792 | 793 | 794 | Road45 795 | Waypoint 796 | 797 | 798 | Direct 799 | 800 | 801 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 802 | 803 | 804 | 805 | 806 | 807 | Avenue Verte and Road2 808 | Waypoint 809 | 810 | 811 | Direct 812 | 813 | 814 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 815 | 816 | 817 | 818 | 819 | 820 | Avenue Verte Cw Véloroute Paris-Londres (N21)1 821 | Avenue Verte Cw Véloroute Paris-Londres (N21) 822 | Avenue Verte Cw Véloroute Paris-Londres (N21) 823 | Waypoint 824 | 825 | 826 | Direct 827 | 828 | 829 | 1300E1D0FC035E0050000D2300001777C5D3 830 | 831 | 832 | 833 | 834 | Avenue Verte110 835 | Avenue Verte Avenue Verte 836 | Avenue Verte Avenue Verte 837 | Waypoint 838 | 839 | 840 | Direct 841 | 842 | 843 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 844 | 845 | 846 | 847 | 848 | 849 | (D 149) 850 | (D 149) 851 | (D 149) 852 | Waypoint 853 | 854 | 855 | Direct 856 | 857 | 858 | 0500E1D0FC032E0050000D2300001A7689D6 859 | 860 | 861 | 862 | 863 | Avenue Verte and Rue Du Biffret1 864 | Avenue Verte and Rue Du Biffret Avenue Verte and Rue Du Biffret 865 | Avenue Verte and Rue Du Biffret Avenue Verte and Rue Du Biffret 866 | Waypoint 867 | 868 | 869 | Direct 870 | 871 | 872 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 873 | 874 | 875 | 876 | 877 | 878 | tertiary1 879 | tertiary 880 | tertiary 881 | Waypoint 882 | 883 | 884 | Direct 885 | 886 | 887 | 05004ED1FC03C10099000D230000E97428DA 888 | 889 | 890 | 891 | 892 | Rue Du Vieux Puits and Avenue Verte1 893 | Rue Du Vieux Puits and Avenue Verte Rue Du Vieux Puits and Avenue Verte 894 | Rue Du Vieux Puits and Avenue Verte Rue Du Vieux Puits and Avenue Verte 895 | Waypoint 896 | 897 | 898 | Direct 899 | 900 | 901 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 902 | 903 | 904 | 905 | 906 | Avenue Verte37 907 | Avenue Verte Avenue Verte 908 | Avenue Verte Avenue Verte 909 | Waypoint 910 | 911 | 912 | Direct 913 | 914 | 915 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 916 | 917 | 918 | 919 | 920 | Avenue Verte and Route D'Écremesnil 921 | Avenue Verte and Route D'Écremesnil Avenue Verte and Route D'Écremesnil 922 | Avenue Verte and Route D'Écremesnil Avenue Verte and Route D'Écremesnil 923 | Waypoint 924 | 925 | 926 | Direct 927 | 928 | 929 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 930 | 931 | 932 | 933 | 934 | Avenue Verte41 935 | Avenue Verte Avenue Verte 936 | Avenue Verte Avenue Verte 937 | Waypoint 938 | 939 | 940 | Direct 941 | 942 | 943 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 944 | 945 | 946 | 947 | 948 | Stade Jacky Schapman1 949 | Stade Jacky Schapman Stade Jacky Schapman 950 | Stade Jacky Schapman Stade Jacky Schapman 951 | Waypoint 952 | 953 | 954 | Direct 955 | 956 | 957 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 958 | 959 | 960 | 961 | 962 | Avenue Verte51 963 | Avenue Verte Avenue Verte 964 | Avenue Verte Avenue Verte 965 | Waypoint 966 | 967 | 968 | Direct 969 | 970 | 971 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 972 | 973 | 974 | 975 | 976 | D1 B and Rue Du Colombier and Avenue Verte1 977 | D1 B and Rue Du Colombier and Avenue Verte D1 B and Rue Du Colombier and Avenue Verte 978 | D1 B and Rue Du Colombier and Avenue Verte D1 B and Rue Du Colombier and Avenue Verte 979 | Waypoint 980 | 981 | 982 | Direct 983 | 984 | 985 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 986 | 987 | 988 | 989 | 990 | Rue Du Stade and Avenue Verte1 991 | Rue Du Stade and Avenue Verte Rue Du Stade and Avenue Verte 992 | Rue Du Stade and Avenue Verte Rue Du Stade and Avenue Verte 993 | Waypoint 994 | 995 | 996 | Direct 997 | 998 | 999 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1000 | 1001 | 1002 | 1003 | 1004 | Route de Neufchâtel1 1005 | Route de Neufchâtel Route de Neufchâtel 1006 | Route de Neufchâtel Route de Neufchâtel 1007 | Waypoint 1008 | 1009 | 1010 | Direct 1011 | 1012 | 1013 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1014 | 1015 | 1016 | 1017 | 1018 | Avenue Verte81 1019 | Avenue Verte Avenue Verte 1020 | Avenue Verte Avenue Verte 1021 | Waypoint 1022 | 1023 | 1024 | Direct 1025 | 1026 | 1027 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1028 | 1029 | 1030 | 1031 | 1032 | Avenue Verte91 1033 | Avenue Verte Avenue Verte 1034 | Avenue Verte Avenue Verte 1035 | Waypoint 1036 | 1037 | 1038 | Direct 1039 | 1040 | 1041 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1042 | 1043 | 1044 | 1045 | 1046 | Avenue Verte101 1047 | Avenue Verte Avenue Verte 1048 | Avenue Verte Avenue Verte 1049 | Waypoint 1050 | 1051 | 1052 | Direct 1053 | 1054 | 1055 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1056 | 1057 | 1058 | 1059 | 1060 | D114 and Avenue Verte1 1061 | D114 and Avenue Verte D114 and Avenue Verte 1062 | D114 and Avenue Verte D114 and Avenue Verte 1063 | Waypoint 1064 | 1065 | 1066 | Direct 1067 | 1068 | 1069 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1070 | 1071 | 1072 | 1073 | 1074 | Avenue Verte111 1075 | Avenue Verte Avenue Verte 1076 | Avenue Verte Avenue Verte 1077 | Waypoint 1078 | 1079 | 1080 | Direct 1081 | 1082 | 1083 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1084 | 1085 | 1086 | 1087 | 1088 | D77 and Avenue Verte1 1089 | D77 and Avenue Verte D77 and Avenue Verte 1090 | D77 and Avenue Verte D77 and Avenue Verte 1091 | Waypoint 1092 | 1093 | 1094 | Direct 1095 | 1096 | 1097 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1098 | 1099 | 1100 | 1101 | 1102 | Rue Du Calvaire1 1103 | Rue Du Calvaire Rue Du Calvaire 1104 | Rue Du Calvaire Rue Du Calvaire 1105 | Waypoint 1106 | 1107 | 1108 | Direct 1109 | 1110 | 1111 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1112 | 1113 | 1114 | 1115 | 1116 | D12 and Avenue Verte1 1117 | D12 and Avenue Verte D12 and Avenue Verte 1118 | D12 and Avenue Verte D12 and Avenue Verte 1119 | Waypoint 1120 | 1121 | 1122 | Direct 1123 | 1124 | 1125 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1126 | 1127 | 1128 | 1129 | 1130 | Avenue Verte121 1131 | Avenue Verte Avenue Verte 1132 | Avenue Verte Avenue Verte 1133 | Waypoint 1134 | 1135 | 1136 | Direct 1137 | 1138 | 1139 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1140 | 1141 | 1142 | 1143 | 1144 | Avenue Verte and Unpaved Road1 1145 | Avenue Verte and Unpaved Road Avenue Verte and Unpaved Road 1146 | Avenue Verte and Unpaved Road Avenue Verte and Unpaved Road 1147 | Waypoint 1148 | 1149 | 1150 | Direct 1151 | 1152 | 1153 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1154 | 1155 | 1156 | 1157 | 1158 | Avenue Verte and Rue de Mesnerettes and Road1 1159 | Avenue Verte and Rue de Mesnerettes and Road Avenue Verte and Rue de Mesnerettes and Road 1160 | Avenue Verte and Rue de Mesnerettes and Road Avenue Verte and Rue de Mesnerettes and Road 1161 | Waypoint 1162 | 1163 | 1164 | Direct 1165 | 1166 | 1167 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1168 | 1169 | 1170 | 1171 | 1172 | Rue Du Château and Avenue Verte1 1173 | Rue Du Château and Avenue Verte Rue Du Château and Avenue Verte 1174 | Rue Du Château and Avenue Verte Rue Du Château and Avenue Verte 1175 | Waypoint 1176 | 1177 | 1178 | Direct 1179 | 1180 | 1181 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1182 | 1183 | 1184 | 1185 | 1186 | Avenue Verte and Road11 1187 | Avenue Verte and Road Avenue Verte and Road 1188 | Avenue Verte and Road Avenue Verte and Road 1189 | Waypoint 1190 | 1191 | 1192 | Direct 1193 | 1194 | 1195 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1196 | 1197 | 1198 | 1199 | 1200 | Avenue Verte131 1201 | Avenue Verte Avenue Verte 1202 | Avenue Verte Avenue Verte 1203 | Waypoint 1204 | 1205 | 1206 | Direct 1207 | 1208 | 1209 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1210 | 1211 | 1212 | 1213 | 1214 | Avenue Verte141 1215 | Avenue Verte Avenue Verte 1216 | Avenue Verte Avenue Verte 1217 | Waypoint 1218 | 1219 | 1220 | Direct 1221 | 1222 | 1223 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1224 | 1225 | 1226 | 1227 | 1228 | Rue de L'Aulage and Avenue Verte1 1229 | Rue de L'Aulage and Avenue Verte Rue de L'Aulage and Avenue Verte 1230 | Rue de L'Aulage and Avenue Verte Rue de L'Aulage and Avenue Verte 1231 | Waypoint 1232 | 1233 | 1234 | Direct 1235 | 1236 | 1237 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1238 | 1239 | 1240 | 1241 | 1242 | Avenue Verte151 1243 | Avenue Verte Avenue Verte 1244 | Avenue Verte Avenue Verte 1245 | Waypoint 1246 | 1247 | 1248 | Direct 1249 | 1250 | 1251 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1252 | 1253 | 1254 | 1255 | 1256 | Avenue Verte161 1257 | Avenue Verte Avenue Verte 1258 | Avenue Verte Avenue Verte 1259 | Waypoint 1260 | 1261 | 1262 | Direct 1263 | 1264 | 1265 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1266 | 1267 | 1268 | 1269 | 1270 | Avenue Verte171 1271 | Avenue Verte Avenue Verte 1272 | Avenue Verte Avenue Verte 1273 | Waypoint 1274 | 1275 | 1276 | Direct 1277 | 1278 | 1279 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1280 | 1281 | 1282 | 1283 | 1284 | Avenue Verte181 1285 | Avenue Verte Avenue Verte 1286 | Avenue Verte Avenue Verte 1287 | Waypoint 1288 | 1289 | 1290 | Direct 1291 | 1292 | 1293 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1294 | 1295 | 1296 | 1297 | 1298 | Avenue Verte191 1299 | Avenue Verte Avenue Verte 1300 | Avenue Verte Avenue Verte 1301 | Waypoint 1302 | 1303 | 1304 | Direct 1305 | 1306 | 1307 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1308 | 1309 | 1310 | 1311 | 1312 | Avenue Verte201 1313 | Avenue Verte Avenue Verte 1314 | Avenue Verte Avenue Verte 1315 | Waypoint 1316 | 1317 | 1318 | Direct 1319 | 1320 | 1321 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1322 | 1323 | 1324 | 1325 | 1326 | Avenue Verte211 1327 | Avenue Verte Avenue Verte 1328 | Avenue Verte Avenue Verte 1329 | Waypoint 1330 | 1331 | 1332 | Direct 1333 | 1334 | 1335 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1336 | 1337 | 1338 | 1339 | 1340 | Avenue Verte221 1341 | Avenue Verte Avenue Verte 1342 | Avenue Verte Avenue Verte 1343 | Waypoint 1344 | 1345 | 1346 | Direct 1347 | 1348 | 1349 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1350 | 1351 | 1352 | 1353 | 1354 | Avenue Verte231 1355 | Avenue Verte Avenue Verte 1356 | Avenue Verte Avenue Verte 1357 | Waypoint 1358 | 1359 | 1360 | Direct 1361 | 1362 | 1363 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1364 | 1365 | 1366 | 1367 | 1368 | Avenue Verte241 1369 | Avenue Verte Avenue Verte 1370 | Avenue Verte Avenue Verte 1371 | Waypoint 1372 | 1373 | 1374 | Direct 1375 | 1376 | 1377 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1378 | 1379 | 1380 | 1381 | 1382 | Avenue Verte251 1383 | Avenue Verte Avenue Verte 1384 | Avenue Verte Avenue Verte 1385 | Waypoint 1386 | 1387 | 1388 | Direct 1389 | 1390 | 1391 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1392 | 1393 | 1394 | 1395 | 1396 | Avenue Verte261 1397 | Avenue Verte Avenue Verte 1398 | Avenue Verte Avenue Verte 1399 | Waypoint 1400 | 1401 | 1402 | Direct 1403 | 1404 | 1405 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1406 | 1407 | 1408 | 1409 | 1410 | Avenue Verte271 1411 | Avenue Verte Avenue Verte 1412 | Avenue Verte Avenue Verte 1413 | Waypoint 1414 | 1415 | 1416 | Direct 1417 | 1418 | 1419 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1420 | 1421 | 1422 | 1423 | 1424 | Avenue Verte281 1425 | Avenue Verte Avenue Verte 1426 | Avenue Verte Avenue Verte 1427 | Waypoint 1428 | 1429 | 1430 | Direct 1431 | 1432 | 1433 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1434 | 1435 | 1436 | 1437 | 1438 | Impasse Du Frais Agneau and Avenue Verte1 1439 | Impasse Du Frais Agneau and Avenue Verte Impasse Du Frais Agneau and Avenue Verte 1440 | Impasse Du Frais Agneau and Avenue Verte Impasse Du Frais Agneau and Avenue Verte 1441 | Waypoint 1442 | 1443 | 1444 | Direct 1445 | 1446 | 1447 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1448 | 1449 | 1450 | 1451 | 1452 | Avenue Verte291 1453 | Avenue Verte Avenue Verte 1454 | Avenue Verte Avenue Verte 1455 | Waypoint 1456 | 1457 | 1458 | Direct 1459 | 1460 | 1461 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1462 | 1463 | 1464 | 1465 | 1466 | Avenue Verte301 1467 | Avenue Verte Avenue Verte 1468 | Avenue Verte Avenue Verte 1469 | Waypoint 1470 | 1471 | 1472 | Direct 1473 | 1474 | 1475 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1476 | 1477 | 1478 | 1479 | 1480 | Avenue Verte311 1481 | Avenue Verte Avenue Verte 1482 | Avenue Verte Avenue Verte 1483 | Waypoint 1484 | 1485 | 1486 | Direct 1487 | 1488 | 1489 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1490 | 1491 | 1492 | 1493 | 1494 | Avenue Verte321 1495 | Avenue Verte Avenue Verte 1496 | Avenue Verte Avenue Verte 1497 | Waypoint 1498 | 1499 | 1500 | Direct 1501 | 1502 | 1503 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1504 | 1505 | 1506 | 1507 | 1508 | Avenue Verte and Impasse Du Mesnil Signaux1 1509 | Avenue Verte and Impasse Du Mesnil Signaux Avenue Verte and Impasse Du Mesnil Signaux 1510 | Avenue Verte and Impasse Du Mesnil Signaux Avenue Verte and Impasse Du Mesnil Signaux 1511 | Waypoint 1512 | 1513 | 1514 | Direct 1515 | 1516 | 1517 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1518 | 1519 | 1520 | 1521 | 1522 | Avenue Verte331 1523 | Avenue Verte Avenue Verte 1524 | Avenue Verte Avenue Verte 1525 | Waypoint 1526 | 1527 | 1528 | Direct 1529 | 1530 | 1531 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1532 | 1533 | 1534 | 1535 | 1536 | D102 and Avenue Verte1 1537 | D102 and Avenue Verte D102 and Avenue Verte 1538 | D102 and Avenue Verte D102 and Avenue Verte 1539 | Waypoint 1540 | 1541 | 1542 | Direct 1543 | 1544 | 1545 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1546 | 1547 | 1548 | 1549 | 1550 | Avenue Verte341 1551 | Avenue Verte Avenue Verte 1552 | Avenue Verte Avenue Verte 1553 | Waypoint 1554 | 1555 | 1556 | Direct 1557 | 1558 | 1559 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1560 | 1561 | 1562 | 1563 | 1564 | Route de la Rosière and Avenue Verte2 1565 | Route de la Rosière and Avenue Verte Route de la Rosière and Avenue Verte 1566 | Route de la Rosière and Avenue Verte Route de la Rosière and Avenue Verte 1567 | Waypoint 1568 | 1569 | 1570 | Direct 1571 | 1572 | 1573 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1574 | 1575 | 1576 | 1577 | 1578 | Avenue Verte351 1579 | Avenue Verte Avenue Verte 1580 | Avenue Verte Avenue Verte 1581 | Waypoint 1582 | 1583 | 1584 | Direct 1585 | 1586 | 1587 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1588 | 1589 | 1590 | 1591 | 1592 | Route de la Rosière and Avenue Verte11 1593 | Route de la Rosière and Avenue Verte Route de la Rosière and Avenue Verte 1594 | Route de la Rosière and Avenue Verte Route de la Rosière and Avenue Verte 1595 | Waypoint 1596 | 1597 | 1598 | Direct 1599 | 1600 | 1601 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1602 | 1603 | 1604 | 1605 | 1606 | Avenue Verte361 1607 | Avenue Verte Avenue Verte 1608 | Avenue Verte Avenue Verte 1609 | Waypoint 1610 | 1611 | 1612 | Direct 1613 | 1614 | 1615 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1616 | 1617 | 1618 | 1619 | 1620 | Route de Beaussault and Avenue Verte1 1621 | Route de Beaussault and Avenue Verte Route de Beaussault and Avenue Verte 1622 | Route de Beaussault and Avenue Verte Route de Beaussault and Avenue Verte 1623 | Waypoint 1624 | 1625 | 1626 | Direct 1627 | 1628 | 1629 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1630 | 1631 | 1632 | 1633 | 1634 | Route de Beaussault and D83 and Place de la Presle 1635 | Route de Beaussault and D83 and Place de la Presle Route de Beaussault and D83 and Place de la Presle 1636 | Route de Beaussault and D83 and Place de la Presle Route de Beaussault and D83 and Place de la Presle 1637 | Waypoint 1638 | 1639 | 1640 | Direct 1641 | 1642 | 1643 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1644 | 1645 | 1646 | 1647 | 1648 | D831 1649 | D83 D83 1650 | D83 D83 1651 | Waypoint 1652 | 1653 | 1654 | Direct 1655 | 1656 | 1657 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1658 | 1659 | 1660 | 1661 | 1662 | Route de Neufchâtel and D831 1663 | Route de Neufchâtel and D83 Route de Neufchâtel and D83 1664 | Route de Neufchâtel and D83 Route de Neufchâtel and D83 1665 | Waypoint 1666 | 1667 | 1668 | Direct 1669 | 1670 | 1671 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1672 | 1673 | 1674 | 1675 | 1676 | Railroad5 1677 | Railroad Railroad 1678 | Railroad Railroad 1679 | Waypoint 1680 | 1681 | 1682 | Direct 1683 | 1684 | 1685 | 000000000000FFFFFFFFFFFFFFFFFFFFFFFF 1686 | 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | --------------------------------------------------------------------------------