Commit 95dc5a25 authored by Kai-Holger Brassel's avatar Kai-Holger Brassel
Browse files

New data type for fraction and new unit for CO₂ equivalent

parent b694749b
Pipeline #3886 failed with stage
in 2 minutes and 45 seconds
Showing with 128 additions and 18 deletions
+128 -18
...@@ -3,4 +3,10 @@ ...@@ -3,4 +3,10 @@
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="quantities" nsURI="https://www.hftstuttgart.de/quantities" nsPrefix="quant"> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="quantities" nsURI="https://www.hftstuttgart.de/quantities" nsPrefix="quant">
<eClassifiers xsi:type="ecore:EDataType" name="QuantityDouble" instanceClassName="de.hftstuttgart.cityunits.model.NullableQuantity"/> <eClassifiers xsi:type="ecore:EDataType" name="QuantityDouble" instanceClassName="de.hftstuttgart.cityunits.model.NullableQuantity"/>
<eClassifiers xsi:type="ecore:EDataType" name="QuantityLong" instanceClassName="de.hftstuttgart.cityunits.model.NullableQuantity"/> <eClassifiers xsi:type="ecore:EDataType" name="QuantityLong" instanceClassName="de.hftstuttgart.cityunits.model.NullableQuantity"/>
<eClassifiers xsi:type="ecore:EDataType" name="Fraction" instanceClassName="java.lang.Double">
<eAnnotations source="https:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="minInclusive" value="0.0"/>
<details key="maxInclusive" value="1.0"/>
</eAnnotations>
</eClassifiers>
</ecore:EPackage> </ecore:EPackage>
...@@ -20,31 +20,33 @@ import tech.units.indriya.unit.TransformedUnit; ...@@ -20,31 +20,33 @@ import tech.units.indriya.unit.TransformedUnit;
import tech.units.indriya.unit.UnitDimension; import tech.units.indriya.unit.UnitDimension;
import tech.units.indriya.unit.Units; import tech.units.indriya.unit.Units;
public class UrbanSimulationUnits extends AbstractSystemOfUnits public class UrbanSimulationUnits extends AbstractSystemOfUnits {
{
private static final UrbanSimulationUnits INSTANCE = new UrbanSimulationUnits(); private static final UrbanSimulationUnits INSTANCE = new UrbanSimulationUnits();
@Override @Override
public String getName() { public String getName() {
return getClass().getSimpleName(); return getClass().getSimpleName();
} }
public static final Unit<Dimensionless> CO2EQ = addUnit(AbstractUnit.ONE);
public static final Unit<Mass> TON = addUnit(Units.KILOGRAM.multiply(1000));
public static final Unit<Dimensionless> PARTS_PER_MILLION = addUnit(new TransformedUnit<>(AbstractUnit.ONE, public static final Unit<Dimensionless> PARTS_PER_MILLION = addUnit(new TransformedUnit<>(AbstractUnit.ONE,
MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.valueOf(1000000)))); MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.valueOf(1000000))));
public static final Unit<Dimensionless> DECIBEL = addUnit(AbstractUnit.ONE.transform( public static final Unit<Dimensionless> DECIBEL = addUnit(AbstractUnit.ONE.transform(
new LogConverter(10).inverse().concatenate(MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.TEN)))); new LogConverter(10).inverse().concatenate(MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.TEN))));
public static final Unit<Mass> TON = addUnit(Units.KILOGRAM.multiply(1000));
public static final Unit<Intensity> IRRADIANCE = addUnit( public static final Unit<Intensity> IRRADIANCE = addUnit(
new AlternateUnit<Intensity>(Units.WATT.divide(Units.SQUARE_METRE), "W/m2")); new AlternateUnit<Intensity>(Units.WATT.divide(Units.SQUARE_METRE), "W/m²"));
// To model costs I added monetary units quick and dirty as SI base units. According to JavaDoc of AbstractUnit, // To model costs I added monetary units quick and dirty as SI base units.
// monetary units should rather be implemented in an extra type hierarchy below ComparableUnit. // According to JavaDoc of AbstractUnit,
// monetary units should rather be implemented in an extra type hierarchy below
// ComparableUnit.
public final static Dimension MONEY_DIMENSION = UnitDimension.parse('M'); public final static Dimension MONEY_DIMENSION = UnitDimension.parse('M');
public final static Unit<Euro> EURO = new BaseUnit<Euro>("€", MONEY_DIMENSION); public final static Unit<Euro> EURO = new BaseUnit<Euro>("€", MONEY_DIMENSION);
public final static Unit<Dollar> DOLLAR = new BaseUnit<Dollar>("$", MONEY_DIMENSION); public final static Unit<Dollar> DOLLAR = new BaseUnit<Dollar>("$", MONEY_DIMENSION);
static { static {
SimpleUnitFormat.getInstance().label(CO2EQ, "CO₂eq");
SimpleUnitFormat.getInstance().label(TON, "t"); SimpleUnitFormat.getInstance().label(TON, "t");
SimpleUnitFormat.getInstance().label(DECIBEL, "dB"); SimpleUnitFormat.getInstance().label(DECIBEL, "dB");
SimpleUnitFormat.getInstance().label(PARTS_PER_MILLION, "ppm"); SimpleUnitFormat.getInstance().label(PARTS_PER_MILLION, "ppm");
...@@ -52,7 +54,6 @@ public class UrbanSimulationUnits extends AbstractSystemOfUnits ...@@ -52,7 +54,6 @@ public class UrbanSimulationUnits extends AbstractSystemOfUnits
SimpleUnitFormat.getInstance().label(DOLLAR, "$"); SimpleUnitFormat.getInstance().label(DOLLAR, "$");
} }
/** /**
* Returns the unique instance of this class. * Returns the unique instance of this class.
* *
......
...@@ -75,6 +75,17 @@ public interface QuantitiesPackage extends EPackage { ...@@ -75,6 +75,17 @@ public interface QuantitiesPackage extends EPackage {
int QUANTITY_LONG = 1; int QUANTITY_LONG = 1;
/**
* The meta object id for the '<em>Fraction</em>' data type.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see java.lang.Double
* @see de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesPackageImpl#getFraction()
* @generated
*/
int FRACTION = 2;
/** /**
* Returns the meta object for data type '{@link de.hftstuttgart.cityunits.model.NullableQuantity <em>Quantity Double</em>}'. * Returns the meta object for data type '{@link de.hftstuttgart.cityunits.model.NullableQuantity <em>Quantity Double</em>}'.
* <!-- begin-user-doc --> * <!-- begin-user-doc -->
...@@ -97,6 +108,18 @@ public interface QuantitiesPackage extends EPackage { ...@@ -97,6 +108,18 @@ public interface QuantitiesPackage extends EPackage {
*/ */
EDataType getQuantityLong(); EDataType getQuantityLong();
/**
* Returns the meta object for data type '{@link java.lang.Double <em>Fraction</em>}'.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @return the meta object for data type '<em>Fraction</em>'.
* @see java.lang.Double
* @model instanceClass="java.lang.Double"
* annotation="https:///org/eclipse/emf/ecore/util/ExtendedMetaData minInclusive='0.0' maxInclusive='1.0'"
* @generated
*/
EDataType getFraction();
/** /**
* Returns the factory that creates the instances of the model. * Returns the factory that creates the instances of the model.
* <!-- begin-user-doc --> * <!-- begin-user-doc -->
...@@ -140,6 +163,16 @@ public interface QuantitiesPackage extends EPackage { ...@@ -140,6 +163,16 @@ public interface QuantitiesPackage extends EPackage {
*/ */
EDataType QUANTITY_LONG = eINSTANCE.getQuantityLong(); EDataType QUANTITY_LONG = eINSTANCE.getQuantityLong();
/**
* The meta object literal for the '<em>Fraction</em>' data type.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see java.lang.Double
* @see de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesPackageImpl#getFraction()
* @generated
*/
EDataType FRACTION = eINSTANCE.getFraction();
} }
} //QuantitiesPackage } //QuantitiesPackage
...@@ -75,6 +75,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac ...@@ -75,6 +75,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
return createQuantityDoubleFromString(eDataType, initialValue); return createQuantityDoubleFromString(eDataType, initialValue);
case QuantitiesPackage.QUANTITY_LONG: case QuantitiesPackage.QUANTITY_LONG:
return createQuantityLongFromString(eDataType, initialValue); return createQuantityLongFromString(eDataType, initialValue);
case QuantitiesPackage.FRACTION:
return createFractionFromString(eDataType, initialValue);
default: default:
throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
} }
...@@ -92,6 +94,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac ...@@ -92,6 +94,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
return convertQuantityDoubleToString(eDataType, instanceValue); return convertQuantityDoubleToString(eDataType, instanceValue);
case QuantitiesPackage.QUANTITY_LONG: case QuantitiesPackage.QUANTITY_LONG:
return convertQuantityLongToString(eDataType, instanceValue); return convertQuantityLongToString(eDataType, instanceValue);
case QuantitiesPackage.FRACTION:
return convertFractionToString(eDataType, instanceValue);
default: default:
throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
} }
...@@ -169,6 +173,24 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac ...@@ -169,6 +173,24 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
return convertQuantityLong((NullableQuantity)instanceValue); return convertQuantityLong((NullableQuantity)instanceValue);
} }
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public Double createFractionFromString(EDataType eDataType, String initialValue) {
return (Double)super.createFromString(eDataType, initialValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String convertFractionToString(EDataType eDataType, Object instanceValue) {
return super.convertToString(eDataType, instanceValue);
}
/** /**
* <!-- begin-user-doc --> * <!-- begin-user-doc -->
* <!-- end-user-doc --> * <!-- end-user-doc -->
......
...@@ -32,6 +32,13 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac ...@@ -32,6 +32,13 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
*/ */
private EDataType quantityLongEDataType = null; private EDataType quantityLongEDataType = null;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
private EDataType fractionEDataType = null;
/** /**
* Creates an instance of the model <b>Package</b>, registered with * Creates an instance of the model <b>Package</b>, registered with
* {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
...@@ -113,6 +120,16 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac ...@@ -113,6 +120,16 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
return quantityLongEDataType; return quantityLongEDataType;
} }
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public EDataType getFraction() {
return fractionEDataType;
}
/** /**
* <!-- begin-user-doc --> * <!-- begin-user-doc -->
* <!-- end-user-doc --> * <!-- end-user-doc -->
...@@ -144,6 +161,7 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac ...@@ -144,6 +161,7 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
// Create data types // Create data types
quantityDoubleEDataType = createEDataType(QUANTITY_DOUBLE); quantityDoubleEDataType = createEDataType(QUANTITY_DOUBLE);
quantityLongEDataType = createEDataType(QUANTITY_LONG); quantityLongEDataType = createEDataType(QUANTITY_LONG);
fractionEDataType = createEDataType(FRACTION);
} }
/** /**
...@@ -172,9 +190,31 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac ...@@ -172,9 +190,31 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
// Initialize data types // Initialize data types
initEDataType(quantityDoubleEDataType, NullableQuantity.class, "QuantityDouble", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(quantityDoubleEDataType, NullableQuantity.class, "QuantityDouble", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
initEDataType(quantityLongEDataType, NullableQuantity.class, "QuantityLong", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); initEDataType(quantityLongEDataType, NullableQuantity.class, "QuantityLong", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
initEDataType(fractionEDataType, Double.class, "Fraction", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
// Create resource // Create resource
createResource(eNS_URI); createResource(eNS_URI);
// Create annotations
// https:///org/eclipse/emf/ecore/util/ExtendedMetaData
createExtendedMetaDataAnnotations();
}
/**
* Initializes the annotations for <b>https:///org/eclipse/emf/ecore/util/ExtendedMetaData</b>.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected void createExtendedMetaDataAnnotations() {
String source = "https:///org/eclipse/emf/ecore/util/ExtendedMetaData";
addAnnotation
(fractionEDataType,
source,
new String[] {
"minInclusive", "0.0",
"maxInclusive", "1.0"
});
} }
} //QuantitiesPackageImpl } //QuantitiesPackageImpl
package de.hftstuttgart.cityunits.tests; package de.hftstuttgart.cityunits.tests;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.*;
import java.util.Locale; import java.util.Locale;
import java.util.Locale.Category; import java.util.Locale.Category;
...@@ -9,6 +9,7 @@ import javax.measure.Quantity; ...@@ -9,6 +9,7 @@ import javax.measure.Quantity;
import javax.measure.Unit; import javax.measure.Unit;
import javax.measure.quantity.Area; import javax.measure.quantity.Area;
import javax.measure.quantity.Length; import javax.measure.quantity.Length;
import javax.measure.quantity.Mass;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -17,8 +18,7 @@ import tech.units.indriya.quantity.Quantities; ...@@ -17,8 +18,7 @@ import tech.units.indriya.quantity.Quantities;
import tech.units.indriya.unit.Units; import tech.units.indriya.unit.Units;
// Quantities.getQuantity("1.50 €"); does not compile in Maven without cast to String ??? // Quantities.getQuantity("1.50 €"); does not compile in Maven without cast to String ???
class QuantityTest class QuantityTest {
{
@BeforeAll @BeforeAll
static void init() { static void init() {
// Initialize additional units like metric ton, $ and € with their labels // Initialize additional units like metric ton, $ and € with their labels
...@@ -29,31 +29,31 @@ class QuantityTest ...@@ -29,31 +29,31 @@ class QuantityTest
@Test @Test
void testTemperature() { void testTemperature() {
Quantity<?> q = Quantities.getQuantity((String)"5 °C"); Quantity<?> q = Quantities.getQuantity((String) "5 °C");
assertEquals("[Θ]", q.getUnit().getDimension().toString(), "Wrong dimension!"); assertEquals("[Θ]", q.getUnit().getDimension().toString(), "Wrong dimension!");
assertEquals("278.15 K", q.toSystemUnit().toString(), "Wrong calculation of Celsius to Kelvin!"); assertEquals("278.15 K", q.toSystemUnit().toString(), "Wrong calculation of Celsius to Kelvin!");
} }
@Test @Test
void testMetreAndArea() { void testMetreAndArea() {
Unit<Area> sqm = Units.METRE.multiply(Units.METRE).asType(Area.class); Unit<Area> sqm = Units.METRE.multiply(Units.METRE).asType(Area.class);
Quantity<Length> line = Quantities.getQuantity(2, Units.METRE); Quantity<Length> line = Quantities.getQuantity(2, Units.METRE);
Quantity<Area> area = line.multiply(line).asType(Area.class); Quantity<Area> area = line.multiply(line).asType(Area.class);
assertEquals(sqm, area.getUnit(), "Wrong unit computation!"); assertEquals(sqm, area.getUnit(), "Wrong unit computation!");
assertEquals(4, area.getValue(), "Wrong calculation of area!"); assertEquals(4, area.getValue(), "Wrong calculation of area!");
} }
@Test @Test
void testUrbanSimulationUnitMoney() { void testUrbanSimulationUnitMoney() {
Quantity<?> cost = Quantities.getQuantity((String)"1.50 €"); Quantity<?> cost = Quantities.getQuantity((String) "1.50 €");
assertEquals(cost.getUnit(), UrbanSimulationUnits.EURO, "Wrong currency!"); assertEquals(cost.getUnit(), UrbanSimulationUnits.EURO, "Wrong currency!");
} }
@Test @Test
void testUrbanSimulationUnitPPMAndTon() { void testUrbanSimulationUnitPPMAndTon() {
Quantity<?> q = Quantities.getQuantity((String)"20 ppm").multiply(Quantities.getQuantity((String)"10 t")); Quantity<?> q = Quantities.getQuantity((String) "20 ppm").multiply(Quantities.getQuantity((String) "10 t"));
assertEquals("[M]", q.getUnit().getDimension().toString()); assertEquals("[M]", q.getUnit().getDimension().toString());
assertEquals(UrbanSimulationUnits.PARTS_PER_MILLION.multiply(UrbanSimulationUnits.TON), q.getUnit()); assertEquals(UrbanSimulationUnits.PARTS_PER_MILLION.multiply(UrbanSimulationUnits.TON), q.getUnit());
assertEquals(200, q.getValue()); assertEquals(200, q.getValue());
...@@ -61,9 +61,17 @@ class QuantityTest ...@@ -61,9 +61,17 @@ class QuantityTest
@Test @Test
void testkWhPerCubicMeter() { void testkWhPerCubicMeter() {
Quantity<?> q = Quantities.getQuantity((String)"5.2 kW*h/m³"); Quantity<?> q = Quantities.getQuantity((String) "5.2 kW*h/m³");
assertEquals("[M]/([L]·[T]²)", q.getUnit().getDimension().toString(), "Wrong dimension!"); assertEquals("[M]/([L]·[T]²)", q.getUnit().getDimension().toString(), "Wrong dimension!");
assertEquals("18720000 W·s/m³", q.toSystemUnit().toString()); assertEquals("18720000 W·s/m³", q.toSystemUnit().toString());
} }
@Test
void testCO2eq() {
Quantity<Mass> q = Quantities.getQuantity("5200.5 kg·CO₂eq").asType(Mass.class);
assertEquals("[M]", q.getUnit().getDimension().toString(), "Wrong dimension!");
assertTrue(q.isEquivalentTo(Quantities.getQuantity("5.2005 t·CO₂eq").asType(Mass.class)),
"Wrong conversion from kg of CO₂eq to ton of CO₂eq!");
}
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment