From 8de58db44ffdb34eba24b20ec156ca36e64cd6aa Mon Sep 17 00:00:00 2001 From: Thomas Rasch Date: Thu, 23 May 2024 15:47:46 +0200 Subject: [PATCH] Code cleanup --- Package.resolved | 8 +- Package.swift | 4 +- Sources/MVTCLI/CLI.swift | 12 +- Sources/MVTCLI/Export.swift | 2 +- .../MVTCLI/Extensions/ArrayExtensions.swift | 6 +- .../MVTCLI/Extensions/StringExtensions.swift | 2 +- Sources/MVTCLI/Merge.swift | 8 +- Sources/MVTCLI/Query.swift | 10 +- .../MVTTools/Extensions/ArrayExtensions.swift | 11 +- .../Extensions/DictionaryExtensions.swift | 2 +- .../MVTTools/Extensions/RingExtensions.swift | 6 +- Sources/MVTTools/VectorTile.swift | 109 +++++++++++++----- Sources/MVTTools/VectorTileDecoder.swift | 42 +++---- Sources/MVTTools/VectorTileEncoder.swift | 51 ++++---- .../MVTTools/VectorTileExportOptions.swift | 6 +- Sources/MVTTools/VectorTileGeoJson.swift | 4 +- Sources/MVTTools/VectorTileInfo.swift | 4 +- Sources/MVTTools/VectorTileMerge.swift | 2 +- Sources/MVTTools/VectorTileQuery.swift | 41 +++---- .../MVTToolsTests/ArrayExtensionsTests.swift | 2 +- Tests/MVTToolsTests/DecoderTests.swift | 14 +-- Tests/MVTToolsTests/EncoderTests.swift | 94 +++++++-------- Tests/MVTToolsTests/ProjectionTests.swift | 20 ++-- Tests/MVTToolsTests/QueryTests.swift | 6 +- Tests/MVTToolsTests/TestData.swift | 6 +- Tests/MVTToolsTests/VectorTileTests.swift | 12 +- 26 files changed, 266 insertions(+), 218 deletions(-) diff --git a/Package.resolved b/Package.resolved index f7fd02f..8e59d95 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Outdooractive/gis-tools", "state" : { - "revision" : "3a72a667c557e84527be32e5fa7ff34953716868", - "version" : "1.4.0" + "revision" : "35554734fbe059660509ee9403ffa4fbfbc1051c", + "version" : "1.5.0" } }, { @@ -23,8 +23,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-argument-parser", "state" : { - "revision" : "46989693916f56d1186bd59ac15124caef896560", - "version" : "1.3.1" + "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b", + "version" : "1.4.0" } }, { diff --git a/Package.swift b/Package.swift index bca7682..537c49f 100644 --- a/Package.swift +++ b/Package.swift @@ -19,9 +19,9 @@ let package = Package( targets: ["MVTTools"]), ], dependencies: [ - .package(url: "https://github.com/Outdooractive/gis-tools", from: "1.4.0"), + .package(url: "https://github.com/Outdooractive/gis-tools", from: "1.5.0"), .package(url: "https://github.com/1024jp/GzipSwift.git", from: "5.2.0"), - .package(url: "https://github.com/apple/swift-argument-parser", from: "1.3.1"), + .package(url: "https://github.com/apple/swift-argument-parser", from: "1.4.0"), .package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"), .package(url: "https://github.com/apple/swift-protobuf", from: "1.26.0"), ], diff --git a/Sources/MVTCLI/CLI.swift b/Sources/MVTCLI/CLI.swift index 69e93cf..3f49b73 100644 --- a/Sources/MVTCLI/CLI.swift +++ b/Sources/MVTCLI/CLI.swift @@ -6,7 +6,7 @@ import MVTTools @main struct CLI: AsyncParsableCommand { - static let logger: Logger = Logger(label: "mvttool") + static let logger = Logger(label: "mvttool") static var configuration = CommandConfiguration( commandName: "mvt", @@ -20,7 +20,7 @@ struct CLI: AsyncParsableCommand { struct Options: ParsableArguments { @Flag(name: .shortAndLong, help: "Print some debug info") - var verbose: Bool = false + var verbose = false @Option(name: .short, help: "Tile zoom level - if it can't be extracted from the path") var z: Int? @@ -90,16 +90,16 @@ struct Options: ParsableArguments { } } - guard let x = x, - let y = y, - let z = z + guard let x, + let y, + let z else { throw "Need z, x and y" } guard x >= 0 else { throw "x must be >= 0" } guard y >= 0 else { throw "y must be >= 0" } guard z >= 0 else { throw "z must be >= 0" } - let maximumTileCoordinate: Int = 1 << z + let maximumTileCoordinate = 1 << z if x >= maximumTileCoordinate { throw "x at zoom \(z) must be smaller than \(maximumTileCoordinate)" } if y >= maximumTileCoordinate { throw "y at zoom \(z) must be smaller than \(maximumTileCoordinate)" } diff --git a/Sources/MVTCLI/Export.swift b/Sources/MVTCLI/Export.swift index fdd38a3..b44c8b5 100644 --- a/Sources/MVTCLI/Export.swift +++ b/Sources/MVTCLI/Export.swift @@ -15,7 +15,7 @@ extension CLI { var layer: [String] = [] @Flag(name: .shortAndLong, help: "Format the output GeoJSON") - var prettyPrint: Bool = false + var prettyPrint = false @OptionGroup var options: Options diff --git a/Sources/MVTCLI/Extensions/ArrayExtensions.swift b/Sources/MVTCLI/Extensions/ArrayExtensions.swift index 4e21151..b3c9ac1 100644 --- a/Sources/MVTCLI/Extensions/ArrayExtensions.swift +++ b/Sources/MVTCLI/Extensions/ArrayExtensions.swift @@ -3,11 +3,13 @@ import Foundation extension Array { var nonempty: Self? { - self.isEmpty ? nil : self + isEmpty ? nil : self } func get(at index: Int) -> Element? { - guard index >= -count && index < count else { return nil } + guard index >= -count, + index < count + else { return nil } if index >= 0 { return self[index] diff --git a/Sources/MVTCLI/Extensions/StringExtensions.swift b/Sources/MVTCLI/Extensions/StringExtensions.swift index 26c0a51..618f476 100644 --- a/Sources/MVTCLI/Extensions/StringExtensions.swift +++ b/Sources/MVTCLI/Extensions/StringExtensions.swift @@ -24,7 +24,7 @@ extension String { options: NSRegularExpression.MatchingOptions(), range: NSRange(startIndex..., in: self), using: { (matchResult, flags, stop) in - guard let matchResult = matchResult else { return } + guard let matchResult else { return } for i in 1 ..< matchResult.numberOfRanges { if let range = Range(matchResult.range(at: i), in: self) { diff --git a/Sources/MVTCLI/Merge.swift b/Sources/MVTCLI/Merge.swift index 69601ca..0081d41 100644 --- a/Sources/MVTCLI/Merge.swift +++ b/Sources/MVTCLI/Merge.swift @@ -3,11 +3,11 @@ import Foundation import MVTTools extension CLI { - + struct Merge: AsyncParsableCommand { static var configuration = CommandConfiguration(abstract: "Merge two or more vector tiles") - + @Option(name: .shortAndLong, help: "Output file") var output: String @@ -69,7 +69,7 @@ extension CLI { simplifyFeatures: .no) tile.write(to: outputUrl, options: exportOptions) } - + } - + } diff --git a/Sources/MVTCLI/Query.swift b/Sources/MVTCLI/Query.swift index 5821add..15666f6 100644 --- a/Sources/MVTCLI/Query.swift +++ b/Sources/MVTCLI/Query.swift @@ -28,8 +28,8 @@ extension CLI { if let partLatitude = Double(possibleCoordinateParts[0]), let partLongitude = Double(possibleCoordinateParts[1]), let partTolerance = Double(possibleCoordinateParts[2]), - (-90...90).contains(partLatitude), - (-180...180).contains(partLongitude), + (-90 ... 90).contains(partLatitude), + (-180 ... 180).contains(partLongitude), partTolerance > 0.0 { coordinate = Coordinate3D(latitude: partLatitude, longitude: partLongitude) @@ -51,8 +51,8 @@ extension CLI { } var result: FeatureCollection? - if let coordinate = coordinate, - let tolerance = tolerance + if let coordinate, + let tolerance { if options.verbose { print("Searching around \(coordinate), tolerance: \(tolerance)m ...") @@ -66,7 +66,7 @@ extension CLI { result = search(term: searchTerm, in: tile) } - if let result = result, + if let result, let output = result.asJsonString(prettyPrinted: true) { print(output, terminator: "") diff --git a/Sources/MVTTools/Extensions/ArrayExtensions.swift b/Sources/MVTTools/Extensions/ArrayExtensions.swift index d8e40b2..4042902 100644 --- a/Sources/MVTTools/Extensions/ArrayExtensions.swift +++ b/Sources/MVTTools/Extensions/ArrayExtensions.swift @@ -4,7 +4,8 @@ extension Array { /// Adds a new element at the end of the array if it's not *nil*. mutating func append(ifNotNil element: Element?) { - guard let element = element else { return } + guard let element else { return } + append(element) } @@ -14,9 +15,9 @@ extension Array { func pairs() -> [(first: Element, second: Element)] { guard !isEmpty else { return [] } - return (0 ..< (self.count / 2)).compactMap { (index) in + return (0 ..< (count / 2)).compactMap { (index) in let i = index * 2 - return (first: self[i], second: self[i+1]) + return (first: self[i], second: self[i + 1]) } } @@ -26,7 +27,9 @@ extension Array { /// /// - parameter index: The index in the array. May be negative. In this case, -1 will be the last element, -2 the second-to-last, and so on. func get(at index: Int) -> Element? { - guard index >= -count && index < count else { return nil } + guard index >= -count, + index < count + else { return nil } if index >= 0 { return self[index] diff --git a/Sources/MVTTools/Extensions/DictionaryExtensions.swift b/Sources/MVTTools/Extensions/DictionaryExtensions.swift index 5c1c15d..d95091f 100644 --- a/Sources/MVTTools/Extensions/DictionaryExtensions.swift +++ b/Sources/MVTTools/Extensions/DictionaryExtensions.swift @@ -3,7 +3,7 @@ import Foundation extension Dictionary { func hasKey(_ key: Key) -> Bool { - return self[key] != nil + self[key] != nil } } diff --git a/Sources/MVTTools/Extensions/RingExtensions.swift b/Sources/MVTTools/Extensions/RingExtensions.swift index ae403f1..0656e97 100644 --- a/Sources/MVTTools/Extensions/RingExtensions.swift +++ b/Sources/MVTTools/Extensions/RingExtensions.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import GISTools @@ -10,13 +10,13 @@ extension Ring { /// Note: Vector tiles have a flipped y axis, so /// clockwise/counterClockwise are reverted var isUnprojectedClockwise: Bool { - return !isClockwise + !isClockwise } /// Note: Vector tiles have a flipped y axis, so /// clockwise/counterClockwise are reverted var isUnprojectedCounterClockwise: Bool { - return !isCounterClockwise + !isCounterClockwise } } diff --git a/Sources/MVTTools/VectorTile.swift b/Sources/MVTTools/VectorTile.swift index d5d3744..dbc8f4a 100644 --- a/Sources/MVTTools/VectorTile.swift +++ b/Sources/MVTTools/VectorTile.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -11,6 +11,7 @@ import Logging public struct VectorTile: Sendable { // MARK: - Properties + // MARK: Public /// A global logger instance for logging errors @@ -54,7 +55,7 @@ public struct VectorTile: Sendable { // MARK: Private/Internal - internal var indexSortOption: RTreeSortOption? + var indexSortOption: RTreeSortOption? struct LayerContainer { var features: [Feature] @@ -88,7 +89,7 @@ public struct VectorTile: Sendable { return nil } - let maximumTileCoordinate: Int = 1 << z + let maximumTileCoordinate = 1 << z if x >= maximumTileCoordinate || y >= maximumTileCoordinate { (logger ?? VectorTile.logger)?.warning("\(z)/\(x)/\(y): Tile coordinate outside bounds") return nil @@ -113,7 +114,7 @@ public struct VectorTile: Sendable { self.boundingBox = MapTile(x: x, y: y, z: z).boundingBox(projection: projection) } - if let sortOption = sortOption { + if let sortOption { createIndex(sortOption: sortOption) } } @@ -125,7 +126,13 @@ public struct VectorTile: Sendable { indexed sortOption: RTreeSortOption? = nil, logger: Logger? = nil) { - self.init(x: tile.x, y: tile.y, z: tile.z, projection: projection, indexed: sortOption, logger: logger) + self.init( + x: tile.x, + y: tile.y, + z: tile.z, + projection: projection, + indexed: sortOption, + logger: logger) } /// Create a vector tile from `data`, which must be in MVT format, at `z`/`x`/`y`. @@ -144,7 +151,7 @@ public struct VectorTile: Sendable { return nil } - let maximumTileCoordinate: Int = 1 << z + let maximumTileCoordinate = 1 << z if x >= maximumTileCoordinate || y >= maximumTileCoordinate { (logger ?? VectorTile.logger)?.warning("\(z)/\(x)/\(y): Tile coordinate outside bounds") return nil @@ -157,15 +164,22 @@ public struct VectorTile: Sendable { self.logger = logger // Note: A plain array might actually be faster for few entries -> check this - let layerWhitelistSet: Set? - if let layerWhitelist { - layerWhitelistSet = Set(layerWhitelist) + let layerWhitelistSet: Set? = if let layerWhitelist { + Set(layerWhitelist) } else { - layerWhitelistSet = nil + nil } - guard let parsedLayers = VectorTile.loadTileFrom(data: data, x: x, y: y, z: z, projection: projection, layerWhitelist: layerWhitelistSet, logger: logger) else { return nil } + guard let parsedLayers = VectorTile.loadTileFrom( + data: data, + x: x, + y: y, + z: z, + projection: projection, + layerWhitelist: layerWhitelistSet, + logger: logger) + else { return nil } self.layers = parsedLayers self.layerNames = Array(layers.keys) @@ -180,7 +194,7 @@ public struct VectorTile: Sendable { self.boundingBox = MapTile(x: x, y: y, z: z).boundingBox(projection: projection) } - if let sortOption = sortOption { + if let sortOption { createIndex(sortOption: sortOption) } } @@ -194,7 +208,15 @@ public struct VectorTile: Sendable { layerWhitelist: [String]? = nil, logger: Logger? = nil) { - self.init(data: data, x: tile.x, y: tile.y, z: tile.z, projection: projection, indexed: sortOption, layerWhitelist: layerWhitelist, logger: logger) + self.init( + data: data, + x: tile.x, + y: tile.y, + z: tile.z, + projection: projection, + indexed: sortOption, + layerWhitelist: layerWhitelist, + logger: logger) } /// Create a vector tile by reading it from `url`, which must be in MVT format, at `z`/`x`/`y`. @@ -213,7 +235,7 @@ public struct VectorTile: Sendable { return nil } - let maximumTileCoordinate: Int = 1 << z + let maximumTileCoordinate = 1 << z if x >= maximumTileCoordinate || y >= maximumTileCoordinate { (logger ?? VectorTile.logger)?.warning("\(z)/\(x)/\(y): Tile coordinate outside bounds") return nil @@ -226,12 +248,11 @@ public struct VectorTile: Sendable { self.logger = logger // Note: A plain array might actually be faster for few entries -> check this - let layerWhitelistSet: Set? - if let layerWhitelist { - layerWhitelistSet = Set(layerWhitelist) + let layerWhitelistSet: Set? = if let layerWhitelist { + Set(layerWhitelist) } else { - layerWhitelistSet = nil + nil } guard let data = try? Data(contentsOf: url) else { @@ -239,7 +260,15 @@ public struct VectorTile: Sendable { return nil } - guard let parsedLayers = VectorTile.loadTileFrom(data: data, x: x, y: y, z: z, projection: projection, layerWhitelist: layerWhitelistSet, logger: logger) else { return nil } + guard let parsedLayers = VectorTile.loadTileFrom( + data: data, + x: x, + y: y, + z: z, + projection: projection, + layerWhitelist: layerWhitelistSet, + logger: logger) + else { return nil } self.layers = parsedLayers self.layerNames = Array(layers.keys) @@ -254,7 +283,7 @@ public struct VectorTile: Sendable { self.boundingBox = MapTile(x: x, y: y, z: z).boundingBox(projection: projection) } - if let sortOption = sortOption { + if let sortOption { createIndex(sortOption: sortOption) } } @@ -268,7 +297,15 @@ public struct VectorTile: Sendable { layerWhitelist: [String]? = nil, logger: Logger? = nil) { - self.init(contentsOf: url, x: tile.x, y: tile.y, z: tile.z, projection: projection, indexed: sortOption, layerWhitelist: layerWhitelist, logger: logger) + self.init( + contentsOf: url, + x: tile.x, + y: tile.y, + z: tile.z, + projection: projection, + indexed: sortOption, + layerWhitelist: layerWhitelist, + logger: logger) } } @@ -279,7 +316,7 @@ extension VectorTile { /// Returns the tile's content as MVT data public func data(options: VectorTileExportOptions? = nil) -> Data? { - return VectorTile.tileDataFor( + VectorTile.tileDataFor( layers: layers, x: x, y: y, @@ -295,7 +332,7 @@ extension VectorTile { options: VectorTileExportOptions? = nil) -> Bool { - guard let data: Data = self.data(options: options) else { return false } + guard let data: Data = data(options: options) else { return false } do { try data.write(to: url) @@ -330,12 +367,16 @@ extension VectorTile { /// Returns an array of GeoJson Features public func features(for layerName: String) -> [Feature]? { - return layers[layerName]?.features + layers[layerName]?.features } /// Replace or add a layer with `features` @discardableResult - public mutating func setFeatures(_ features: [Feature], for layerName: String) -> Bool { + public mutating func setFeatures( + _ features: [Feature], + for layerName: String) + -> Bool + { let features: [Feature] = features.map { (feature) in var feature = feature.projected(to: projection) feature.updateBoundingBox(onlyIfNecessary: true) @@ -357,7 +398,7 @@ extension VectorTile { features: features, boundingBox: layerBoundingBox) - if let indexSortOption = indexSortOption { + if let indexSortOption { newLayerContainer.rTree = RTree(features, sortOption: indexSortOption) } @@ -369,7 +410,11 @@ extension VectorTile { /// Append `features` to a layer, or create a new layer if it doesn't already exist @discardableResult - public mutating func appendFeatures(_ features: [Feature], to layerName: String) -> Bool { + public mutating func appendFeatures( + _ features: [Feature], + to layerName: String) + -> Bool + { var allFeatures: [Feature] = [] if let layerContainer = layers[layerName] { @@ -398,7 +443,7 @@ extension VectorTile { boundingBox: layerBoundingBox) // TODO: Improve this, don't update the complete index - if let indexSortOption = indexSortOption { + if let indexSortOption { newLayerContainer.rTree = RTree(allFeatures, sortOption: indexSortOption) } @@ -410,7 +455,11 @@ extension VectorTile { /// Remove features from a layer. @discardableResult - public mutating func removeFeatures(fromLayer layerName: String, where shouldBeRemoved: (Feature) -> Bool) -> Bool { + public mutating func removeFeatures( + fromLayer layerName: String, + where shouldBeRemoved: (Feature) -> Bool) + -> Bool + { guard let layerContainer = layers[layerName] else { return false } var allFeatures = layerContainer.features @@ -427,7 +476,7 @@ extension VectorTile { boundingBox: layerBoundingBox) // TODO: Improve this, don't update the complete index - if let indexSortOption = indexSortOption { + if let indexSortOption { newLayerContainer.rTree = RTree(allFeatures, sortOption: indexSortOption) } diff --git a/Sources/MVTTools/VectorTileDecoder.swift b/Sources/MVTTools/VectorTileDecoder.swift index 24307cd..f6c6b1d 100644 --- a/Sources/MVTTools/VectorTileDecoder.swift +++ b/Sources/MVTTools/VectorTileDecoder.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -40,15 +40,15 @@ extension VectorTile { var layers: [String: LayerContainer] = [:] - var lastExtent: Int = 0 + var lastExtent = 0 var projectionFunction: ((_ x: Int, _ y: Int) -> Coordinate3D) = passThroughFromTile for layer in tile.layers { guard (layerWhitelist?.contains(layer.name) ?? true) else { continue } let name: String = layer.name - let extent: Int = Int(layer.extent) - let version: Int = Int(layer.version) + let extent = Int(layer.extent) + let version = Int(layer.version) if extent != lastExtent { lastExtent = extent @@ -100,8 +100,8 @@ extension VectorTile { // Maybe an encoded JSON object? if string.hasPrefix("[") || string.hasPrefix("{"), - let data = string.data(using: .utf8), - let object = try? JSONSerialization.jsonObject(with: data) + let data = string.data(using: .utf8), + let object = try? JSONSerialization.jsonObject(with: data) { return object } @@ -135,7 +135,11 @@ extension VectorTile { layerFeatures.reserveCapacity(layer.features.count) for feature in layer.features { - guard var layerFeature: Feature = convertToLayerFeature(geometryIntegers: feature.geometry, ofType: feature.type, projectionFunction: projectionFunction) else { continue } + guard var layerFeature: Feature = convertToLayerFeature( + geometryIntegers: feature.geometry, + ofType: feature.type, + projectionFunction: projectionFunction) + else { continue } var properties: [String: Any] = [:] for tags in feature.tags.pairs() { @@ -178,7 +182,7 @@ extension VectorTile { switch featureType { case .point: if multiCoordinates.count == 1, - let coordinate = multiCoordinates.first?.first + let coordinate = multiCoordinates.first?.first { feature = Feature(Point(coordinate), calculateBoundingBox: true) } @@ -245,16 +249,16 @@ extension VectorTile { projectionFunction: ((_ x: Int, _ y: Int) -> Coordinate3D)) -> [[Coordinate3D]] { - var x: Int = 0 - var y: Int = 0 + var x = 0 + var y = 0 var commandId: UInt32 = 0 - var commandCount: Int = 0 + var commandCount = 0 var coordinates: [Coordinate3D] = [] var result: [[Coordinate3D]] = [] - var index: Int = 0 + var index = 0 let geometryCount: Int = geometryIntegers.count while index < geometryCount { @@ -269,9 +273,7 @@ extension VectorTile { guard featureType != .point, commandCount == 1, coordinates.count > 1 - else { - break - } + else { break } coordinates.append(coordinates[0]) @@ -293,7 +295,7 @@ extension VectorTile { y += VectorTile.zigZagDecode(Int(dy)) if commandId == VectorTile.commandIdMoveTo, - !coordinates.isEmpty + !coordinates.isEmpty { result.append(coordinates) coordinates = [] @@ -312,7 +314,7 @@ extension VectorTile { } private static func zigZagDecode(_ n: Int) -> Int { - return (n >> 1) ^ (-(n & 1)) + (n >> 1) ^ (-(n & 1)) } // MARK: - Projections @@ -322,7 +324,7 @@ extension VectorTile { y: Int) -> Coordinate3D { - return Coordinate3D(x: Double(x), y: Double(y), projection: .noSRID) + Coordinate3D(x: Double(x), y: Double(y), projection: .noSRID) } static func projectToEpsg3857( @@ -332,7 +334,7 @@ extension VectorTile { extent: Int) -> ((Int, Int) -> Coordinate3D) { - let extent: Double = Double(extent) + let extent = Double(extent) let bounds = MapTile(x: x, y: y, z: z).boundingBox(projection: .epsg3857) let topLeft = Coordinate3D(x: bounds.southWest.x, y: bounds.northEast.y) @@ -354,7 +356,7 @@ extension VectorTile { extent: Int) -> ((Int, Int) -> Coordinate3D) { - let extent: Double = Double(extent) + let extent = Double(extent) let bounds = MapTile(x: x, y: y, z: z).boundingBox(projection: .epsg3857) let topLeft = Coordinate3D(x: bounds.southWest.x, y: bounds.northEast.y) diff --git a/Sources/MVTTools/VectorTileEncoder.swift b/Sources/MVTTools/VectorTileEncoder.swift index d9997c0..31188e6 100644 --- a/Sources/MVTTools/VectorTileEncoder.swift +++ b/Sources/MVTTools/VectorTileEncoder.swift @@ -1,10 +1,10 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools -import Gzip import struct GISTools.Polygon +import Gzip // MARK: Writing vector tiles @@ -21,7 +21,7 @@ extension VectorTile { { var tile = VectorTile_Tile() - let extent: UInt32 = UInt32(options.extent) + let extent = UInt32(options.extent) let projectionFunction: ((Coordinate3D) -> (x: Int, y: Int)) var clipBoundingBox: BoundingBox? @@ -36,7 +36,7 @@ extension VectorTile { clipBoundingBox = MapTile(x: x, y: y, z: z).boundingBox(projection: .epsg4326) } - var bufferSize: Int = 0 + var bufferSize = 0 switch options.bufferSize { case let .extent(extent): bufferSize = extent @@ -72,17 +72,16 @@ extension VectorTile { var vectorTileLayers: [VectorTile_Tile.Layer] = [] for (layerName, layerContainer) in layers { - let layerFeatures: [Feature] - if let clippedToBoundingBox = clipBoundingBox { + let layerFeatures: [Feature] = if let clippedToBoundingBox = clipBoundingBox { if simplifyDistance > 0.0 { - layerFeatures = layerContainer.features.compactMap({ $0.clipped(to: clippedToBoundingBox)?.simplified(tolerance: simplifyDistance) }) + layerContainer.features.compactMap({ $0.clipped(to: clippedToBoundingBox)?.simplified(tolerance: simplifyDistance) }) } else { - layerFeatures = layerContainer.features.compactMap({ $0.clipped(to: clippedToBoundingBox ) }) + layerContainer.features.compactMap({ $0.clipped(to: clippedToBoundingBox) }) } } else { - layerFeatures = layerContainer.features + layerContainer.features } var layer: VectorTile_Tile.Layer = encodeVersion2( @@ -99,7 +98,7 @@ extension VectorTile { let serializedData = try? tile.serializedData() if options.compression != .no, - let serializedData = serializedData + let serializedData { var value = 6 // default if case let .level(compressionLevel) = options.compression { @@ -132,7 +131,7 @@ extension VectorTile { var valuePositions: [AnyHashable: UInt32] = [:] for feature in features { - guard var vectorTileFeature = self.vectorTileFeature(from: feature, projectionFunction: projectionFunction) else { continue } + guard var vectorTileFeature = vectorTileFeature(from: feature, projectionFunction: projectionFunction) else { continue } var tags: [UInt32] = [] @@ -148,7 +147,7 @@ extension VectorTile { // Encode arrays and dictionaries as JSON encoded strings var hashablePropertyValue: AnyHashable - if let array = propertyValue as? Array { + if let array = propertyValue as? [Sendable] { guard let data: Data = (try? JSONSerialization.data(withJSONObject: array)) else { continue } hashablePropertyValue = String(data: data, encoding: .utf8) ?? "" } @@ -266,8 +265,8 @@ extension VectorTile { return nil } - if let geometryIntegers = geometryIntegers, - let geometryType = geometryType + if let geometryIntegers, + let geometryType { var vectorTileFeature = VectorTile_Tile.Feature() vectorTileFeature.type = geometryType @@ -295,8 +294,8 @@ extension VectorTile { { var geometryIntegers: [UInt32] = [] - var dx: Int = 0 - var dy: Int = 0 + var dx = 0 + var dy = 0 var commandId: UInt32 = 0 var commandCount: UInt32 = 0 @@ -363,7 +362,7 @@ extension VectorTile { commandInteger = (commandId & 0x7) | (commandCount << 3) geometryIntegers.append(commandInteger) - for coordinate in coordinates[1 ..< coordinates.count - 1] { + for coordinate in coordinates[1 ..< coordinates.count - 1] { let (x, y) = projectionFunction(coordinate) geometryIntegers.append(UInt32(VectorTile.zigZagEncode(Int(x) - dx))) geometryIntegers.append(UInt32(VectorTile.zigZagEncode(Int(y) - dy))) @@ -384,14 +383,14 @@ extension VectorTile { } private static func zigZagEncode(_ n: Int) -> Int { - return (n >> 31) ^ (n << 1) + (n >> 31) ^ (n << 1) } // MARK: - Projections static func passThroughToTile() -> ((Coordinate3D) -> (x: Int, y: Int)) { - return { (coordinate) -> (Int, Int) in - return (x: Int(coordinate.x), y: Int(coordinate.y)) + { (coordinate) -> (Int, Int) in + (x: Int(coordinate.x), y: Int(coordinate.y)) } } @@ -402,7 +401,7 @@ extension VectorTile { extent: Int) -> ((Coordinate3D) -> (x: Int, y: Int)) { - let extent: Double = Double(extent) + let extent = Double(extent) let bounds = MapTile(x: x, y: y, z: z).boundingBox(projection: .epsg3857) let topLeft = Coordinate3D(x: bounds.southWest.x, y: bounds.northEast.y) @@ -410,8 +409,8 @@ extension VectorTile { let ySpan: Double = abs(bounds.northEast.y - bounds.southWest.y) return { (coordinate) -> (Int, Int) in - let projectedX: Int = Int(((coordinate.x - topLeft.x) / xSpan) * extent) - let projectedY: Int = Int(((topLeft.y - coordinate.y) / ySpan) * extent) + let projectedX = Int(((coordinate.x - topLeft.x) / xSpan) * extent) + let projectedY = Int(((topLeft.y - coordinate.y) / ySpan) * extent) return (projectedX, projectedY) } } @@ -423,7 +422,7 @@ extension VectorTile { extent: Int) -> ((Coordinate3D) -> (x: Int, y: Int)) { - let extent: Double = Double(extent) + let extent = Double(extent) let bounds = MapTile(x: x, y: y, z: z).boundingBox(projection: .epsg3857) let topLeft = Coordinate3D(x: bounds.southWest.x, y: bounds.northEast.y) @@ -432,8 +431,8 @@ extension VectorTile { return { (coordinate) -> (Int, Int) in let projectedCoordinate = coordinate.projected(to: .epsg3857) - let projectedX: Int = Int(((projectedCoordinate.x - topLeft.x) / xSpan) * extent) - let projectedY: Int = Int(((topLeft.y - projectedCoordinate.y) / ySpan) * extent) + let projectedX = Int(((projectedCoordinate.x - topLeft.x) / xSpan) * extent) + let projectedY = Int(((topLeft.y - projectedCoordinate.y) / ySpan) * extent) return (projectedX, projectedY) } } diff --git a/Sources/MVTTools/VectorTileExportOptions.swift b/Sources/MVTTools/VectorTileExportOptions.swift index a8cc58f..6db263a 100644 --- a/Sources/MVTTools/VectorTileExportOptions.swift +++ b/Sources/MVTTools/VectorTileExportOptions.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -36,10 +36,10 @@ public struct VectorTileExportOptions { } /// The grid width and height of one tile. Always 4096. - public let extent: Int = 4096 + public let extent = 4096 /// The tile size in pixels. Always 256. - public let tileSize: Int = 256 + public let tileSize = 256 /// The buffer around the tile, either in pixels (see ``tileSize``) or in the same dimension as ``extent`` (default: **0**). public var bufferSize: BufferSizeOptions = .extent(0) diff --git a/Sources/MVTTools/VectorTileGeoJson.swift b/Sources/MVTTools/VectorTileGeoJson.swift index b504562..529eb1c 100644 --- a/Sources/MVTTools/VectorTileGeoJson.swift +++ b/Sources/MVTTools/VectorTileGeoJson.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -48,7 +48,7 @@ extension VectorTile { prettyPrinted: Bool = false) -> Bool { - guard let data: Data = self.toGeoJson( + guard let data: Data = toGeoJson( layerNames: layerNames, additionalFeatureProperties: additionalFeatureProperties, prettyPrinted: prettyPrinted) diff --git a/Sources/MVTTools/VectorTileInfo.swift b/Sources/MVTTools/VectorTileInfo.swift index 8f020f2..25ad7ef 100644 --- a/Sources/MVTTools/VectorTileInfo.swift +++ b/Sources/MVTTools/VectorTileInfo.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -66,7 +66,7 @@ extension VectorTile { return [ "layers": layers, - "errors": false + "errors": false, ] } diff --git a/Sources/MVTTools/VectorTileMerge.swift b/Sources/MVTTools/VectorTileMerge.swift index 0ebd66f..11df7e2 100644 --- a/Sources/MVTTools/VectorTileMerge.swift +++ b/Sources/MVTTools/VectorTileMerge.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools diff --git a/Sources/MVTTools/VectorTileQuery.swift b/Sources/MVTTools/VectorTileQuery.swift index 786b39a..135164d 100644 --- a/Sources/MVTTools/VectorTileQuery.swift +++ b/Sources/MVTTools/VectorTileQuery.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -44,12 +44,11 @@ extension VectorTile { featureFilter: ((Feature) -> Bool)? = nil) -> [QueryResult] { - let queryLayerNames: [String] - if let layerName { - queryLayerNames = [layerName] + let queryLayerNames: [String] = if let layerName { + [layerName] } else { - queryLayerNames = layerNames + layerNames } var result: [QueryResult] = [] @@ -108,12 +107,11 @@ extension VectorTile { featureFilter: ((Feature) -> Bool)? = nil) -> [QueryResult] { - let queryLayerNames: [String] - if let layerName { - queryLayerNames = [layerName] + let queryLayerNames: [String] = if let layerName { + [layerName] } else { - queryLayerNames = layerNames + layerNames } var result: [QueryResult] = [] @@ -124,14 +122,12 @@ extension VectorTile { boundingBox.intersects(queryBoundingBox) else { continue } - let resultFeatures: [Feature] - - if let rTree = layerFeatureContainer.rTree { + let resultFeatures: [Feature] = if let rTree = layerFeatureContainer.rTree { // The search will only return features that intersect with the bounding box - resultFeatures = rTree.search(inBoundingBox: queryBoundingBox) + rTree.search(inBoundingBox: queryBoundingBox) } else { - resultFeatures = layerFeatureContainer.features.filter({ feature in + layerFeatureContainer.features.filter({ feature in // Check the feature itself guard feature.intersects(queryBoundingBox) else { return false } @@ -170,12 +166,11 @@ extension VectorTile { projection: projection) } - let queryLayerNames: [String] - if let layerName { - queryLayerNames = [layerName] + let queryLayerNames: [String] = if let layerName { + [layerName] } else { - queryLayerNames = layerNames + layerNames } var results: [QueryManyResult] = [] @@ -190,14 +185,12 @@ extension VectorTile { boundingBox.intersects(queryBoundingBox) else { break } - let resultFeatures: [Feature] - - if let rTree = layerFeatureContainer.rTree { + let resultFeatures: [Feature] = if let rTree = layerFeatureContainer.rTree { // The search will only return features that intersect with the bounding box - resultFeatures = rTree.search(inBoundingBox: queryBoundingBox) + rTree.search(inBoundingBox: queryBoundingBox) } else { - resultFeatures = layerFeatureContainer.features.filter({ feature in + layerFeatureContainer.features.filter({ feature in // Check the feature itself guard feature.intersects(queryBoundingBox) else { return false } @@ -270,7 +263,7 @@ extension VectorTile { projection: projection), ], padding: tolerance)! - .clamped() + .clamped() } } diff --git a/Tests/MVTToolsTests/ArrayExtensionsTests.swift b/Tests/MVTToolsTests/ArrayExtensionsTests.swift index 1e95fab..e3d5b3c 100644 --- a/Tests/MVTToolsTests/ArrayExtensionsTests.swift +++ b/Tests/MVTToolsTests/ArrayExtensionsTests.swift @@ -29,7 +29,7 @@ final class ArrayExtensionsTests: XCTestCase { func testSmallPairs() { let empty: [Int] = [] - let small: [Int] = [1] + let small = [1] let emptyPairs = empty.pairs() let smallPairs = small.pairs() diff --git a/Tests/MVTToolsTests/DecoderTests.swift b/Tests/MVTToolsTests/DecoderTests.swift index 42939b4..09e8fba 100644 --- a/Tests/MVTToolsTests/DecoderTests.swift +++ b/Tests/MVTToolsTests/DecoderTests.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import GISTools import struct GISTools.Polygon @@ -22,7 +22,7 @@ final class DecoderTests: XCTestCase { let coordinates2 = VectorTile.multiCoordinatesFrom(geometryIntegers: geometry2, ofType: .point, projectionFunction: VectorTile.passThroughFromTile) let result2 = [ [Coordinate3D(x: 5.0, y: 7.0, projection: .noSRID)], - [Coordinate3D(x: 3.0, y: 2.0, projection: .noSRID)] + [Coordinate3D(x: 3.0, y: 2.0, projection: .noSRID)], ] XCTAssertNotNil(coordinates2, "Failed to parse a MULTIPOINT") XCTAssertEqual(coordinates2, result2) @@ -109,7 +109,7 @@ final class DecoderTests: XCTestCase { XCTAssertNotNil(point1, "Failed to parse a POINT") XCTAssertNotNil(boundingBox1, "FEATURE(POINT) without bounding box") - let result1: Point = Point(Coordinate3D(x: 25.0, y: 17.0, projection: .noSRID)) + let result1 = Point(Coordinate3D(x: 25.0, y: 17.0, projection: .noSRID)) XCTAssertEqual(point1, result1) XCTAssertEqual(boundingBox1, result1.calculateBoundingBox()) @@ -126,7 +126,7 @@ final class DecoderTests: XCTestCase { XCTAssertNotNil(multiPoint2, "Failed to parse a MULTIPOINT") XCTAssertNotNil(boundingBox2, "FEATURE(MULTIPOINT) without bounding box") - let result2: MultiPoint = MultiPoint([ + let result2 = MultiPoint([ Coordinate3D(x: 5.0, y: 7.0, projection: .noSRID), Coordinate3D(x: 3.0, y: 2.0, projection: .noSRID), ])! @@ -146,7 +146,7 @@ final class DecoderTests: XCTestCase { XCTAssertNotNil(lineString3, "Failed to parse a LINESTRING") XCTAssertNotNil(boundingBox3, "FEATURE(LINESTRING) without bounding box") - let result3: LineString = LineString([ + let result3 = LineString([ Coordinate3D(x: 2.0, y: 2.0, projection: .noSRID), Coordinate3D(x: 2.0, y: 10.0, projection: .noSRID), Coordinate3D(x: 10.0, y: 10.0, projection: .noSRID), @@ -167,7 +167,7 @@ final class DecoderTests: XCTestCase { XCTAssertNotNil(multiLineString4, "Failed to parse a MULTILINESTRING") XCTAssertNotNil(boundingBox4, "FEATURE(MULTILINESTRING) without bounding box") - let result4: MultiLineString = MultiLineString([[ + let result4 = MultiLineString([[ Coordinate3D(x: 2.0, y: 2.0, projection: .noSRID), Coordinate3D(x: 2.0, y: 10.0, projection: .noSRID), Coordinate3D(x: 10.0, y: 10.0, projection: .noSRID), @@ -214,7 +214,7 @@ final class DecoderTests: XCTestCase { XCTAssertNotNil(multiPolygon6, "Failed to parse a MULTIPOLYGON") XCTAssertNotNil(boundingBox6, "FEATURE(MULTIPOLYGON) without bounding box") - let result6: MultiPolygon = MultiPolygon([[[ + let result6 = MultiPolygon([[[ Coordinate3D(x: 0.0, y: 0.0, projection: .noSRID), Coordinate3D(x: 10.0, y: 0.0, projection: .noSRID), Coordinate3D(x: 10.0, y: 10.0, projection: .noSRID), diff --git a/Tests/MVTToolsTests/EncoderTests.swift b/Tests/MVTToolsTests/EncoderTests.swift index e8e1c19..7e62db2 100644 --- a/Tests/MVTToolsTests/EncoderTests.swift +++ b/Tests/MVTToolsTests/EncoderTests.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import GISTools import struct GISTools.Polygon @@ -19,7 +19,7 @@ final class EncoderTests: XCTestCase { // MultiPoint let multiPoint = [ [Coordinate3D(latitude: 7.0, longitude: 5.0)], - [Coordinate3D(latitude: 2.0, longitude: 3.0)] + [Coordinate3D(latitude: 2.0, longitude: 3.0)], ] let multiPointGeometryIntegers = VectorTile.geometryIntegers(fromMultiCoordinates: multiPoint, ofType: .point, projectionFunction: VectorTile.passThroughToTile()) let multiPointResult: [UInt32] = [17, 10, 14, 3, 9] @@ -30,7 +30,7 @@ final class EncoderTests: XCTestCase { Coordinate3D(latitude: 2.0, longitude: 2.0), Coordinate3D(latitude: 10.0, longitude: 2.0), Coordinate3D(latitude: 10.0, longitude: 10.0), - ]] + ]] let lineStringGeometryIntegers = VectorTile.geometryIntegers(fromMultiCoordinates: lineString, ofType: .linestring, projectionFunction: VectorTile.passThroughToTile()) let lineStringResult: [UInt32] = [9, 4, 4, 18, 0, 16, 16, 0] XCTAssertEqual(lineStringGeometryIntegers, lineStringResult) @@ -39,11 +39,11 @@ final class EncoderTests: XCTestCase { let multiLineString = [[ Coordinate3D(latitude: 2.0, longitude: 2.0), Coordinate3D(latitude: 10.0, longitude: 2.0), - Coordinate3D(latitude: 10.0, longitude: 10.0) - ], [ - Coordinate3D(latitude: 1.0, longitude: 1.0), - Coordinate3D(latitude: 5.0, longitude: 3.0), - ]] + Coordinate3D(latitude: 10.0, longitude: 10.0), + ], [ + Coordinate3D(latitude: 1.0, longitude: 1.0), + Coordinate3D(latitude: 5.0, longitude: 3.0), + ]] let multiLineStringGeometryIntegers = VectorTile.geometryIntegers(fromMultiCoordinates: multiLineString, ofType: .linestring, projectionFunction: VectorTile.passThroughToTile()) let multiLineStringResult: [UInt32] = [9, 4, 4, 18, 0, 16, 16, 0, 9, 17, 17, 10, 4, 8] XCTAssertEqual(multiLineStringGeometryIntegers, multiLineStringResult) @@ -54,7 +54,7 @@ final class EncoderTests: XCTestCase { Coordinate3D(latitude: 12.0, longitude: 8.0), Coordinate3D(latitude: 34.0, longitude: 20.0), Coordinate3D(latitude: 6.0, longitude: 3.0), - ]] + ]] let polygonGeometryIntegers = VectorTile.geometryIntegers(fromMultiCoordinates: polygon, ofType: .polygon, projectionFunction: VectorTile.passThroughToTile()) let polygonResult: [UInt32] = [9, 6, 12, 18, 10, 12, 24, 44, 15] XCTAssertEqual(polygonGeometryIntegers, polygonResult) @@ -66,19 +66,19 @@ final class EncoderTests: XCTestCase { Coordinate3D(latitude: 10.0, longitude: 10.0), Coordinate3D(latitude: 10.0, longitude: 0.0), Coordinate3D(latitude: 0.0, longitude: 0.0), - ], [ - Coordinate3D(latitude: 11.0, longitude: 11.0), - Coordinate3D(latitude: 11.0, longitude: 20.0), - Coordinate3D(latitude: 20.0, longitude: 20.0), - Coordinate3D(latitude: 20.0, longitude: 11.0), - Coordinate3D(latitude: 11.0, longitude: 11.0), - ], [ - Coordinate3D(latitude: 13.0, longitude: 13.0), - Coordinate3D(latitude: 17.0, longitude: 13.0), - Coordinate3D(latitude: 17.0, longitude: 17.0), - Coordinate3D(latitude: 13.0, longitude: 17.0), - Coordinate3D(latitude: 13.0, longitude: 13.0), - ]] + ], [ + Coordinate3D(latitude: 11.0, longitude: 11.0), + Coordinate3D(latitude: 11.0, longitude: 20.0), + Coordinate3D(latitude: 20.0, longitude: 20.0), + Coordinate3D(latitude: 20.0, longitude: 11.0), + Coordinate3D(latitude: 11.0, longitude: 11.0), + ], [ + Coordinate3D(latitude: 13.0, longitude: 13.0), + Coordinate3D(latitude: 17.0, longitude: 13.0), + Coordinate3D(latitude: 17.0, longitude: 17.0), + Coordinate3D(latitude: 13.0, longitude: 17.0), + Coordinate3D(latitude: 13.0, longitude: 13.0), + ]] let multiPolygonGeometryIntegers = VectorTile.geometryIntegers(fromMultiCoordinates: multiPolygon, ofType: .polygon, projectionFunction: VectorTile.passThroughToTile()) let multiPolygonResult: [UInt32] = [9, 0, 0, 26, 20, 0, 0, 20, 19, 0, 15, 9, 22, 2, 26, 18, 0, 0, 18, 17, 0, 15, 9, 4, 13, 26, 0, 8, 8, 0, 0, 7, 15] XCTAssertEqual(multiPolygonGeometryIntegers, multiPolygonResult) @@ -98,7 +98,7 @@ final class EncoderTests: XCTestCase { // MultiPoint let multiPoint = Feature(MultiPoint([ Coordinate3D(latitude: 7.0, longitude: 5.0), - Coordinate3D(latitude: 2.0, longitude: 3.0) + Coordinate3D(latitude: 2.0, longitude: 3.0), ])!, id: .int(501)) let multiPointFeature = VectorTile.vectorTileFeature(from: multiPoint, projectionFunction: VectorTile.passThroughToTile()) XCTAssertNotNil(multiPointFeature, "Failed to encode a MULTIPOINT") @@ -126,11 +126,11 @@ final class EncoderTests: XCTestCase { let multiLineString = Feature(MultiLineString([[ Coordinate3D(latitude: 2.0, longitude: 2.0), Coordinate3D(latitude: 10.0, longitude: 2.0), - Coordinate3D(latitude: 10.0, longitude: 10.0) - ], [ - Coordinate3D(latitude: 1.0, longitude: 1.0), - Coordinate3D(latitude: 5.0, longitude: 3.0), - ]])!, id: .int(503)) + Coordinate3D(latitude: 10.0, longitude: 10.0), + ], [ + Coordinate3D(latitude: 1.0, longitude: 1.0), + Coordinate3D(latitude: 5.0, longitude: 3.0), + ]])!, id: .int(503)) let multiLineStringFeature = VectorTile.vectorTileFeature(from: multiLineString, projectionFunction: VectorTile.passThroughToTile()) XCTAssertNotNil(multiLineStringFeature, "Failed to encode a MULTILINESTRING") @@ -145,7 +145,7 @@ final class EncoderTests: XCTestCase { Coordinate3D(latitude: 12.0, longitude: 8.0), Coordinate3D(latitude: 34.0, longitude: 20.0), Coordinate3D(latitude: 6.0, longitude: 3.0), - ]])!, id: .int(504)) + ]])!, id: .int(504)) let polygonFeature = VectorTile.vectorTileFeature(from: polygon, projectionFunction: VectorTile.passThroughToTile()) XCTAssertNotNil(polygonFeature, "Failed to encode a POLYGON") @@ -161,19 +161,19 @@ final class EncoderTests: XCTestCase { Coordinate3D(latitude: 10.0, longitude: 10.0), Coordinate3D(latitude: 10.0, longitude: 0.0), Coordinate3D(latitude: 0.0, longitude: 0.0), - ]], [[ - Coordinate3D(latitude: 11.0, longitude: 11.0), - Coordinate3D(latitude: 11.0, longitude: 20.0), - Coordinate3D(latitude: 20.0, longitude: 20.0), - Coordinate3D(latitude: 20.0, longitude: 11.0), - Coordinate3D(latitude: 11.0, longitude: 11.0), - ], [ - Coordinate3D(latitude: 13.0, longitude: 13.0), - Coordinate3D(latitude: 17.0, longitude: 13.0), - Coordinate3D(latitude: 17.0, longitude: 17.0), - Coordinate3D(latitude: 13.0, longitude: 17.0), - Coordinate3D(latitude: 13.0, longitude: 13.0), - ]]])!, id: .int(505)) + ]], [[ + Coordinate3D(latitude: 11.0, longitude: 11.0), + Coordinate3D(latitude: 11.0, longitude: 20.0), + Coordinate3D(latitude: 20.0, longitude: 20.0), + Coordinate3D(latitude: 20.0, longitude: 11.0), + Coordinate3D(latitude: 11.0, longitude: 11.0), + ], [ + Coordinate3D(latitude: 13.0, longitude: 13.0), + Coordinate3D(latitude: 17.0, longitude: 13.0), + Coordinate3D(latitude: 17.0, longitude: 17.0), + Coordinate3D(latitude: 13.0, longitude: 17.0), + Coordinate3D(latitude: 13.0, longitude: 13.0), + ]]])!, id: .int(505)) let multiPolygonFeature = VectorTile.vectorTileFeature(from: multiPolygon, projectionFunction: VectorTile.passThroughToTile()) XCTAssertNotNil(polygonFeature, "Failed to encode a MULTIPOLYGON") @@ -204,7 +204,7 @@ final class EncoderTests: XCTestCase { } func testCompressOption() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) @@ -222,7 +222,7 @@ final class EncoderTests: XCTestCase { } func testBufferSizeOption() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) @@ -242,7 +242,7 @@ final class EncoderTests: XCTestCase { } func testSimplifyOption() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) @@ -261,9 +261,9 @@ final class EncoderTests: XCTestCase { } -fileprivate extension Data { +extension Data { - func utf8EncodedString() -> String? { + private func utf8EncodedString() -> String? { String(data: self, encoding: .utf8) } diff --git a/Tests/MVTToolsTests/ProjectionTests.swift b/Tests/MVTToolsTests/ProjectionTests.swift index e7fc7ae..86f0882 100644 --- a/Tests/MVTToolsTests/ProjectionTests.swift +++ b/Tests/MVTToolsTests/ProjectionTests.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import Foundation import GISTools @@ -11,28 +11,28 @@ final class ProjectionTests: XCTestCase { func testProjectToEpsg3857() { let projection1 = Coordinate3D(latitude: 20.5, longitude: 10.5).projected(to: .epsg3857) - XCTAssertEqual(projection1.latitude, 2332357.812619, accuracy: 0.00001) - XCTAssertEqual(projection1.longitude, 1168854.653329, accuracy: 0.00001) + XCTAssertEqual(projection1.latitude, 2_332_357.812619, accuracy: 0.00001) + XCTAssertEqual(projection1.longitude, 1_168_854.653329, accuracy: 0.00001) let projection2 = Coordinate3D(latitude: 45.0, longitude: -180.0).projected(to: .epsg3857) - XCTAssertEqual(projection2.latitude, 5621521.486192, accuracy: 0.00001) - XCTAssertEqual(projection2.longitude, -20037508.342789, accuracy: 0.00001) + XCTAssertEqual(projection2.latitude, 5_621_521.486192, accuracy: 0.00001) + XCTAssertEqual(projection2.longitude, -20_037_508.342789, accuracy: 0.00001) let projection3 = Coordinate3D(latitude: -45.0, longitude: 45.0).projected(to: .epsg3857) - XCTAssertEqual(projection3.latitude, -5621521.486192, accuracy: 0.00001) - XCTAssertEqual(projection3.longitude, 5009377.085697, accuracy: 0.00001) + XCTAssertEqual(projection3.latitude, -5_621_521.486192, accuracy: 0.00001) + XCTAssertEqual(projection3.longitude, 5_009_377.085697, accuracy: 0.00001) } func testProjectToEpsg4326() { - let projection1 = Coordinate3D(x: 1168854.653329, y: 2332357.812619).projected(to: .epsg4326) + let projection1 = Coordinate3D(x: 1_168_854.653329, y: 2_332_357.812619).projected(to: .epsg4326) XCTAssertEqual(projection1.latitude, 20.5, accuracy: 0.00001) XCTAssertEqual(projection1.longitude, 10.5, accuracy: 0.00001) - let projection2 = Coordinate3D(x: -20037508.342789, y: 5621521.486192).projected(to: .epsg4326) + let projection2 = Coordinate3D(x: -20_037_508.342789, y: 5_621_521.486192).projected(to: .epsg4326) XCTAssertEqual(projection2.latitude, 45.0, accuracy: 0.00001) XCTAssertEqual(projection2.longitude, -180.0, accuracy: 0.00001) - let projection3 = Coordinate3D(x: 5009377.09, y: -5621521.49).projected(to: .epsg4326) + let projection3 = Coordinate3D(x: 5_009_377.09, y: -5_621_521.49).projected(to: .epsg4326) XCTAssertEqual(projection3.latitude, -45.0, accuracy: 0.00001) XCTAssertEqual(projection3.longitude, 45.0, accuracy: 0.00001) } diff --git a/Tests/MVTToolsTests/QueryTests.swift b/Tests/MVTToolsTests/QueryTests.swift index 25a6cc6..6dce526 100644 --- a/Tests/MVTToolsTests/QueryTests.swift +++ b/Tests/MVTToolsTests/QueryTests.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import GISTools import XCTest @@ -16,7 +16,7 @@ final class QueryTests: XCTestCase { } func testQuery() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) @@ -35,7 +35,7 @@ final class QueryTests: XCTestCase { } func testQueryWithIndex() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) diff --git a/Tests/MVTToolsTests/TestData.swift b/Tests/MVTToolsTests/TestData.swift index 22e5327..5f7fce6 100644 --- a/Tests/MVTToolsTests/TestData.swift +++ b/Tests/MVTToolsTests/TestData.swift @@ -1,5 +1,5 @@ -import XCTest import Foundation +import XCTest class TestData { @@ -10,7 +10,7 @@ class TestData { .appendingPathComponent(name) do { - if !(try path.checkResourceIsReachable()) { + if try !(path.checkResourceIsReachable()) { XCTAssert(false, "Fixture \(name) not found.") return "" } @@ -29,7 +29,7 @@ class TestData { .appendingPathComponent(name) do { - if !(try path.checkResourceIsReachable()) { + if try !(path.checkResourceIsReachable()) { XCTAssert(false, "Fixture \(name) not found.") return Data() } diff --git a/Tests/MVTToolsTests/VectorTileTests.swift b/Tests/MVTToolsTests/VectorTileTests.swift index e4a589b..f4acbd0 100644 --- a/Tests/MVTToolsTests/VectorTileTests.swift +++ b/Tests/MVTToolsTests/VectorTileTests.swift @@ -1,5 +1,5 @@ #if !os(Linux) -import CoreLocation + import CoreLocation #endif import GISTools import struct GISTools.Polygon @@ -10,7 +10,7 @@ import XCTest final class VectorTileTests: XCTestCase { func testLoadMvt() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let tileLayerNames: [String] = ["landuse", "waterway", "water", "aeroway", "barrier_line", "building", "landuse_overlay", "tunnel", "road", "bridge", "admin", "country_label_line", "country_label", "marine_label", "state_label", "place_label", "water_label", "area_label", "rail_station_label", "airport_label", "road_label", "waterway_label", "building_label"].sorted() let mvt = TestData.dataFromFile(name: tileName) @@ -50,8 +50,8 @@ final class VectorTileTests: XCTestCase { "test3": [1, 2, 3], "test4": [ "sub1": 1, - "sub2": 2 - ] + "sub2": 2, + ], ] tile.setFeatures([feature], for: "test") @@ -62,7 +62,7 @@ final class VectorTileTests: XCTestCase { } func testTileInfo() { - let tileName: String = "14_8716_8015.vector.mvt" + let tileName = "14_8716_8015.vector.mvt" let mvt = TestData.dataFromFile(name: tileName) XCTAssertFalse(mvt.isEmpty) @@ -113,7 +113,7 @@ final class VectorTileTests: XCTestCase { func testEncodeDecodeBigInt() throws { let feature = try XCTUnwrap(Feature(jsonData: TestData.dataFromFile(name: "bigint_id.geojson"))) - XCTAssertEqual(feature.id, .uint(18446744073638380036)) + XCTAssertEqual(feature.id, .uint(18_446_744_073_638_380_036)) var tile = try XCTUnwrap(VectorTile(x: 10, y: 25, z: 6)) tile.setFeatures([feature], for: "test")