Skip to content

Commit 146d39d

Browse files
committed
added a transform option to the import and export commands
1 parent 552e7f4 commit 146d39d

File tree

7 files changed

+108
-12
lines changed

7 files changed

+108
-12
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* citydb-tool - Command-line tool for the 3D City Database
3+
* https://www.3dcitydb.org/
4+
*
5+
* Copyright 2022-2025
6+
* virtualcitysystems GmbH, Germany
7+
* https://vc.systems/
8+
*
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
*/
21+
22+
package org.citydb.cli.common;
23+
24+
import org.citydb.model.common.Matrix3x4;
25+
import picocli.CommandLine;
26+
27+
import java.util.Arrays;
28+
29+
public class TransformOptions implements Option {
30+
@CommandLine.Option(names = "--transform", paramLabel = "<m0,m1,...,m11|swap-xy>",
31+
description = "Transform coordinates using a 3x4 matrix in row-major order. Use 'swap-xy' as a shortcut.")
32+
private String transform;
33+
34+
private Matrix3x4 transformationMatrix;
35+
36+
public Matrix3x4 getTransformationMatrix() {
37+
return transformationMatrix;
38+
}
39+
40+
@Override
41+
public void preprocess(CommandLine commandLine) throws Exception {
42+
if (transform != null) {
43+
if (transform.equalsIgnoreCase("swap-xy")) {
44+
transformationMatrix = Matrix3x4.ofRowMajor(
45+
0, 1, 0, 0,
46+
1, 0, 0, 0,
47+
0, 0, 1, 0);
48+
} else {
49+
String[] values = transform.split(",");
50+
if (values.length == 12) {
51+
try {
52+
transformationMatrix = Matrix3x4.ofRowMajor(Arrays.stream(values)
53+
.map(Double::parseDouble)
54+
.toList());
55+
} catch (NumberFormatException e) {
56+
throw new CommandLine.ParameterException(commandLine,
57+
"Error: The elements of a 3x4 matrix must be floating point numbers but were '" +
58+
String.join(",", values) + "'");
59+
}
60+
} else {
61+
throw new CommandLine.ParameterException(commandLine,
62+
"Error: A 3x4 matrix must be in M0,M1,...,M11 format but was '" + transform + "'");
63+
}
64+
}
65+
}
66+
}
67+
}

citydb-cli/src/main/java/org/citydb/cli/exporter/ExportController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ public abstract class ExportController implements Command {
8181
@CommandLine.Mixin
8282
protected CrsOptions crsOptions;
8383

84+
@CommandLine.Mixin
85+
protected TransformOptions transformOptions;
86+
8487
@CommandLine.ArgGroup(exclusive = false, order = Integer.MAX_VALUE,
8588
heading = "Query and filter options:%n")
8689
protected QueryOptions queryOptions;
@@ -263,6 +266,10 @@ protected ExportOptions getExportOptions() throws ExecutionException {
263266
exportOptions.setTargetSrs(crsOptions.getTargetSrs());
264267
}
265268

269+
if (transformOptions != null) {
270+
exportOptions.setAffineTransform(transformOptions.getTransformationMatrix());
271+
}
272+
266273
if (queryOptions != null) {
267274
if (queryOptions.getLodOptions() != null) {
268275
exportOptions.setLodOptions(queryOptions.getLodOptions().getExportLodOptions());

citydb-cli/src/main/java/org/citydb/cli/importer/ImportController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ enum Mode {import_all, skip, delete, terminate}
8585
description = "Compute and overwrite extents of features.")
8686
protected Boolean computeEnvelopes;
8787

88+
@CommandLine.Mixin
89+
protected TransformOptions transformOptions;
90+
8891
@CommandLine.ArgGroup(exclusive = false, order = Integer.MAX_VALUE,
8992
heading = "Database connection options:%n")
9093
protected ConnectionOptions connectionOptions;
@@ -295,6 +298,10 @@ protected ImportOptions getImportOptions() throws ExecutionException {
295298
importOptions.setNumberOfThreads(threadsOptions.getNumberOfThreads());
296299
}
297300

301+
if (transformOptions != null) {
302+
importOptions.setAffineTransform(transformOptions.getTransformationMatrix());
303+
}
304+
298305
return importOptions;
299306
}
300307

citydb-model/src/main/java/org/citydb/model/common/Matrix2x2.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.citydb.model.util.matrix.Matrix;
2525

26+
import java.util.Arrays;
2627
import java.util.List;
2728
import java.util.Objects;
2829

@@ -58,6 +59,10 @@ public static Matrix2x2 ofRowMajor(List<Double> values) {
5859
}
5960
}
6061

