Skip to content

Commit

Permalink
Output options cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
trasch committed Aug 27, 2024
1 parent 27158a4 commit 2155e1f
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 74 deletions.
27 changes: 22 additions & 5 deletions Sources/MVTCLI/Dump.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ extension CLI {
@Flag(
name: [.customLong("Di", withSingleDash: true), .long],
help: "Don't parse the layer name (option 'property-name') from Feature properties in the input GeoJSONs. Might speed up GeoJSON parsing considerably.")
var disableInputLayerProperty: Bool = false
var disableInputLayerProperty = false

@Flag(
name: [.customLong("Do", withSingleDash: true), .long],
help: "Don't add the layer name (option 'property-name') as a Feature property in the output GeoJSONs.")
var disableOutputLayerProperty: Bool = false
var disableOutputLayerProperty = false

@Option(
name: [.customLong("oSm", withSingleDash: true), .long],
help: "Simplify output features using meters.")
var simplifyMeters: Int?

@OptionGroup
var xyzOptions: XYZOptions
Expand Down Expand Up @@ -77,10 +82,15 @@ extension CLI {
}
}

var exportOptions = VectorTile.ExportOptions()
if let simplifyMeters, simplifyMeters > 0 {
exportOptions.simplifyFeatures = .meters(Double(simplifyMeters))
}

if options.verbose {
print("Dumping \(tile.origin) tile '\(url.lastPathComponent)' [\(tile.x),\(tile.y)]@\(tile.z)")
print("Property name: \(propertyName)")

print("Layer property name: \(propertyName)")
if disableInputLayerProperty {
print(" - disable input layer property")
}
Expand All @@ -96,15 +106,22 @@ extension CLI {

if tile.origin == .mvt
|| !disableInputLayerProperty,
let layerAllowlist
let layerAllowlist
{
print("Layers: '\(layerAllowlist.joined(separator: ","))'")
}

print("Output options:")
print(" - Pretty print: true")
print(" - Simplification: \(exportOptions.simplifyFeatures)")

print("GeoJSON:")
}

guard let data = tile.toGeoJson(
prettyPrinted: true,
layerProperty: disableOutputLayerProperty ? nil : propertyName)
layerProperty: disableOutputLayerProperty ? nil : propertyName,
options: exportOptions)
else { throw CLIError("Failed to extract the tile data as GeoJSON") }

print(String(data: data, encoding: .utf8) ?? "", terminator: "")
Expand Down
56 changes: 40 additions & 16 deletions Sources/MVTCLI/Export.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ extension CLI {
completion: .file(extensions: ["geojson", "json"]))
var outputFile: String

@Option(
name: [.customLong("oC", withSingleDash: true), .long],
help: "Output file compression level, between 0=none to 9=best. (default: none)")
var compressionLevel: Int?

@Option(
name: [.customLong("oSm", withSingleDash: true), .long],
help: "Simplify output features using meters.")
var simplifyMeters: Int?

@Flag(
name: .shortAndLong,
help: "Overwrite existing files.")
Expand All @@ -31,9 +41,9 @@ extension CLI {
var propertyName: String = VectorTile.defaultLayerPropertyName

@Flag(
name: [.customLong("Do", withSingleDash: true), .long],
name: [.customLong("Do", withSingleDash: true), .long],
help: "Don't add the layer name (option 'property-name') as a Feature property in the output GeoJSONs.")
var disableOutputLayerProperty: Bool = false
var disableOutputLayerProperty = false

@Flag(
name: .shortAndLong,
Expand All @@ -57,19 +67,6 @@ extension CLI {
let layerAllowlist = layer.nonempty
let outputUrl = URL(fileURLWithPath: outputFile)

if options.verbose {
print("Dumping tile '\(url.lastPathComponent)' [\(x),\(y)]@\(z) to '\(outputUrl.lastPathComponent)'")
print("Property name: \(propertyName)")

if disableOutputLayerProperty {
print(" - disable output layer property")
}

if let layerAllowlist {
print("Layers: '\(layerAllowlist.joined(separator: ","))'")
}
}

if (try? outputUrl.checkResourceIsReachable()) ?? false {
if forceOverwrite {
if options.verbose {
Expand All @@ -90,9 +87,36 @@ extension CLI {
logger: options.verbose ? CLI.logger : nil)
else { throw CLIError("Failed to parse the resource at '\(path)'") }

var exportOptions = VectorTile.ExportOptions()
if let simplifyMeters, simplifyMeters > 0 {
exportOptions.simplifyFeatures = .meters(Double(simplifyMeters))
}
if let compressionLevel, compressionLevel > 0 {
exportOptions.compression = .level(max(0, min(9, compressionLevel)))
}

if options.verbose {
print("Dumping tile '\(url.lastPathComponent)' [\(x),\(y)]@\(z) to '\(outputUrl.lastPathComponent)'")

print("Layer property name: \(propertyName)")
if disableOutputLayerProperty {
print(" - disable output layer property")
}

if let layerAllowlist {
print("Layers: '\(layerAllowlist.joined(separator: ","))'")
}

print("Output options:")
print(" - Pretty print: \(prettyPrint)")
print(" - Compression: \(exportOptions.compression)")
print(" - Simplification: \(exportOptions.simplifyFeatures)")
}

guard let data = tile.toGeoJson(
prettyPrinted: prettyPrint,
layerProperty: disableOutputLayerProperty ? nil : propertyName)
layerProperty: disableOutputLayerProperty ? nil : propertyName,
options: exportOptions)
else { throw CLIError("Failed to extract the tile data as GeoJSON") }

try data.write(to: outputUrl, options: .atomic)
Expand Down
30 changes: 18 additions & 12 deletions Sources/MVTCLI/Import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension CLI {
@Option(
name: [.customLong("oC", withSingleDash: true), .long],
help: "Output file compression level, between 0=none to 9=best.")
var compressionLevel: Int = 9
var compressionLevel = 9

@Option(
name: [.customLong("oBe", withSingleDash: true), .long],
Expand Down Expand Up @@ -69,7 +69,7 @@ extension CLI {
@Flag(
name: [.customLong("Di", withSingleDash: true), .long],
help: "Don't parse the layer name (option 'property-name') from Feature properties in the input GeoJSONs, just use 'layer-name' or a default. Might speed up GeoJSON parsing considerably.")
var disableInputLayerProperty: Bool = false
var disableInputLayerProperty = false

@OptionGroup
var xyzOptions: XYZOptions
Expand Down Expand Up @@ -126,16 +126,22 @@ extension CLI {
guard var tile else { throw CLIError("Failed to create a tile [\(x),\(y)]@\(z)") }

if options.verbose {
print("Import into \(tile.origin) tile '\(outputUrl.lastPathComponent)' [\(x),\(y)]@\(z)")
print("Property name: \(propertyName)")
print("Import into \(tile.origin == .none ? "new" : tile.origin.rawValue) tile '\(outputUrl.lastPathComponent)' [\(x),\(y)]@\(z)")

print("Layer property name: \(propertyName)")
if disableInputLayerProperty {
print(" - disable input layer property")
}

if let layerName {
print("Fallback layer name: \(layerName)")
}

if !disableInputLayerProperty,
let layerAllowlist
{
print("Layers: '\(layerAllowlist.joined(separator: ","))'")
}
}

for path in other {
Expand All @@ -157,7 +163,7 @@ extension CLI {
throw CLIError("Failed to parse the GeoJSON at '\(path)'")
}

print("- \(otherUrl.lastPathComponent)")
print("- \(otherUrl.lastPathComponent) (geojson)")

if !disableInputLayerProperty,
let layerAllowlist
Expand Down Expand Up @@ -201,18 +207,18 @@ extension CLI {
.no
}

if options.verbose {
print("Output options:")
print(" - Buffer size: \(bufferSize)")
print(" - Compression: \(compression)")
print(" - Simplification: \(simplifyFeatures)")
}

let exportOptions: VectorTile.ExportOptions = .init(
bufferSize: bufferSize,
compression: compression,
simplifyFeatures: simplifyFeatures)

if options.verbose {
print("Output options:")
print(" - Buffer size: \(exportOptions.bufferSize)")
print(" - Compression: \(exportOptions.compression)")
print(" - Simplification: \(exportOptions.simplifyFeatures)")
}

tile.write(
to: outputUrl,
options: exportOptions)
Expand Down
49 changes: 19 additions & 30 deletions Sources/MVTCLI/Merge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ extension CLI {
print("Dumping the merged tile to the console")
}

print("Property name: \(propertyName)")

print("Layer property name: \(propertyName)")
if disableInputLayerProperty {
print(" - disable input layer property")
}
Expand Down Expand Up @@ -238,16 +237,14 @@ extension CLI {
x: x,
y: y,
z: z,
layerWhitelist: layerAllowlist,
logger: options.verbose ? CLI.logger : nil)
layerWhitelist: layerAllowlist)
{
otherTile = other
}
else if let other = VectorTile(
contentsOfGeoJson: otherUrl,
layerProperty: disableInputLayerProperty ? nil : propertyName,
layerWhitelist: disableInputLayerProperty ? nil : layerAllowlist,
logger: options.verbose ? CLI.logger : nil)
layerWhitelist: disableInputLayerProperty ? nil : layerAllowlist)
{
otherTile = other
}
Expand All @@ -270,58 +267,50 @@ extension CLI {

// Export

let bufferSize: VectorTile.ExportOptions.BufferSizeOptions = if let bufferPixels, bufferPixels > 0 {
.pixel(bufferPixels)
var exportOptions = VectorTile.ExportOptions()

if let bufferPixels, bufferPixels > 0 {
exportOptions.bufferSize = .pixel(bufferPixels)
}
else if let bufferExtents, bufferExtents > 0 {
.extent(bufferExtents)
exportOptions.bufferSize = .extent(bufferExtents)
}
else if outputFormatToUse == .geojson {
.extent(0)
exportOptions.bufferSize = .extent(0)
}
else {
.extent(512)
exportOptions.bufferSize = .extent(512)
}

var compression: VectorTile.ExportOptions.CompressionOptions = .no
if outputUrl != nil { // don't gzip output to the console
if let compressionLevel {
if compressionLevel > 0 {
compression = .level(max(0, min(9, compressionLevel)))
exportOptions.compression = .level(max(0, min(9, compressionLevel)))
}
}
else if outputFormatToUse == .mvt {
compression = .level(9)
exportOptions.compression = .level(9)
}
}

let simplifyFeatures: VectorTile.ExportOptions.SimplifyFeaturesOptions = if let simplifyMeters, simplifyMeters > 0 {
.meters(Double(simplifyMeters))
if let simplifyMeters, simplifyMeters > 0 {
exportOptions.simplifyFeatures = .meters(Double(simplifyMeters))
}
else if let simplifyExtents, simplifyExtents > 0 {
.extent(simplifyExtents)
}
else {
.no
exportOptions.simplifyFeatures = .extent(simplifyExtents)
}

if options.verbose {
print("Output options:")
print(" - File format: \(outputFormatToUse)")
print(" - Buffer size: \(bufferSize)")
print(" - Compression: \(compression)")
print(" - Simplification: \(simplifyFeatures)")

if outputFormatToUse == .geojson || outputUrl == nil {
print(" - Pretty print: \(prettyPrint)")
}
print(" - File format: \(outputFormatToUse)")
print(" - Buffer size: \(exportOptions.bufferSize)")
print(" - Compression: \(exportOptions.compression)")
print(" - Simplification: \(exportOptions.simplifyFeatures)")
}

let exportOptions: VectorTile.ExportOptions = .init(
bufferSize: bufferSize,
compression: compression,
simplifyFeatures: simplifyFeatures)

if let outputUrl {
if outputFormatToUse == .geojson {
if let data = tile.toGeoJson(
Expand Down
Loading

0 comments on commit 2155e1f

Please sign in to comment.