Skip to content

Commit

Permalink
added affine transformation options to import and export
Browse files Browse the repository at this point in the history
  • Loading branch information
clausnagel committed Jan 2, 2025
1 parent 71d2535 commit 552e7f4
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* citydb-tool - Command-line tool for the 3D City Database
* https://www.3dcitydb.org/
*
* Copyright 2022-2025
* virtualcitysystems GmbH, Germany
* https://vc.systems/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.citydb.model.encoding;

import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.reader.ObjectReader;
import org.citydb.model.common.Matrix3x4;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class Matrix3x4Reader implements ObjectReader<Matrix3x4> {
@Override
public Matrix3x4 readObject(JSONReader jsonReader, Type type, Object o, long l) {
if (jsonReader.isArray()) {
List<Double> values = new ArrayList<>();
for (Object value : jsonReader.readArray()) {
if (value instanceof Number number) {
values.add(number.doubleValue());
}
}

if (values.size() > 11) {
return Matrix3x4.ofRowMajor(values);
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* citydb-tool - Command-line tool for the 3D City Database
* https://www.3dcitydb.org/
*
* Copyright 2022-2025
* virtualcitysystems GmbH, Germany
* https://vc.systems/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.citydb.model.encoding;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.writer.ObjectWriter;
import org.citydb.model.common.Matrix3x4;

import java.lang.reflect.Type;
import java.util.List;

public class Matrix3x4Writer implements ObjectWriter<Matrix3x4> {
@Override
public void write(JSONWriter jsonWriter, Object o, Object o1, Type type, long l) {
if (o instanceof Matrix3x4 matrix) {
jsonWriter.startArray();
List<Double> values = matrix.toRowMajor();
for (int i = 0; i < values.size(); i++) {
if (i != 0) {
jsonWriter.writeComma();
}
jsonWriter.writeDouble(values.get(i));
}
jsonWriter.endArray();
} else {
jsonWriter.writeNull();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,12 @@ public Envelope getEnvelope(Matrix4x4 transformationMatrix, Point referencePoint
if (transformationMatrix != null && referencePoint != null) {
Envelope envelope;
if (geometry != null) {
envelope = AffineTransformer.of(transformationMatrix.plus(new Matrix(4, 4)
envelope = geometry.getEnvelope();
AffineTransformer.of(transformationMatrix.plus(new Matrix(4, 4)
.set(0, 3, referencePoint.getCoordinate().getX())
.set(1, 3, referencePoint.getCoordinate().getY())
.set(2, 3, referencePoint.getCoordinate().getZ())))
.transform(geometry.getEnvelope());
.transform(envelope);
} else {
envelope = Envelope.empty().include(Point.of(Coordinate.of(
referencePoint.getCoordinate().getX() + transformationMatrix.get(0, 3),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.citydb.model.common.Matrix2x2;
import org.citydb.model.common.Matrix3x4;
import org.citydb.model.common.Matrix4x4;
import org.citydb.model.common.Visitable;
import org.citydb.model.feature.Feature;
import org.citydb.model.geometry.*;
import org.citydb.model.property.AppearanceProperty;
Expand Down Expand Up @@ -61,7 +62,7 @@ public static AffineTransformer ofRowMajor(List<Double> values, int rows) {
return of(new Matrix(values, rows));
}

public Coordinate transform(Coordinate coordinate) {
public void transform(Coordinate coordinate) {
Matrix transformed = matrix.times(new Matrix(new double[][]{
{coordinate.getX()},
{coordinate.getY()},
Expand All @@ -74,27 +75,25 @@ public Coordinate transform(Coordinate coordinate) {
if (coordinate.getDimension() == 3) {
coordinate.setZ(transformed.get(2, 0));
}

return coordinate;
}

public Feature transform(Feature feature) {
public void transform(Feature feature) {
feature.accept(processor);
return feature;
}

public Geometry<?> transform(Geometry<?> geometry) {
public void transform(Geometry<?> geometry) {
geometry.accept(processor);
return geometry;
}

public Envelope transform(Envelope envelope) {
public void transform(Visitable visitable) {
visitable.accept(processor);
}

public void transform(Envelope envelope) {
if (!envelope.isEmpty()) {
transform(envelope.getLowerCorner());
transform(envelope.getUpperCorner());
}

return envelope;
}

private class Processor extends ModelWalker {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import org.citydb.core.concurrent.LazyCheckedInitializer;
import org.citydb.core.file.OutputFile;
import org.citydb.core.file.output.RegularOutputFile;
import org.citydb.model.common.Matrix3x4;
import org.citydb.model.encoding.Matrix3x4Reader;
import org.citydb.model.encoding.Matrix3x4Writer;
import org.citydb.operation.exporter.options.AppearanceOptions;
import org.citydb.operation.exporter.options.LodOptions;

Expand All @@ -47,6 +50,8 @@ public class ExportOptions {
private SrsReference targetSrs;
private LodOptions lodOptions;
private AppearanceOptions appearanceOptions;
@JSONField(serializeUsing = Matrix3x4Writer.class, deserializeUsing = Matrix3x4Reader.class)
private Matrix3x4 affineTransform;

public OutputFile getOutputFile() {
if (outputFile == null) {
Expand Down Expand Up @@ -105,4 +110,13 @@ public ExportOptions setAppearanceOptions(AppearanceOptions appearanceOptions) {
this.appearanceOptions = appearanceOptions;
return this;
}

public Optional<Matrix3x4> getAffineTransform() {
return Optional.ofNullable(affineTransform);
}

public ExportOptions setAffineTransform(Matrix3x4 affineTransform) {
this.affineTransform = affineTransform;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.citydb.model.property.FeatureProperty;
import org.citydb.model.property.ImplicitGeometryProperty;
import org.citydb.model.property.Property;
import org.citydb.model.util.AffineTransformer;
import org.citydb.model.walker.ModelWalker;
import org.citydb.operation.exporter.ExportHelper;

Expand All @@ -43,6 +44,7 @@ public class Postprocessor {
private final ExportHelper helper;
private final EnvelopeHelper envelopeHelper;
private final AppearanceHelper appearanceHelper;
private final AffineTransformer transformer;
private final Comparator<Property<?>> comparator = Comparator.comparingLong(
property -> property.getDescriptor()
.map(DatabaseDescriptor::getId)
Expand All @@ -52,6 +54,7 @@ public Postprocessor(ExportHelper helper) {
this.helper = helper;
appearanceHelper = new AppearanceHelper(helper);
envelopeHelper = new EnvelopeHelper(helper);
transformer = helper.getOptions().getAffineTransform().map(AffineTransformer::of).orElse(null);
}

public void process(Feature feature) {
Expand All @@ -75,11 +78,20 @@ public void process(Feature feature) {
envelopeHelper.updateEnvelope(feature);
}

if (transformer != null) {
transformer.transform(feature);
}

sortAttributes(feature);
}

public void process(Visitable visitable) {
appearanceHelper.assignSurfaceData(visitable, helper.getSurfaceDataMapper());

if (transformer != null) {
transformer.transform(visitable);
}

sortAttributes(visitable);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.citydb.model.common.Visitable;
import org.citydb.model.feature.Feature;
import org.citydb.model.feature.FeatureDescriptor;
import org.citydb.model.util.AffineTransformer;
import org.citydb.operation.importer.common.DatabaseImporter;
import org.citydb.operation.importer.feature.FeatureImporter;
import org.citydb.operation.importer.reference.CacheType;
Expand All @@ -51,6 +52,7 @@ public class ImportHelper {
private final SchemaMapping schemaMapping;
private final TableHelper tableHelper;
private final SequenceHelper sequenceHelper;
private final AffineTransformer transformer;
private final Map<CacheType, ReferenceCache> caches = new EnumMap<>(CacheType.class);
private final List<ImportLogEntry> logEntries = new ArrayList<>();
private final Importer.TransactionMode transactionMode;
Expand All @@ -70,6 +72,7 @@ public class ImportHelper {
schemaMapping = adapter.getSchemaAdapter().getSchemaMapping();
tableHelper = new TableHelper(this);
sequenceHelper = new SequenceHelper(this);
transformer = options.getAffineTransform().map(AffineTransformer::of).orElse(null);
batchSize = options.getBatchSize() > 0 ?
Math.min(options.getBatchSize(), adapter.getSchemaAdapter().getMaximumBatchSize()) :
ImportOptions.DEFAULT_BATCH_SIZE;
Expand Down Expand Up @@ -110,6 +113,10 @@ public FileLocator getFileLocator(ExternalFile file) {

FeatureDescriptor importFeature(Feature feature) throws ImportException {
try {
if (transformer != null) {
transformer.transform(feature);
}

generateSequenceValues(feature);
FeatureDescriptor descriptor = tableHelper.getOrCreateImporter(FeatureImporter.class).doImport(feature);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@

package org.citydb.operation.importer;

import com.alibaba.fastjson2.annotation.JSONField;
import org.citydb.config.SerializableConfig;
import org.citydb.core.CoreConstants;
import org.citydb.model.common.Matrix3x4;
import org.citydb.model.encoding.Matrix3x4Reader;
import org.citydb.model.encoding.Matrix3x4Writer;

import java.nio.file.Path;
import java.util.Optional;

@SerializableConfig(name = "importOptions")
public class ImportOptions {
Expand All @@ -33,6 +38,8 @@ public class ImportOptions {
private String tempDirectory;
private int numberOfThreads;
private int batchSize = DEFAULT_BATCH_SIZE;
@JSONField(serializeUsing = Matrix3x4Writer.class, deserializeUsing = Matrix3x4Reader.class)
private Matrix3x4 affineTransform;

public Path getTempDirectory() {
return tempDirectory != null ? CoreConstants.WORKING_DIR.resolve(tempDirectory) : null;
Expand Down Expand Up @@ -60,4 +67,13 @@ public ImportOptions setBatchSize(int batchSize) {
this.batchSize = batchSize;
return this;
}

public Optional<Matrix3x4> getAffineTransform() {
return Optional.ofNullable(affineTransform);
}

public ImportOptions setAffineTransform(Matrix3x4 affineTransform) {
this.affineTransform = affineTransform;
return this;
}
}

0 comments on commit 552e7f4

Please sign in to comment.