62+
public static Matrix2x2 ofRowMajor(double... values) {
63+
return ofRowMajor(values != null ? Arrays.stream(values).boxed().toList() : null);
64+
}
65+
6166
public static Matrix2x2 identity() {
6267
return new Matrix2x2(Matrix.identity(2, 2));
6368
}

citydb-model/src/main/java/org/citydb/model/common/Matrix3x4.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.citydb.model.util.matrix.Matrix;
2525

26+
import java.util.Arrays;
2627
import java.util.List;
2728
import java.util.Objects;
2829

@@ -60,7 +61,11 @@ public static Matrix3x4 ofRowMajor(List<Double> values) {
6061
}
6162
}
6263

64+
public static Matrix3x4 ofRowMajor(double... values) {
65+
return ofRowMajor(values != null ? Arrays.stream(values).boxed().toList() : null);
66+
}
67+
6368
public static Matrix3x4 identity() {
64-
return new Matrix3x4(Matrix.identity(4, 4).getSubMatrix(0, 2, 0, 3));
69+
return new Matrix3x4(Matrix.identity(3, 4));
6570
}
6671
}

citydb-model/src/main/java/org/citydb/model/common/Matrix4x4.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.citydb.model.util.matrix.Matrix;
2525

26+
import java.util.Arrays;
2627
import java.util.List;
2728
import java.util.Objects;
2829

@@ -58,6 +59,10 @@ public static Matrix4x4 ofRowMajor(List<Double> values) {
5859
}
5960
}
6061

62+
public static Matrix4x4 ofRowMajor(double... values) {
63+
return ofRowMajor(values != null ? Arrays.stream(values).boxed().toList() : null);
64+
}
65+
6166
public static Matrix4x4 identity() {
6267
return new Matrix4x4(Matrix.identity(4, 4));
6368
}

citydb-operation/src/main/java/org/citydb/operation/exporter/ExportOptions.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ public class ExportOptions {
4848
private OutputFile outputFile;
4949
private int numberOfThreads;
5050
private SrsReference targetSrs;
51-
private LodOptions lodOptions;
52-
private AppearanceOptions appearanceOptions;
5351
@JSONField(serializeUsing = Matrix3x4Writer.class, deserializeUsing = Matrix3x4Reader.class)
5452
private Matrix3x4 affineTransform;
53+
private LodOptions lodOptions;
54+
private AppearanceOptions appearanceOptions;
5555

5656
public OutputFile getOutputFile() {
5757
if (outputFile == null) {
@@ -93,6 +93,15 @@ public ExportOptions setTargetSrs(SrsReference targetSrs) {
9393
return this;
9494
}
9595

96+
public Optional<Matrix3x4> getAffineTransform() {
97+
return Optional.ofNullable(affineTransform);
98+
}
99+
100+
public ExportOptions setAffineTransform(Matrix3x4 affineTransform) {
101+
this.affineTransform = affineTransform;
102+
return this;
103+
}
104+
96105
public Optional<LodOptions> getLodOptions() {
97106
return Optional.ofNullable(lodOptions);
98107
}
@@ -110,13 +119,4 @@ public ExportOptions setAppearanceOptions(AppearanceOptions appearanceOptions) {
110119
this.appearanceOptions = appearanceOptions;
111120
return this;
112121
}
113-
114-
public Optional<Matrix3x4> getAffineTransform() {
115-
return Optional.ofNullable(affineTransform);
116-
}
117-
118-
public ExportOptions setAffineTransform(Matrix3x4 affineTransform) {
119-
this.affineTransform = affineTransform;
120-
return this;
121-
}
122122
}

0 commit comments

Comments
 (0)