Skip to content

Commit

Permalink
adapted API of feature reader and writer
Browse files Browse the repository at this point in the history
  • Loading branch information
clausnagel committed Nov 10, 2024
1 parent 74c26be commit 1556541
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,12 @@ protected boolean doExport() throws ExecutionException {
FeatureStatistics tileStatistics = new FeatureStatistics(databaseManager.getAdapter());

try (OutputFile outputFile = builder.newOutputFile(file);
FeatureWriter writer = createWriter(query, ioAdapter)) {
FeatureWriter writer = createWriter(outputFile, writeOptions, query, ioAdapter)) {
Exporter exporter = Exporter.newInstance();
exportOptions.setOutputFile(outputFile);

logger.info("{}Exporting to {} file {}.", getTileCounter(tilingHelper, tile),
ioManager.getFileFormat(ioAdapter), outputFile.getFile());
writer.initialize(outputFile, writeOptions);

logger.debug("Querying features matching the request...");
logger.trace("Using SQL query:\n{}", () -> helper.getFormattedSql(executor.getSelect(),
Expand Down Expand Up @@ -229,8 +228,8 @@ protected boolean doExport() throws ExecutionException {
return shouldRun;
}

private FeatureWriter createWriter(Query query, IOAdapter ioAdapter) throws WriteException {
FeatureWriter writer = ioAdapter.createWriter();
private FeatureWriter createWriter(OutputFile file, WriteOptions options, Query query, IOAdapter ioAdapter) throws WriteException {
FeatureWriter writer = ioAdapter.createWriter(file, options);
return query.getSorting().isPresent() ?
SequentialWriter.of(writer) :
writer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
package org.citydb.cli.exporter.util;

import org.apache.logging.log4j.Logger;
import org.citydb.core.file.OutputFile;
import org.citydb.io.writer.FeatureWriter;
import org.citydb.io.writer.WriteException;
import org.citydb.io.writer.WriteOptions;
import org.citydb.logging.LoggerManager;
import org.citydb.model.feature.Feature;
import org.citydb.model.feature.FeatureDescriptor;
Expand Down Expand Up @@ -60,11 +58,6 @@ public static SequentialWriter of(FeatureWriter writer) {
return new SequentialWriter(writer);
}

@Override
public void initialize(OutputFile file, WriteOptions options) throws WriteException {
writer.initialize(file, options);
}

@Override
public void write(Feature feature, BiConsumer<Boolean, Throwable> onCompletion) throws WriteException {
long sequenceId = feature.getDescriptor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,7 @@ protected boolean doImport() throws ExecutionException {
InputFile inputFile = inputFiles.get(i);
logger.info("[{}|{}] Importing file {}.", i + 1, inputFiles.size(), inputFile.getContentFile());

try (FeatureReader reader = ioAdapter.createReader()) {
logger.debug("Preprocessing input file...");
reader.initialize(inputFile, readOptions);

logger.debug("Importing features from input file...");
try (FeatureReader reader = ioAdapter.createReader(inputFile, readOptions)) {
importer.startSession(databaseManager.getAdapter(), importOptions);

reader.read(feature -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,20 @@
package org.citydb.io.citygml;

import org.citydb.core.file.InputFile;
import org.citydb.core.file.OutputFile;
import org.citydb.io.FileFormat;
import org.citydb.io.IOAdapter;
import org.citydb.io.IOAdapterException;
import org.citydb.io.citygml.reader.CityGMLReader;
import org.citydb.io.citygml.writer.CityGMLWriter;
import org.citydb.io.reader.FeatureReader;
import org.citydb.io.reader.ReadException;
import org.citydb.io.reader.ReadOptions;
import org.citydb.io.validator.ValidateException;
import org.citydb.io.validator.Validator;
import org.citydb.io.writer.FeatureWriter;
import org.citydb.io.writer.WriteException;
import org.citydb.io.writer.WriteOptions;
import org.citygml4j.core.ade.ADERegistry;
import org.citygml4j.xml.CityGMLADELoader;
import org.citygml4j.xml.module.citygml.CityGMLModules;
Expand Down Expand Up @@ -75,13 +80,13 @@ public boolean canRead(InputFile file) {
}

@Override
public FeatureReader createReader() {
return new CityGMLReader(context);
public FeatureReader createReader(InputFile file, ReadOptions options) throws ReadException {
return new CityGMLReader(file, options, context);
}

@Override
public FeatureWriter createWriter() {
return new CityGMLWriter(context);
public FeatureWriter createWriter(OutputFile file, WriteOptions options) throws WriteException {
return new CityGMLWriter(file, options, context);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,20 @@
package org.citydb.io.citygml;

import org.citydb.core.file.InputFile;
import org.citydb.core.file.OutputFile;
import org.citydb.io.FileFormat;
import org.citydb.io.IOAdapter;
import org.citydb.io.IOAdapterException;
import org.citydb.io.citygml.reader.CityJSONReader;
import org.citydb.io.citygml.writer.CityJSONWriter;
import org.citydb.io.reader.FeatureReader;
import org.citydb.io.reader.ReadException;
import org.citydb.io.reader.ReadOptions;
import org.citydb.io.validator.ValidateException;
import org.citydb.io.validator.Validator;
import org.citydb.io.writer.FeatureWriter;
import org.citydb.io.writer.WriteException;
import org.citydb.io.writer.WriteOptions;
import org.citygml4j.cityjson.CityJSONContext;
import org.citygml4j.cityjson.CityJSONContextException;

Expand Down Expand Up @@ -77,13 +82,13 @@ public boolean canRead(InputFile file) {
}

@Override
public FeatureReader createReader() {
return new CityJSONReader(adapterContext, cityJSONContext);
public FeatureReader createReader(InputFile file, ReadOptions options) throws ReadException {
return new CityJSONReader(file, options, adapterContext, cityJSONContext);
}

@Override
public FeatureWriter createWriter() {
return new CityJSONWriter(adapterContext, cityJSONContext);
public FeatureWriter createWriter(OutputFile file, WriteOptions options) throws WriteException {
return new CityJSONWriter(file, options, adapterContext, cityJSONContext);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,32 +48,26 @@

public class CityGMLReader implements FeatureReader {
private final Logger logger = LoggerManager.getInstance().getLogger(CityGMLReader.class);
private final InputFile file;
private final ReadOptions options;
private final CityGMLAdapterContext context;
private final CityGMLReaderFactory factory;
private final CityGMLFormatOptions formatOptions;
private final PersistentMapStore store;

private InputFile file;
private ReadOptions options;
private CityGMLFormatOptions formatOptions;
private volatile boolean isPreprocessed;
private volatile boolean shouldRun = true;
private Preprocessor preprocessor;
private PersistentMapStore store;
private Throwable exception;

private volatile boolean isInitialized;
private volatile boolean shouldRun;

public CityGMLReader(CityGMLAdapterContext context) {
this.context = Objects.requireNonNull(context, "CityGML adapter context must not be null.");
factory = CityGMLReaderFactory.newInstance(context.getCityGMLContext());
}

@Override
public void initialize(InputFile file, ReadOptions options) throws ReadException {
public CityGMLReader(InputFile file, ReadOptions options, CityGMLAdapterContext context) throws ReadException {
this.file = Objects.requireNonNull(file, "The input file must not be null.");
this.options = Objects.requireNonNull(options, "The read options must not be null.");
factory.setReadOptions(options);
this.context = Objects.requireNonNull(context, "CityGML adapter context must not be null.");

try {
formatOptions = options.getFormatOptions().getOrElse(CityGMLFormatOptions.class, CityGMLFormatOptions::new);
formatOptions = options.getFormatOptions()
.getOrElse(CityGMLFormatOptions.class, CityGMLFormatOptions::new);
} catch (ConfigException e) {
throw new ReadException("Failed to get CityGML format options from config.", e);
}
Expand All @@ -87,6 +81,7 @@ public void initialize(InputFile file, ReadOptions options) throws ReadException
throw new ReadException("Failed to initialize local cache.", e);
}

factory = CityGMLReaderFactory.newInstance(context.getCityGMLContext(), options);
preprocessor = new Preprocessor()
.resolveGeometryReferences(formatOptions.isResolveGeometryReferences())
.resolveCrossLodReferences(formatOptions.isResolveCrossLodReferences())
Expand All @@ -95,18 +90,12 @@ public void initialize(InputFile file, ReadOptions options) throws ReadException
.mapLod0RoofEdge(formatOptions.isMapLod0RoofEdge())
.mapLod1MultiSurfaces(formatOptions.isMapLod1MultiSurfaces())
.setNumberOfThreads(options.getNumberOfThreads());

logger.debug("Reading global objects and resolving global references.");
preprocessor.processGlobalObjects(file, factory);

isInitialized = true;
shouldRun = true;
}

@Override
public void read(Consumer<Feature> consumer) throws ReadException {
if (!isInitialized) {
throw new ReadException("Illegal to read data when reader has not been initialized.");
if (!isPreprocessed) {
preprocess();
}

CityGMLInputFactory inputFactory = factory.createInputFactory();
Expand Down Expand Up @@ -178,21 +167,22 @@ private void process(AbstractFeature feature, Consumer<Feature> consumer, ModelB
}
}

private void preprocess() throws ReadException {
logger.debug("Reading global objects and resolving global references...");
preprocessor.processGlobalObjects(file, factory);
isPreprocessed = true;
}

@Override
public void cancel() {
shouldRun = false;
if (isInitialized) {
preprocessor.cancel();
}
preprocessor.cancel();
}

@Override
public void close() {
if (isInitialized) {
store.close();
preprocessor = null;
exception = null;
isInitialized = false;
}
store.close();
preprocessor = null;
exception = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,18 @@

public class CityGMLReaderFactory {
private final CityGMLContext context;
private final ReadOptions options;
private final String seed;
private ReadOptions options;

private CityGMLReaderFactory(CityGMLContext context) {
private CityGMLReaderFactory(CityGMLContext context, ReadOptions options) {
this.context = Objects.requireNonNull(context, "CityGML context must not be null.");
this.options = Objects.requireNonNull(options, "The read options must not be null.");
seed = "citydb-" + Long.toUnsignedString(new SecureRandom().nextLong() ^ System.currentTimeMillis());
TextContent.setZoneOffsetProvider(localDateTime -> ZoneOffset.UTC);
}

public static CityGMLReaderFactory newInstance(CityGMLContext context) {
return new CityGMLReaderFactory(context);
}

public CityGMLReaderFactory setReadOptions(ReadOptions options) {
this.options = options;
return this;
public static CityGMLReaderFactory newInstance(CityGMLContext context, ReadOptions options) {
return new CityGMLReaderFactory(context, options);
}

public CityGMLInputFactory createInputFactory() throws ReadException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,28 @@

public class CityJSONReader implements FeatureReader {
private final Logger logger = LoggerManager.getInstance().getLogger(CityJSONReader.class);
private final InputFile file;
private final ReadOptions options;
private final CityGMLAdapterContext adapterContext;
private final CityJSONContext cityJSONContext;
private final CityJSONReaderFactory factory;
private final PersistentMapStore store;

private InputFile file;
private ReadOptions options;
private CityJSONReaderFactory factory;
private PersistentMapStore store;
private volatile boolean shouldRun = true;
private Throwable exception;

private volatile boolean isInitialized;
private volatile boolean shouldRun;

public CityJSONReader(CityGMLAdapterContext adapterContext, CityJSONContext cityJSONContext) {
this.adapterContext = Objects.requireNonNull(adapterContext, "CityGML adapter context must not be null.");
this.cityJSONContext = Objects.requireNonNull(cityJSONContext, "CityJSON context must not be null.");
}

@Override
public void initialize(InputFile file, ReadOptions options) throws ReadException {
public CityJSONReader(InputFile file, ReadOptions options, CityGMLAdapterContext adapterContext, CityJSONContext cityJSONContext) throws ReadException {
this.file = Objects.requireNonNull(file, "The input file must not be null.");
this.options = Objects.requireNonNull(options, "The read options must not be null.");
this.adapterContext = Objects.requireNonNull(adapterContext, "CityGML adapter context must not be null.");
Objects.requireNonNull(cityJSONContext, "CityJSON context must not be null.");

CityJSONFormatOptions formatOptions;
try {
formatOptions = options.getFormatOptions()
.getOrElse(CityJSONFormatOptions.class, CityJSONFormatOptions::new);
} catch (ConfigException e) {
throw new ReadException("Failed to get CityJSON format options from config.", e);
}

try {
store = PersistentMapStore.builder()
Expand All @@ -77,27 +78,11 @@ public void initialize(InputFile file, ReadOptions options) throws ReadException
throw new ReadException("Failed to initialize local cache.", e);
}

CityJSONFormatOptions formatOptions;
try {
formatOptions = options.getFormatOptions().get(CityJSONFormatOptions.class);
} catch (ConfigException e) {
throw new ReadException("Failed to get CityJSON format options from config.", e);
}

factory = CityJSONReaderFactory.newInstance(cityJSONContext)
.setReadOptions(options)
.setFormatOptions(formatOptions);

isInitialized = true;
shouldRun = true;
factory = CityJSONReaderFactory.newInstance(cityJSONContext, options, formatOptions);
}

@Override
public void read(Consumer<Feature> consumer) throws ReadException {
if (!isInitialized) {
throw new ReadException("Illegal to read data when reader has not been initialized.");
}

ExecutorService service = ExecutorHelper.newFixedAndBlockingThreadPool(options.getNumberOfThreads() > 0 ?
options.getNumberOfThreads() :
Math.max(2, Runtime.getRuntime().availableProcessors()));
Expand Down Expand Up @@ -147,10 +132,7 @@ public void cancel() {

@Override
public void close() {
if (isInitialized) {
store.close();
exception = null;
isInitialized = false;
}
store.close();
exception = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,19 @@

public class CityJSONReaderFactory {
private final CityJSONContext context;
private final ReadOptions options;
private final CityJSONFormatOptions formatOptions;
private final String seed;
private ReadOptions options;
private CityJSONFormatOptions formatOptions = new CityJSONFormatOptions();

private CityJSONReaderFactory(CityJSONContext context) {
private CityJSONReaderFactory(CityJSONContext context, ReadOptions options, CityJSONFormatOptions formatOptions) {
this.context = Objects.requireNonNull(context, "CityJSON context must not be null.");
this.options = Objects.requireNonNull(options, "The read options must not be null.");
this.formatOptions = Objects.requireNonNull(formatOptions, "The format options must not be null.");
seed = "citydb-" + Long.toUnsignedString(new SecureRandom().nextLong() ^ System.currentTimeMillis());
}

public static CityJSONReaderFactory newInstance(CityJSONContext context) {
return new CityJSONReaderFactory(context);
}

public CityJSONReaderFactory setReadOptions(ReadOptions options) {
this.options = options;
return this;
}

public CityJSONReaderFactory setFormatOptions(CityJSONFormatOptions formatOptions) {
if (formatOptions != null) {
this.formatOptions = formatOptions;
}

return this;
public static CityJSONReaderFactory newInstance(CityJSONContext context, ReadOptions options, CityJSONFormatOptions formatOptions) {
return new CityJSONReaderFactory(context, options, formatOptions);
}

public CityJSONReader createReader(InputFile file) throws ReadException {
Expand Down
Loading

0 comments on commit 1556541

Please sign in to comment.