diff --git a/rtron-main/src/main/kotlin/io/rtron/main/processor/CompressionFormat.kt b/rtron-main/src/main/kotlin/io/rtron/main/processor/CompressionFormat.kt index 01e612a1..01ec6153 100644 --- a/rtron-main/src/main/kotlin/io/rtron/main/processor/CompressionFormat.kt +++ b/rtron-main/src/main/kotlin/io/rtron/main/processor/CompressionFormat.kt @@ -16,11 +16,6 @@ package io.rtron.main.processor -import arrow.core.None -import arrow.core.Option -import arrow.core.some -import io.rtron.io.files.CompressedFileExtension - enum class CompressionFormat { NONE, GZ, @@ -28,9 +23,9 @@ enum class CompressionFormat { ZST } -fun CompressionFormat.toOptionalCompressedFileExtension(): Option = when (this) { - CompressionFormat.NONE -> None - CompressionFormat.GZ -> CompressedFileExtension.GZ.some() - CompressionFormat.ZIP -> CompressedFileExtension.ZIP.some() - CompressionFormat.ZST -> CompressedFileExtension.ZST.some() +fun CompressionFormat.toFileExtension(): String = when (this) { + CompressionFormat.NONE -> "" + CompressionFormat.GZ -> ".gz" + CompressionFormat.ZIP -> ".zip" + CompressionFormat.ZST -> ".zst" } diff --git a/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlParameters.kt b/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlParameters.kt index a4f423dd..203c9037 100644 --- a/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlParameters.kt +++ b/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlParameters.kt @@ -20,8 +20,6 @@ import arrow.core.Either import arrow.core.left import arrow.core.right import io.rtron.readerwriter.citygml.CitygmlVersion -import io.rtron.readerwriter.citygml.CitygmlWriterParameters -import io.rtron.readerwriter.opendrive.OpendriveWriterParameters import io.rtron.transformer.converter.opendrive2roadspaces.Opendrive2RoadspacesParameters import io.rtron.transformer.converter.roadspaces2citygml.Roadspaces2CitygmlParameters import io.rtron.transformer.evaluator.opendrive.OpendriveEvaluatorParameters @@ -101,10 +99,6 @@ data class OpendriveToCitygmlParameters( cropPolygonY = cropPolygonY ) - fun deriveOpendriveWriterParameters() = OpendriveWriterParameters( - fileCompression = compressionFormat.toOptionalCompressedFileExtension() - ) - fun deriveOpendrive2RoadspacesParameters() = Opendrive2RoadspacesParameters( concurrentProcessing = false, @@ -137,9 +131,4 @@ data class OpendriveToCitygmlParameters( generateLongitudinalFillerSurfaces = Roadspaces2CitygmlParameters.DEFAULT_GENERATE_LONGITUDINAL_FILLER_SURFACES, mappingBackwardsCompatibility = convertToCitygml2 ) - - fun deriveCitygmlWriterParameters() = CitygmlWriterParameters( - versions = setOf(this.getCitygmlWriteVersion()), - fileCompression = compressionFormat.toOptionalCompressedFileExtension() - ) } diff --git a/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlProcessor.kt b/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlProcessor.kt index df693b9d..15612320 100644 --- a/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlProcessor.kt +++ b/rtron-main/src/main/kotlin/io/rtron/main/processor/OpendriveToCitygmlProcessor.kt @@ -22,9 +22,9 @@ import io.rtron.io.messages.getTextSummary import io.rtron.io.serialization.serializeToJsonFile import io.rtron.main.project.processAllFiles import io.rtron.readerwriter.citygml.CitygmlWriter -import io.rtron.readerwriter.opendrive.OpendriveFileReader -import io.rtron.readerwriter.opendrive.OpendriveFileWriter +import io.rtron.readerwriter.opendrive.OpendriveReader import io.rtron.readerwriter.opendrive.OpendriveValidator +import io.rtron.readerwriter.opendrive.OpendriveWriter import io.rtron.std.handleEmpty import io.rtron.transformer.converter.opendrive2roadspaces.Opendrive2RoadspacesTransformer import io.rtron.transformer.converter.roadspaces2citygml.Roadspaces2CitygmlTransformer @@ -50,7 +50,7 @@ class OpendriveToCitygmlProcessor( processAllFiles( inputDirectoryPath = inputPath, - withFilenameEndings = OpendriveFileReader.supportedFilenameEndings, + withFilenameEndings = OpendriveReader.supportedFilenameEndings, outputDirectoryPath = outputPath ) { val outputSubDirectoryPath = outputDirectoryPath / "citygml_${parameters.getCitygmlWriteVersion()}" @@ -71,7 +71,7 @@ class OpendriveToCitygmlProcessor( return@processAllFiles } // read of OpenDRIVE model - val opendriveModel = OpendriveFileReader.readFromFile(inputFilePath) + val opendriveModel = OpendriveReader.readFromFile(inputFilePath) .getOrElse { logger.warn(it.message); return@processAllFiles } // evaluate OpenDRIVE model @@ -103,8 +103,8 @@ class OpendriveToCitygmlProcessor( } // write offset OpenDRIVE model - val opendriveFileWriter = OpendriveFileWriter(parameters.deriveOpendriveWriterParameters()) - opendriveFileWriter.write(opendriveCropped, outputSubDirectoryPath) + val opendriveFilePath = outputSubDirectoryPath / ("opendrive.xodr" + parameters.compressionFormat.toFileExtension()) + OpendriveWriter.writeToFile(opendriveCropped, opendriveFilePath) // transform OpenDRIVE model to Roadspaces model val opendrive2RoadspacesTransformer = Opendrive2RoadspacesTransformer(parameters.deriveOpendrive2RoadspacesParameters()) @@ -126,7 +126,7 @@ class OpendriveToCitygmlProcessor( citygmlModelResult.second.serializeToJsonFile(outputSubDirectoryPath / ROADSPACES_TO_CITYGML_REPORT_PATH) // write CityGML model - CitygmlWriter.writeModel(citygmlModelResult.first, outputSubDirectoryPath, "citygml_model", parameters.deriveCitygmlWriterParameters()) + CitygmlWriter.writeToFile(citygmlModelResult.first, parameters.getCitygmlWriteVersion(), outputSubDirectoryPath / "citygml_model.gml") } } diff --git a/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveParameters.kt b/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveParameters.kt index 7eecbc69..80559590 100644 --- a/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveParameters.kt +++ b/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveParameters.kt @@ -16,9 +16,6 @@ package io.rtron.main.processor -import io.rtron.readerwriter.citygml.CitygmlVersion -import io.rtron.readerwriter.citygml.CitygmlWriterParameters -import io.rtron.readerwriter.opendrive.OpendriveWriterParameters import io.rtron.transformer.converter.opendrive2roadspaces.Opendrive2RoadspacesParameters import io.rtron.transformer.converter.roadspaces2citygml.Roadspaces2CitygmlParameters import io.rtron.transformer.evaluator.opendrive.OpendriveEvaluatorParameters @@ -53,10 +50,6 @@ data class ValidateOpendriveParameters( planViewGeometryAngleWarningTolerance = planViewGeometryAngleWarningTolerance ) - fun deriveOpendriveWriterParameters() = OpendriveWriterParameters( - fileCompression = compressionFormat.toOptionalCompressedFileExtension() - ) - fun deriveOpendrive2RoadspacesParameters() = Opendrive2RoadspacesParameters( concurrentProcessing = false, numberTolerance = tolerance, @@ -104,14 +97,4 @@ data class ValidateOpendriveParameters( generateLongitudinalFillerSurfaces = false, mappingBackwardsCompatibility = false ) - - fun deriveCitygml2WriterParameters() = CitygmlWriterParameters( - versions = setOf(CitygmlVersion.V2_0), - fileCompression = compressionFormat.toOptionalCompressedFileExtension() - ) - - fun deriveCitygml3WriterParameters() = CitygmlWriterParameters( - versions = setOf(CitygmlVersion.V3_0), - fileCompression = compressionFormat.toOptionalCompressedFileExtension() - ) } diff --git a/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveProcessor.kt b/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveProcessor.kt index de9af7ab..9c46fb80 100644 --- a/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveProcessor.kt +++ b/rtron-main/src/main/kotlin/io/rtron/main/processor/ValidateOpendriveProcessor.kt @@ -21,10 +21,11 @@ import com.charleskorn.kaml.Yaml import io.rtron.io.messages.getTextSummary import io.rtron.io.serialization.serializeToJsonFile import io.rtron.main.project.processAllFiles +import io.rtron.readerwriter.citygml.CitygmlVersion import io.rtron.readerwriter.citygml.CitygmlWriter -import io.rtron.readerwriter.opendrive.OpendriveFileReader -import io.rtron.readerwriter.opendrive.OpendriveFileWriter +import io.rtron.readerwriter.opendrive.OpendriveReader import io.rtron.readerwriter.opendrive.OpendriveValidator +import io.rtron.readerwriter.opendrive.OpendriveWriter import io.rtron.std.handleEmpty import io.rtron.transformer.converter.opendrive2roadspaces.Opendrive2RoadspacesTransformer import io.rtron.transformer.converter.roadspaces2citygml.Roadspaces2CitygmlTransformer @@ -46,7 +47,7 @@ class ValidateOpendriveProcessor( processAllFiles( inputDirectoryPath = inputPath, - withFilenameEndings = OpendriveFileReader.supportedFilenameEndings, + withFilenameEndings = OpendriveReader.supportedFilenameEndings, outputDirectoryPath = outputPath ) { // write the parameters as yaml file @@ -60,7 +61,7 @@ class ValidateOpendriveProcessor( return@processAllFiles } // read of OpenDRIVE model - val opendriveModel = OpendriveFileReader.readFromFile(inputFilePath) + val opendriveModel = OpendriveReader.readFromFile(inputFilePath) .getOrElse { logger.warn(it.message); return@processAllFiles } // evaluate OpenDRIVE model @@ -78,8 +79,8 @@ class ValidateOpendriveProcessor( // write modified OpenDRIVE model if (parameters.writeOpendriveFile) { - val opendriveFileWriter = OpendriveFileWriter(parameters.deriveOpendriveWriterParameters()) - opendriveFileWriter.write(modifiedOpendriveModel, outputDirectoryPath) + val filePath = outputDirectoryPath / ("opendrive.xodr" + parameters.compressionFormat.toFileExtension()) + OpendriveWriter.writeToFile(modifiedOpendriveModel, filePath) } // transform OpenDRIVE model to Roadspaces model @@ -103,7 +104,8 @@ class ValidateOpendriveProcessor( // write CityGML 2 model if (parameters.writeCitygml2File) { - CitygmlWriter.writeModel(citygml2ModelResult.first, outputDirectoryPath, "citygml2_model", parameters.deriveCitygml2WriterParameters()) + val filePath = outputDirectoryPath / ("citygml2_model.gml" + parameters.compressionFormat.toFileExtension()) + CitygmlWriter.writeToFile(citygml2ModelResult.first, CitygmlVersion.V2_0, filePath) } // transform Roadspaces model to CityGML3 model @@ -113,7 +115,8 @@ class ValidateOpendriveProcessor( // write CityGML3 model if (parameters.writeCitygml3File) { - CitygmlWriter.writeModel(citygml3ModelResult.first, outputDirectoryPath, "citygml3_model", parameters.deriveCitygml3WriterParameters()) + val filePath = outputDirectoryPath / ("citygml3_model.gml" + parameters.compressionFormat.toFileExtension()) + CitygmlWriter.writeToFile(citygml3ModelResult.first, CitygmlVersion.V3_0, filePath) } } } diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriter.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriter.kt index aef6dc99..5973adf6 100644 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriter.kt +++ b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriter.kt @@ -22,10 +22,9 @@ import io.rtron.model.citygml.CitygmlModel import mu.KotlinLogging import org.citygml4j.xml.CityGMLContext import org.citygml4j.xml.module.citygml.CoreModule +import java.io.OutputStream import java.nio.charset.StandardCharsets import java.nio.file.Path -import kotlin.io.path.Path -import kotlin.io.path.div object CitygmlWriter { @@ -36,18 +35,18 @@ object CitygmlWriter { // Methods - fun writeModel(model: CitygmlModel, directoryPath: Path, fileNameWithoutExtension: String, parameters: CitygmlWriterParameters): List { - return parameters.versions.map { write(model, it, directoryPath, fileNameWithoutExtension, parameters) } + fun writeToFile(model: CitygmlModel, version: CitygmlVersion, filePath: Path) { + val outputStream = filePath.outputStreamDirectOrCompressed() + writeToStream(model, version, outputStream) + outputStream.close() + + logger.info("Completed writing of file ${filePath.fileName} (around ${filePath.getFileSizeToDisplay()}).") } - private fun write(model: CitygmlModel, version: CitygmlVersion, directoryPath: Path, fileNameWithoutExtension: String, parameters: CitygmlWriterParameters): Path { + fun writeToStream(model: CitygmlModel, version: CitygmlVersion, outputStream: OutputStream) { val citygmlVersion = version.toGmlCitygml() val out = citygmlContext.createCityGMLOutputFactory(citygmlVersion)!! - val fileName = fileNameWithoutExtension + ".gml" + parameters.fileCompression.fold({ "" }, { it.extensionWithDot }) - val filePath = directoryPath / Path(fileName) - val outputStream = filePath.outputStreamDirectOrCompressed() - val writer = out.createCityGMLChunkWriter(outputStream, StandardCharsets.UTF_8.name()) writer.apply { withIndent(" ") @@ -61,10 +60,5 @@ object CitygmlWriter { } writer.close() - outputStream.close() - logger.info("Completed writing of file $fileName (around ${filePath.getFileSizeToDisplay()}).") - return filePath } - - val supportedFilenameEndings: Set = setOf("gml") } diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriterParameters.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriterParameters.kt deleted file mode 100644 index 9f0884d2..00000000 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/citygml/CitygmlWriterParameters.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2019-2023 Chair of Geoinformatics, Technical University of Munich - * - * 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 io.rtron.readerwriter.citygml - -import arrow.core.None -import arrow.core.Option -import io.rtron.io.files.CompressedFileExtension - -data class CitygmlWriterParameters( - val versions: Set, - val fileCompression: Option -) { - // Properties and Initializers - init { - require(versions.isNotEmpty()) { "At least one CitGML version must be set." } - } - - companion object { - val DEFAULT_FILE_COMPRESSION = None - } -} diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveReader.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveReader.kt index aa0664bc..ed5c28a0 100644 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveReader.kt +++ b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveReader.kt @@ -36,7 +36,7 @@ import java.io.InputStream import java.nio.file.Path import kotlin.io.path.isRegularFile -object OpendriveFileReader { +object OpendriveReader { // Properties and Initializers private val logger = KotlinLogging.logger {} diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriter.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriter.kt index fe4b72b3..0d8d78e4 100644 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriter.kt +++ b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriter.kt @@ -19,26 +19,31 @@ package io.rtron.readerwriter.opendrive import arrow.core.Either import arrow.core.raise.either import io.rtron.io.files.getFileSizeToDisplay +import io.rtron.io.files.outputStreamDirectOrCompressed import io.rtron.model.opendrive.OpendriveModel import io.rtron.readerwriter.opendrive.writer.OpendriveMarshaller import io.rtron.std.BaseException import mu.KotlinLogging +import java.io.OutputStream import java.nio.file.Path -class OpendriveFileWriter( - val parameters: OpendriveWriterParameters -) { +object OpendriveWriter { // Properties and Initializers private val logger = KotlinLogging.logger {} private val opendriveMarshaller by lazy { OpendriveMarshaller() } // Methods - fun write(model: OpendriveModel, directoryPath: Path): Either = either { - val filePath = opendriveMarshaller.writeToFile(model, directoryPath, parameters.fileCompression).bind() + fun writeToFile(model: OpendriveModel, filePath: Path): Either = either { + val outputStream: OutputStream = filePath.outputStreamDirectOrCompressed() + writeToStream(model, outputStream) + outputStream.close() + logger.info("Completed writing of file ${filePath.fileName} (around ${filePath.getFileSizeToDisplay()}).") + } - filePath + fun writeToStream(model: OpendriveModel, outputStream: OutputStream) { + opendriveMarshaller.writeToStream(model, outputStream) } } diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriterParameters.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriterParameters.kt deleted file mode 100644 index 85ac71df..00000000 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/OpendriveWriterParameters.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2019-2023 Chair of Geoinformatics, Technical University of Munich - * - * 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 io.rtron.readerwriter.opendrive - -import arrow.core.None -import arrow.core.Option -import io.rtron.io.files.CompressedFileExtension - -data class OpendriveWriterParameters( - val fileCompression: Option = DEFAULT_FILE_COMPRESSION -) { - - companion object { - val DEFAULT_FILE_COMPRESSION = None - } -} diff --git a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/writer/OpendriveMarshaller.kt b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/writer/OpendriveMarshaller.kt index 9322f0cd..4128dd25 100644 --- a/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/writer/OpendriveMarshaller.kt +++ b/rtron-readerwriter/src/main/kotlin/io/rtron/readerwriter/opendrive/writer/OpendriveMarshaller.kt @@ -16,21 +16,13 @@ package io.rtron.readerwriter.opendrive.writer -import arrow.core.Either -import arrow.core.Option -import arrow.core.right -import io.rtron.io.files.CompressedFileExtension -import io.rtron.io.files.outputStreamDirectOrCompressed import io.rtron.model.opendrive.OpendriveModel -import io.rtron.readerwriter.opendrive.OpendriveWriterException import io.rtron.readerwriter.opendrive.version.OpendriveVersion import io.rtron.readerwriter.opendrive.writer.mapper.opendrive17.Opendrive17Mapper import jakarta.xml.bind.JAXBContext import jakarta.xml.bind.Marshaller import org.mapstruct.factory.Mappers import java.io.OutputStream -import java.nio.file.Path -import kotlin.io.path.Path import kotlin.io.path.div class OpendriveMarshaller { @@ -47,20 +39,14 @@ class OpendriveMarshaller { } // Methods - fun writeToFile(model: OpendriveModel, directoryPath: Path, outputFileCompression: Option): Either { + + fun writeToStream(model: OpendriveModel, outputStream: OutputStream) { val converter = Mappers.getMapper(Opendrive17Mapper::class.java) val opendrive17Model = converter.mapModel(model) opendrive17Model.header.revMajor = supportedVersion.rev.first opendrive17Model.header.revMinor = supportedVersion.rev.second - - val fileName = "opendrive17.xml" + outputFileCompression.fold({ "" }, { it.extensionWithDot }) - val filePath = directoryPath / Path(fileName) - val outputStream: OutputStream = filePath.outputStreamDirectOrCompressed() jaxbMarshaller.marshal(opendrive17Model, outputStream) - outputStream.close() - - return filePath.right() } }