Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AER-2804 Added option to not add receptor hexagon representation in results in GML #301

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class GMLWriter {

private final AeriusGMLVersion version;
private Boolean formattedOutput = Boolean.TRUE;
private boolean withRepresentation = true;

public GMLWriter(final ReceptorGridSettings rgs, final ReferenceGenerator referenceGenerator) {
this(rgs, referenceGenerator, LATEST_WRITER_VERSION);
Expand All @@ -102,6 +103,13 @@ public void setFormattedOutput(final Boolean formattedOutput) {
this.formattedOutput = formattedOutput;
}

/**
* If called GML Receptors won't be generated with the hexagon representation geometry.
*/
public void setNoReceptorRepresentation() {
this.withRepresentation = false;
}

/**
* Get a map of the GML representation (String) for each {@link EmissionSourceFeature} object.
*
Expand Down Expand Up @@ -359,7 +367,7 @@ public void write(final OutputStream outputStream, final IsScenario scenario, fi
}

private InternalGMLWriter createInternalWriter() throws AeriusException {
return new InternalGMLWriter(receptorGridSettings, referenceGenerator, formattedOutput, version);
return new InternalGMLWriter(receptorGridSettings, referenceGenerator, formattedOutput, version, withRepresentation);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ final class InternalGMLWriter {
private final Boolean formattedOutput;

InternalGMLWriter(final ReceptorGridSettings rgs, final ReferenceGenerator referenceGenerator, final Boolean formattedOutput,
final AeriusGMLVersion version) throws AeriusException {
writer = GMLVersionWriterFactory.createGMLVersionWriter(rgs.getZoomLevel1(), GMLSchema.getSRSName(rgs.getEPSG().getSrid()), version);
final AeriusGMLVersion version, final boolean withRepresentation) throws AeriusException {
writer = GMLVersionWriterFactory.createGMLVersionWriter(rgs.getZoomLevel1(), GMLSchema.getSRSName(rgs.getEPSG().getSrid()), version,
withRepresentation);
this.referenceGenerator = referenceGenerator;
this.schema = GMLVersionWriterFactory.getSchema(version);
this.formattedOutput = formattedOutput;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@
import nl.overheid.aerius.shared.domain.geo.HexagonZoomLevel;
import nl.overheid.aerius.shared.exception.AeriusException;

public class GMLVersionWriterFactory {
public final class GMLVersionWriterFactory {

private GMLVersionWriterFactory() {
// Util class
}

public static GMLVersionWriter createGMLVersionWriter(final HexagonZoomLevel zoomLevel1, final String srsName,
final AeriusGMLVersion aeriusGMLVersion) {
switch (aeriusGMLVersion) {
case V5_1:
return new GMLVersionWriterV51(zoomLevel1, srsName);
case V6_0:
return new GMLVersionWriterV60(zoomLevel1, srsName);
default:
throw new IllegalArgumentException("Aerius GML version is not supported");
}
final AeriusGMLVersion aeriusGMLVersion, final boolean withRepresentation) {
return switch (aeriusGMLVersion) {
case V5_1 -> new GMLVersionWriterV51(zoomLevel1, srsName);
case V6_0 -> new GMLVersionWriterV60(zoomLevel1, srsName, withRepresentation);
default -> throw new IllegalArgumentException("Aerius GML version is not supported");
};
}

public static Schema getSchema(final AeriusGMLVersion aeriusGMLVersion) throws AeriusException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ public class GMLVersionWriterV60 implements GMLVersionWriter {
private final CIMLKMeasure2GML measure2gml;
private final CIMLKDispersionLine2GML dispersionLine2gml;

public GMLVersionWriterV60(final HexagonZoomLevel zoomLevel1, final String srsName) {
public GMLVersionWriterV60(final HexagonZoomLevel zoomLevel1, final String srsName, final boolean withRepresentation) {
geometry2gml = new Geometry2GML(srsName);
source2gml = new Source2GML(geometry2gml);
building2gml = new Building2GML(geometry2gml);
result2gml = new Result2GML(geometry2gml, zoomLevel1);
result2gml = new Result2GML(geometry2gml, zoomLevel1, withRepresentation);
measure2gml = new CIMLKMeasure2GML(geometry2gml);
dispersionLine2gml = new CIMLKDispersionLine2GML(geometry2gml);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ final class Result2GML {

private final Geometry2GML geometry2gml;
private final HexagonZoomLevel zoomLevel1;
private final boolean withRepresentation;

public Result2GML(final Geometry2GML geometry2gml, final HexagonZoomLevel zoomLevel1) {
public Result2GML(final Geometry2GML geometry2gml, final HexagonZoomLevel zoomLevel1, final boolean withRepresentation) {
this.geometry2gml = geometry2gml;
this.zoomLevel1 = zoomLevel1;
this.withRepresentation = withRepresentation;
}

/**
Expand Down Expand Up @@ -147,7 +149,7 @@ private List<EntityReferenceProperty> fromEntityReferences(final List<nl.overhei
return converted;
}

private EntityReference convert(final nl.overheid.aerius.shared.domain.v2.point.EntityReference entityReference) {
private static EntityReference convert(final nl.overheid.aerius.shared.domain.v2.point.EntityReference entityReference) {
final EntityReference gmlEntityReference = new EntityReference();
gmlEntityReference.setEntityType(entityReference.getEntityType().name());
gmlEntityReference.setCode(entityReference.getCode());
Expand All @@ -169,15 +171,15 @@ private static int compare(final CriticalLevelProperty o1, final CriticalLevelPr
return sort;
}

private CriticalLevel convert(final EmissionResultKey key, final Double value) {
private static CriticalLevel convert(final EmissionResultKey key, final Double value) {
final CriticalLevel criticalLevel = new CriticalLevel();
criticalLevel.setResultType(key.getEmissionResultType());
criticalLevel.setSubstance(key.getSubstance());
criticalLevel.setValue(value);
return criticalLevel;
}

private AbstractCalculationPoint fromCustomPoint(final nl.overheid.aerius.shared.domain.v2.point.CustomCalculationPoint aeriusPoint) {
private static AbstractCalculationPoint fromCustomPoint(final nl.overheid.aerius.shared.domain.v2.point.CustomCalculationPoint aeriusPoint) {
//treat as a custom calculation point
//The proper representation of a custompoint would be a circle with a surface of 1ha.
//Unclear at this point if this is required for GML and if it should be implemented by a GML polygon, arc or circle.
Expand All @@ -187,13 +189,13 @@ private AbstractCalculationPoint fromCustomPoint(final nl.overheid.aerius.shared
return returnPoint;
}

private void setCustomProperties(final nl.overheid.aerius.shared.domain.v2.point.CustomCalculationPoint aeriusPoint,
private static void setCustomProperties(final nl.overheid.aerius.shared.domain.v2.point.CustomCalculationPoint aeriusPoint,
final AbstractCalculationPoint returnPoint) {
returnPoint.setAssessmentCategory(aeriusPoint.getAssessmentCategory() == null ? null : aeriusPoint.getAssessmentCategory().name());
returnPoint.setHeight(aeriusPoint.getHeight());
}

private AbstractCalculationPoint fromSubPoint(final nl.overheid.aerius.shared.domain.v2.point.SubPoint aeriusPoint) {
private static AbstractCalculationPoint fromSubPoint(final nl.overheid.aerius.shared.domain.v2.point.SubPoint aeriusPoint) {
final SubPoint returnSubPoint = new SubPoint();
returnSubPoint.setSubPointId(aeriusPoint.getSubPointId());
returnSubPoint.setReceptorPointId(aeriusPoint.getReceptorId());
Expand All @@ -206,17 +208,30 @@ private AbstractCalculationPoint fromReceptorPoint(final nl.overheid.aerius.shar
throws AeriusException {
//treat as receptor point.
final ReceptorPoint returnReceptorPoint = new ReceptorPoint();

returnReceptorPoint.setReceptorPointId(aeriusPoint.getId());
returnReceptorPoint.setEdgeEffect(aeriusPoint.getEdgeEffect());
//receptor are represented by a hexagon.
final Geometry geometry = HexagonUtil.createHexagon(point, zoomLevel1);
if (geometry instanceof final nl.overheid.aerius.shared.domain.v2.geojson.Polygon polygon) {
returnReceptorPoint.setRepresentation(
geometry2gml.toXMLPolygon(polygon, new Polygon()));
}
setRepresentation(point, returnReceptorPoint);
return returnReceptorPoint;
}

/**
* Receptors are represented by a hexagon.
*
* @param point
* @param receptorPoint
* @throws AeriusException
*/
private void setRepresentation(final Point point, final ReceptorPoint receptorPoint) throws AeriusException {
if (withRepresentation) {
final Geometry geometry = HexagonUtil.createHexagon(point, zoomLevel1);

if (geometry instanceof final nl.overheid.aerius.shared.domain.v2.geojson.Polygon polygon) {
receptorPoint.setRepresentation(geometry2gml.toXMLPolygon(polygon, new Polygon()));
}
}
}

private static List<ResultProperty> getResults(final CalculationPoint aeriusPoint, final Substance[] substances) {
final List<Substance> substanceList = Arrays.asList(substances);
final List<ResultProperty> results = toResultProperties(aeriusPoint, substanceList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ private static MetaData getMetaData() throws AeriusException {
metaDataInput.getOptions().getRblCalculationOptions().setMonitorSrm2Year(MONITOR_SRM2_YEAR);
metaDataInput.setResultsIncluded(true);
final InternalGMLWriter writer = new InternalGMLWriter(gridSettings, GMLTestDomain.TEST_REFERENCE_GENERATOR, Boolean.TRUE,
GMLWriter.LATEST_WRITER_VERSION);
GMLWriter.LATEST_WRITER_VERSION, true);
return writer.getWriter().metaData2GML(metaDataInput);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class GMLWriterPerformanceTest {
@Test
void testConvertMetaData() throws IOException, AeriusException {
final InternalGMLWriter writer = new InternalGMLWriter(GMLTestDomain.getExampleGridSettings(), GMLTestDomain.TEST_REFERENCE_GENERATOR,
Boolean.TRUE, GMLWriter.LATEST_WRITER_VERSION);
Boolean.TRUE, GMLWriter.LATEST_WRITER_VERSION, true);

final int numberOfSources = 800000;
final List<EmissionSourceFeature> sourceFeatures = new ArrayList<>(numberOfSources);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -69,6 +70,7 @@ class GMLWriterTest {
private static final String RECEPTORS_CONCENTRATION_ONLY_FILE = "test_receptors_concentration_only";
private static final String RECEPTORS_EDGE_EFFECT_FILE = "test_receptors_edge_effect";
private static final String RECEPTORS_ALL_FILE = "test_receptors";
private static final Object RECEPTORS_NO_REPRESENTATION = "test_receptors_no_representation";
private static final String MIXED_FEATURES_FILE = "test_mixed_features";
private static final String PATH_CURRENT_VERSION = GMLWriter.LATEST_WRITER_VERSION.name().toLowerCase() + "/";

Expand Down Expand Up @@ -110,7 +112,7 @@ void testConvertInvalidSources() throws IOException, AeriusException {
final List<EmissionSourceFeature> sources1 = getExampleEmissionSources();
sources1.get(0).setGeometry(null);

final IllegalArgumentException e = assertThrows(
assertThrows(
IllegalArgumentException.class,
() -> getConversionResult(converter, sources1),
"Emissionsource not allowed to have no geometry.");
Expand Down Expand Up @@ -216,24 +218,32 @@ private List<EmissionSourceFeature> getExampleEmissionSources() {

private static Stream<Arguments> convertReceptorsData() {
return Stream.of(
Arguments.of(RECEPTORS_ALL_FILE, true, true, false),
Arguments.of(RECEPTORS_DEPOSITION_ONLY_FILE, true, false, false),
Arguments.of(RECEPTORS_CONCENTRATION_ONLY_FILE, false, true, false),
Arguments.of(RECEPTORS_EDGE_EFFECT_FILE, true, true, true));
Arguments.of(RECEPTORS_ALL_FILE, Set.of(ConvertReceptorsOptions.INCLUDE_DEPOSITION, ConvertReceptorsOptions.INCLUDE_CONCENTRATION)),
Arguments.of(RECEPTORS_DEPOSITION_ONLY_FILE, Set.of(ConvertReceptorsOptions.INCLUDE_DEPOSITION)),
Arguments.of(RECEPTORS_CONCENTRATION_ONLY_FILE, Set.of(ConvertReceptorsOptions.INCLUDE_CONCENTRATION)),
Arguments.of(RECEPTORS_EDGE_EFFECT_FILE, Set.of(ConvertReceptorsOptions.INCLUDE_DEPOSITION, ConvertReceptorsOptions.INCLUDE_CONCENTRATION,
ConvertReceptorsOptions.INCLUDE_OVERLAPPING)),
Arguments.of(RECEPTORS_NO_REPRESENTATION, Set.of(ConvertReceptorsOptions.INCLUDE_DEPOSITION, ConvertReceptorsOptions.INCLUDE_CONCENTRATION,
ConvertReceptorsOptions.NO_REPRESENTATION)));
}

@ParameterizedTest(name = "Testfile: {0}")
@MethodSource("convertReceptorsData")
void testConvertReceptors(final String receptorFile, final boolean includeDeposition, final boolean includeConcentration,
final boolean includeOverlapping) throws IOException, AeriusException {
final ArrayList<CalculationPointFeature> receptors = getExampleAeriusPoints(includeDeposition, includeConcentration, includeOverlapping);
void testConvertReceptors(final String receptorFile, final Set<ConvertReceptorsOptions> options) throws IOException, AeriusException {
final ArrayList<CalculationPointFeature> receptors = getExampleAeriusPoints(
ConvertReceptorsOptions.INCLUDE_DEPOSITION.in(options),
ConvertReceptorsOptions.INCLUDE_CONCENTRATION.in(options),
ConvertReceptorsOptions.INCLUDE_OVERLAPPING.in(options));
final MetaDataInput metaDataInput = getMetaDataInput(new ScenarioMetaData());
metaDataInput.setName(null);
metaDataInput.setReference(null);
metaDataInput.setSituationType(null);
metaDataInput.setResultsIncluded(true);
final GMLWriter writer = new GMLWriter(RECEPTOR_GRID_SETTINGS, GMLTestDomain.TEST_REFERENCE_GENERATOR);
String result;
if (ConvertReceptorsOptions.NO_REPRESENTATION.in(options)) {
writer.setNoReceptorRepresentation();
}
final String result;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
writer.writeAeriusPoints(bos, receptors, metaDataInput);
result = bos.toString(StandardCharsets.UTF_8.name());
Expand Down Expand Up @@ -387,4 +397,26 @@ private ScenarioMetaData getScenarioMetaData() {
return metaData;
}

private enum ConvertReceptorsOptions {
/**
* Include deposition results.
*/
INCLUDE_DEPOSITION,
/**
* Include concentration results.
*/
INCLUDE_CONCENTRATION,
/**
* Include edge effect results.
*/
INCLUDE_OVERLAPPING,
/**
* Don't include hexagon representation geometry.
*/
NO_REPRESENTATION;

public boolean in(final Set<ConvertReceptorsOptions> options) {
return options.contains(this);
}
}
}
Loading
Loading