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

Entities #9

Open
wants to merge 146 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
8d144ee
[feat] adding Datastream entity skeleton
Alystrasz Oct 27, 2021
cc76320
[feat] adding Datastream constructor
Alystrasz Oct 27, 2021
aed9017
[refactor] ObservationType enumeration holds all possible Datastream.…
Alystrasz Oct 27, 2021
bf92c83
[refactor] UnitOfMeasurement interface types Datastream.unitOfMeasure…
Alystrasz Oct 27, 2021
ab1261d
[feat] adding Datastream DAO class
Alystrasz Oct 27, 2021
12f913d
Merge branch 'master' into feat/entities
Alystrasz Oct 27, 2021
da29860
[fix] DatastreamDao implements BaseDao.buildEntity member
Alystrasz Oct 28, 2021
fda7e2b
[test] Datastream should throw when created with wrong phenomenon time
Alystrasz Oct 28, 2021
a493975
[test] Datastream should throw when created with wrong result time
Alystrasz Oct 28, 2021
18c1998
[feat] Datastream throws when created with wrong time range values
Alystrasz Oct 28, 2021
a00e24a
[test] Datastream should throw when created with random string as fir…
Alystrasz Oct 28, 2021
fff8005
[test] Datastream should throw when created with random string as sec…
Alystrasz Oct 28, 2021
292d002
[test] Datastream should throw when created with random strings as bo…
Alystrasz Oct 28, 2021
325f8f0
[test] Datastream should throw when created with too many phenomenon …
Alystrasz Oct 28, 2021
83909ff
[test] adjusting awaited error messages in Datastream build tests
Alystrasz Oct 28, 2021
04d671d
[feat] Datastream cannot be built with falsy time range values
Alystrasz Oct 28, 2021
986d400
[feat] adding ObservedProperty class skeleton
Alystrasz Oct 28, 2021
7571b11
[feat] ObservedProperty builder can create entity instances
Alystrasz Oct 28, 2021
e6dd021
[test] ObservedPropertyBuilder should not build ObservedProperty with…
Alystrasz Oct 28, 2021
ac143f6
[test] ObservedPropertyBuilder should not build ObservedProperty with…
Alystrasz Oct 28, 2021
c07d060
[test] ObservedPropertyBuilder should not build ObservedProperty with…
Alystrasz Oct 28, 2021
5c11148
[feat] adding ObservedProperty DAO class
Alystrasz Oct 28, 2021
5196615
[feat] datastreams and observed properties DAOs are accessible from s…
Alystrasz Oct 28, 2021
da3cdbf
[feat] ObservedProperty now have datastreams list attribute
Alystrasz Oct 28, 2021
d2c5b92
[feat] Thing now have datastreams list attribute
Alystrasz Oct 28, 2021
70045cb
[docs] adding specification links to all entities
Alystrasz Oct 28, 2021
9adcda2
[feat] Datastream have things list attribute
Alystrasz Oct 28, 2021
e91dfc2
[feat] Datastream have observedProperties list attribute
Alystrasz Oct 28, 2021
465e4a6
[feat] adding FeatureOfInterest entity skeleton
Alystrasz Nov 4, 2021
09cdbeb
[refactor] FeatureOfInterest.feature is of Geometry type
Alystrasz Nov 4, 2021
a6c939b
[feat] adding FeatureOfInterest DAO class
Alystrasz Nov 4, 2021
b6c5c43
[feat] FeatureOfInterest DAO is accessible through service instance
Alystrasz Nov 4, 2021
54aef70
[test] FeatureOfInterest DAO should return some public attributes
Alystrasz Nov 4, 2021
29f40cf
[test] resetting service instance before each DAO test
Alystrasz Nov 4, 2021
eaeedf2
[test] adding mock API response for FeaturesOfInterest
Alystrasz Nov 4, 2021
d7ba5d6
[test] DAO should build feature of interest (point) from API response
Alystrasz Nov 4, 2021
d4de8b8
[fix] FeatureOfInterest.feature has GeoJSON.Feature type
Alystrasz Nov 4, 2021
7873815
[test] DAO should build feature of interest (with feature collection)…
Alystrasz Nov 4, 2021
2f5f25d
[feat] FeatureOfInterestBuilder class can build FeatureOfInterest ins…
Alystrasz Nov 4, 2021
a3e2be8
[test] FeatureOfInterest builder should not build instance without name
Alystrasz Nov 4, 2021
ea32dd5
[feat] FeatureOfInterestBuilder.setFeatureFromCoordinates creates fea…
Alystrasz Nov 4, 2021
07f2555
[test] FeatureOfInterest builder should not build instance without de…
Alystrasz Nov 4, 2021
7079ed7
[test] FeatureOfInterest builder should not build instance without fe…
Alystrasz Nov 4, 2021
be7a486
[test] FeatureOfInterest builder should build instance with point fea…
Alystrasz Nov 4, 2021
9b8b149
[test] FeatureOfInterest builder should build instance with polygon f…
Alystrasz Nov 4, 2021
cb2e932
[refactor] lint
Alystrasz Nov 4, 2021
453d9fb
[refactor] removing rest operator from FeatureOfInterestBuilder.setFe…
Alystrasz Nov 4, 2021
db08c5c
[feat] FeatureOfInterestBuilder should build instance with feature pr…
Alystrasz Nov 4, 2021
2f1512c
[refactor] FeatureOfInterest and Location entities share encodingType…
Alystrasz Nov 4, 2021
96bc98a
[feat] adding Observation entity skeleton
Alystrasz Nov 4, 2021
ad348d6
[fix] locationEncodingType has been renamed to encodingType
Alystrasz Nov 4, 2021
b2b7760
[refactor] exporting Datastream time ranges checks into dedicated class
Alystrasz Nov 4, 2021
cd20679
[test] exporting time range related tests to dedicated tests file
Alystrasz Nov 4, 2021
d3e9b19
[feat] checking Observation time ranges with TimeChecks class
Alystrasz Nov 4, 2021
4b41d02
[refactor] renaming TimeChecks class to TimeChecker
Alystrasz Nov 5, 2021
dbe02af
[refactor] TimeChecker.checkTimeRange returns a boolean
Alystrasz Nov 5, 2021
05c4247
[chore] adding iso-datestring-validator dependency
Alystrasz Nov 5, 2021
5180368
[feat] TimeChecker can verify ISO-8601 dates
Alystrasz Nov 5, 2021
f01117f
[refactor] rewriting TimeChecker.checkTimeRange using TimeChecker.che…
Alystrasz Nov 5, 2021
8993da8
[docs] TimeChecker class is documented
Alystrasz Nov 5, 2021
59daab8
[feat] HistoricalLocation uses TimeChecker to verify its time attribute
Alystrasz Nov 5, 2021
f38c432
[fix] calendar date format (YYYY-MM) complies with ISO-8601 norm
Alystrasz Nov 5, 2021
4763b87
[test] TimeChecker.checkISODate should return true with YYYY-MM-DD ca…
Alystrasz Nov 5, 2021
63f9cb5
[fix] YYYY-MM-DD date format complies with ISO-8601 norm
Alystrasz Nov 5, 2021
2fb4301
[test] should create an Observation instance with a date as phenomeno…
Alystrasz Nov 5, 2021
e0beda3
[test] should create an Observation instance with a time interval as …
Alystrasz Nov 5, 2021
7ea9b6a
[refactor] lint
Alystrasz Nov 5, 2021
3d8aa50
[test] should create an Observation instance with a resultTime
Alystrasz Nov 5, 2021
8a542a9
[test] building an Observation should throw with a random string as r…
Alystrasz Nov 5, 2021
cbc8dbd
[feat] Observation.resultTime attribute is sanitized with TimeChecker…
Alystrasz Nov 5, 2021
51a04ff
[feat] adding ObservationDao class skeleton
Alystrasz Nov 5, 2021
64a4a44
[test] Observation DAO should return public attributes
Alystrasz Nov 5, 2021
77591a4
[test] adding Observation API mock responses
Alystrasz Nov 5, 2021
eae97fd
[test] Observation DAO should build instance from API response
Alystrasz Nov 5, 2021
4d08539
[fix] Observation resultQuality, validTime and parameters attributes …
Alystrasz Nov 5, 2021
813fbe6
[test] Observation instance should be created without resultQuality, …
Alystrasz Nov 5, 2021
3dd8fbf
[feat] Observation resultQuality, validTime and parameters are option…
Alystrasz Nov 5, 2021
8c0e508
[chore] adding coverage report command
Alystrasz Nov 5, 2021
ee4ec49
[test] DatastreamDao should return correct path name
Alystrasz Nov 5, 2021
34b7bd7
[test] FeatureOfInterestDao should return correct path name
Alystrasz Nov 5, 2021
b92dfe0
[test] HistoricalLocationDao should return correct path name
Alystrasz Nov 5, 2021
a7eb680
[test] LocationDao should return correct path name
Alystrasz Nov 5, 2021
d39f8dd
[test] ObservationDao should return correct path name
Alystrasz Nov 5, 2021
fd57cc0
[test] ObservedPropertyDao should return correct path name
Alystrasz Nov 5, 2021
ed77774
[refactor] lint
Alystrasz Nov 5, 2021
5c8f4a0
[test] Datastream DAO should return public attributes
Alystrasz Nov 5, 2021
3aa0c87
[test] adding Datastream API mock responses
Alystrasz Nov 5, 2021
241435b
[test] Datastream DAO should build instance from API response
Alystrasz Nov 5, 2021
64ee7a3
[feat] Datastream observedArea, phenomenonTime and resultTime attribu…
Alystrasz Nov 5, 2021
66a15a6
[test] Datastream should throw when created with empty phenomenon time
Alystrasz Nov 5, 2021
9d6221a
[fix] Datastream instance cannot be created with empty phenomenonTime…
Alystrasz Nov 5, 2021
b1750c7
[test] Datastream should throw when created with empty result time
Alystrasz Nov 5, 2021
ef84d96
[fix] Observation resultQuality, validTime and parameters attributes …
Alystrasz Nov 5, 2021
67c2bf4
[chore] excluding test folder from test coverage
Alystrasz Nov 5, 2021
0ceeb8a
[feat] adding ObservationBuilder class skeleton
Alystrasz Dec 16, 2021
0576fe6
[test] Observation builder should build an instance with all parameters
Alystrasz Dec 16, 2021
4594a80
[feat] ObservationBuilder can build entities
Alystrasz Dec 16, 2021
171d33b
[test] ObservationBuilder should not build an instance without phenom…
Alystrasz Dec 16, 2021
f8cd534
[test] ObservationBuilder should not build an instance without result
Alystrasz Dec 16, 2021
f645a7f
[test] ObservationBuilder should not build an instance without result…
Alystrasz Dec 16, 2021
d93cca2
[feat] ObservationBuilder throws when a required argument is missing
Alystrasz Dec 16, 2021
1c5bd0f
[test] ObservationBuilder should build an instance with mandatory par…
Alystrasz Dec 16, 2021
dae0493
[fix] some Observation properties may be undefined
Alystrasz Dec 16, 2021
e4de3d7
[fix] some Datastream properties may be undefined
Alystrasz Dec 16, 2021
babadc6
[feat] Observation entity has Datastreams list
Alystrasz Dec 16, 2021
9131dd1
[feat] Observation entity has FeaturesOfInterest list
Alystrasz Dec 16, 2021
f5e50a4
[docs] adding documentation to Observation entity
Alystrasz Dec 16, 2021
9d137a6
[fix] Observation.resultTime is an optional parameter
Alystrasz Dec 17, 2021
0e389e6
[fix] Observation.phenomenonTime is an optional parameter
Alystrasz Dec 17, 2021
81ea164
[feat] service holds a ObservationDao reference
Alystrasz Dec 17, 2021
153fd10
[feat] FeatureOfInterest has Observations list attribute
Alystrasz Dec 17, 2021
2296716
[feat] adding documentation to FeatureOfInterest entity
Alystrasz Dec 17, 2021
547f29d
[feat] adding documentation to Thing entity
Alystrasz Dec 17, 2021
955947e
[feat] adding documentation to Datastream entity
Alystrasz Dec 17, 2021
aef956d
[feat] adding documentation to HistoricalLocation entity
Alystrasz Dec 17, 2021
e1e5047
[feat] adding documentation to Location entity
Alystrasz Dec 17, 2021
1728a80
[feat] adding documentation to Observation entity
Alystrasz Dec 17, 2021
e88444f
[feat] adding documentation to ObservedProperty entity
Alystrasz Dec 17, 2021
b9b9a58
[feat] adding Sensor entity class skeleton
Alystrasz Dec 17, 2021
73c740e
[refactor] moving Sensor entity to dao/model package
Alystrasz Dec 20, 2021
6366848
[feat] Sensor has Datastreams list attribute
Alystrasz Dec 20, 2021
656bc88
[feat] adding SensorDao class skeleton
Alystrasz Dec 21, 2021
8d9f72f
[test] SensorDao should return correct path name
Alystrasz Dec 21, 2021
35aa976
[test] SensorDao should return public attributes
Alystrasz Dec 21, 2021
056b47c
[feat] adding SensorDao.entityPublicAttributes implementation
Alystrasz Dec 21, 2021
e229e79
[test] SensorDao should build instance from API response
Alystrasz Dec 21, 2021
676b7f6
[feat] adding Sensor missing attributes (encodingType and metadata)
Alystrasz Jan 10, 2022
937e77c
[feat] service holds sensor DAO reference
Alystrasz Jan 10, 2022
90be2b5
[feat] Sensor.dao returns an instance of SensorDao
Alystrasz Jan 10, 2022
12f916c
[feat] SensorDao can build Sensors through buildEntity method
Alystrasz Jan 10, 2022
2d9585a
[feat] adding SensorBuilder class skeleton
Alystrasz Jan 10, 2022
5eb9b7b
[test] SensorBuilder should build an instance with all parameters
Alystrasz Jan 10, 2022
dba7dd1
[feat] SensorBuilder can build Sensor instance
Alystrasz Jan 10, 2022
3cb6c52
[test] SensorBuilder should not build instance without name
Alystrasz Jan 10, 2022
e53fa87
[test] SensorBuilder should not build instance without description
Alystrasz Jan 10, 2022
836cf02
[test] SensorBuilder should not build instance without encodingType
Alystrasz Jan 10, 2022
9f70c30
[test] SensorBuilder should not build instance without metadata
Alystrasz Jan 10, 2022
0f1712f
[fix] SensorBuilder throws if a required attribute is not given
Alystrasz Jan 10, 2022
2819de3
[feat] Datastream entity has Observations list
Alystrasz Jan 10, 2022
8c13367
[feat] Datastream entity has Sensors list
Alystrasz Jan 10, 2022
a5b5cf3
[test] Datastream should be created with no unit of measurement
Alystrasz Jan 10, 2022
4564728
[fix] Datastream.unitOfMeasurement can be null
Alystrasz Jan 10, 2022
7e2deb2
[test] Datastream should not be created with unit.name === null
Alystrasz Jan 10, 2022
d8b7eea
[test] Datastream should not be created with unit.definition === null
Alystrasz Jan 10, 2022
5fc584b
[test] Datastream should not be created with unit.symbol === null
Alystrasz Jan 10, 2022
fd273cf
[fix] unitOfMeasurement must have all of its properties either define…
Alystrasz Jan 10, 2022
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
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ We tested the library against following backends:

#### Location encoding type

If you want to run this library against a backend only supporting `'application/vnd.geo+json'` encoding for Location entities, you can
specify it in your service declaration:
If you want to run this library against a backend only supporting `'application/vnd.geo+json'` encoding for FeatureOfInterest/Location entities, you can specify it in your service declaration:

```typescript
const service = new SensorThingsService(
'https://example.org',
{ locationEncodingType: 'application/vnd.geo+json' }
{ encodingType: 'application/vnd.geo+json' }
);
```
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverageFrom: ['src/**/*.ts','!test/**']
};
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint src/ --ext .js,.jsx,.ts,.tsx --fix",
"test": "jest",
"test:coverage": "npx jest --coverage",
"test:integration": "npx ts-node test/integration.ts",
"clean": "rm -rf dist build package",
"ts-node": "ts-node",
Expand Down Expand Up @@ -47,7 +48,8 @@
},
"dependencies": {
"@turf/helpers": "^6.5.0",
"axios": "^0.22.0"
"axios": "^0.22.0",
"iso-datestring-validator": "^2.2.0"
},
"size-limit": [
{
Expand Down
26 changes: 26 additions & 0 deletions src/dao/DatastreamDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {BaseDao} from "./BaseDao";
import {Datastream} from "../model/Datastream";
import {UnitOfMeasurement} from "../model/utils/UnitOfMeasurement";
import {ObservationType} from "../model/utils/ObservationType";
import {Polygon} from "@turf/helpers";

export class DatastreamDao extends BaseDao<Datastream> {
buildEntity(data: Record<string, unknown>): Datastream {
return new Datastream(
this._service,
data.name as string,
data.description as string,
data.unitOfMeasurement as UnitOfMeasurement,
data.observationType as ObservationType,
data.observedArea as Polygon,
data.phenomenonTime as string,
data.resultTime as string
);
}
get entityPathname(): string {
return "Datastreams";
}
get entityPublicAttributes(): string[] {
return ['name', 'description', 'unitOfMeasurement', 'observationType', 'observedArea', 'phenomenonTime', 'resultTime'];
}
}
20 changes: 20 additions & 0 deletions src/dao/FeatureOfInterestDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Feature } from "@turf/helpers";
import { FeatureOfInterest } from "../model/FeatureOfInterest";
import { BaseDao } from "./BaseDao";

export class FeatureOfInterestDao extends BaseDao<FeatureOfInterest> {
get entityPathname(): string {
return 'FeaturesOfInterest';
}
get entityPublicAttributes(): string[] {
return ['name', 'description', 'encodingType', 'feature'];
}
buildEntity(data: Record<string, unknown>): FeatureOfInterest {
return new FeatureOfInterest(
this._service,
data.name as string,
data.description as string,
data.feature as Feature
)
}
}
22 changes: 22 additions & 0 deletions src/dao/ObservationDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Observation } from "../model/Observation";
import { BaseDao } from "./BaseDao";

export class ObservationDao extends BaseDao<Observation> {
get entityPathname(): string {
return 'Observations';
}
get entityPublicAttributes(): string[] {
return ['phenomenonTime', 'result', 'resultTime', 'resultQuality', 'validTime', 'parameters'];
}
buildEntity(data: Record<string, unknown>): Observation {
return new Observation(
this._service,
data.phenomenonTime as string,
data.result as unknown,
data.resultTime as string,
data.resultQuality as unknown,
data.validTime as string,
data.parameters as Record<string, unknown>
);
}
}
19 changes: 19 additions & 0 deletions src/dao/ObservedPropertyDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {BaseDao} from "./BaseDao";
import {ObservedProperty} from "../model/ObservedProperty";

export class ObservedPropertyDao extends BaseDao<ObservedProperty> {
buildEntity(data: Record<string, unknown>): ObservedProperty {
return new ObservedProperty(
this._service,
data.name as string,
data.definition as string,
data.description as string
);
}
get entityPathname(): string {
return "ObservedProperties";
}
get entityPublicAttributes(): string[] {
return ['name', 'description', 'definition'];
}
}
20 changes: 20 additions & 0 deletions src/dao/SensorDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Sensor } from "../model/Sensor";
import { BaseDao } from "./BaseDao";

export class SensorDao extends BaseDao<Sensor> {
get entityPathname(): string {
return 'Sensors';
}
get entityPublicAttributes(): string[] {
return ['name', 'description', 'encodingType', 'metadata'];
}
buildEntity(data: Record<string, unknown>): Sensor {
return new Sensor(
this._service,
data.name as string,
data.description as string,
data.encodingType as string,
data.metadata as string
);
}
}
121 changes: 121 additions & 0 deletions src/model/Datastream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {Entity} from "./Entity";
import {BaseDao} from "../dao/BaseDao";
import {Polygon} from "@turf/helpers";
import {SensorThingsService} from "../service/SensorThingsService";
import {ObservationType} from "./utils/ObservationType";
import {UnitOfMeasurement} from "./utils/UnitOfMeasurement";
import {DatastreamDao} from "../dao/DatastreamDao";
import {DatastreamThingsList} from "./list/DatastreamThingsList";
import {DatastreamObservedPropertiesList} from "./list/DatastreamObservedPropertiesList";
import { TimeChecker } from "./utils/TimeChecker";
import {DatastreamObservationsList} from "./list/DatastreamObservationsList";
import {DatastreamSensorsList} from "./list/DatastreamSensorsList";

/**
* A Datastream groups a collection of Observations measuring the same ObservedProperty and produced by the same Sensor.
*
* http://docs.opengeospatial.org/is/15-078r6/15-078r6.html#28
*/
export class Datastream extends Entity<Datastream> {
/**
* A property provides a label for Datastream entity, commonly a descriptive name.
*/
public name: string;

/**
* The description of the Datastream entity.
*/
public description: string;

/**
* A JSON Object containing three key-value pairs. The name property presents the full name of the unitOfMeasurement;
* the symbol property shows the textual form of the unit symbol; and the definition contains the URI defining the
* unitOfMeasurement.
* The values of these properties SHOULD follow the Unified Code for Unit of Measure (UCUM).
*/
public unitOfMeasurement: UnitOfMeasurement;

/**
* The type of Observation (with unique result type), which is used by the service to encode observations.
*/
public observationType: ObservationType;

/**
* The spatial bounding box of the spatial extent of all FeaturesOfInterest that belong to the Observations
* associated with this Datastream.
*/
public observedArea: Polygon | undefined;

/**
* The temporal interval of the phenomenon times of all observations belonging to this Datastream.
*/
public phenomenonTime: string | undefined;

/**
* The temporal interval of the result times of all observations belonging to this Datastream.
*/
public resultTime: string | undefined;


/**
* A Thing has zero-to-many Datastreams. A Datastream entity SHALL only link to a Thing as a collection of Observations.
*/
public things: DatastreamThingsList;

/**
* The Observations in a Datastream are performed by one-and-only-one Sensor. One Sensor MAY produce zero-to-many
* Observations in different Datastreams.
*/
public sensors: DatastreamSensorsList;

/**
* The Observations of a Datastream SHALL observe the same ObservedProperty. The Observations of different Datastreams
* MAY observe the same ObservedProperty.
*/
public observedProperties: DatastreamObservedPropertiesList;

/**
* A Datastream has zero-to-many Observations. One Observation SHALL occur in one-and-only-one Datastream.
*/
public observations: DatastreamObservationsList;

constructor(
service: SensorThingsService, name: string, description: string,
unitOfMeasurement: UnitOfMeasurement | null,
observationType: ObservationType,
observedArea: Polygon | undefined = undefined,
phenomenonTime: string | undefined = undefined,
resultTime: string | undefined = undefined
) {
super(service);
this.name = name;
this.description = description;

this.unitOfMeasurement = unitOfMeasurement ?? {
name: null,
symbol: null,
definition: null
};
if (![0, 3].includes(Object.values(this.unitOfMeasurement).filter(v => v === null).length))
throw new RangeError('unitOfMeasurement must have all of its properties either defined or null.');

this.observationType = observationType;
this.observedArea = observedArea;
this.things = new DatastreamThingsList(this, this._service);
this.sensors = new DatastreamSensorsList(this, this._service);
this.observedProperties = new DatastreamObservedPropertiesList(this, this._service);
this.observations = new DatastreamObservationsList(this, this._service);

const checker = new TimeChecker();
if (phenomenonTime !== undefined && !checker.checkTimeRange(phenomenonTime))
throw new RangeError(`"${phenomenonTime}" is not a valid phenomenonTime value.`);
this.phenomenonTime = phenomenonTime;
if (resultTime !== undefined && !checker.checkTimeRange(resultTime))
throw new RangeError(`"${resultTime}" is not a valid resultTime value.`);
this.resultTime = resultTime;
}

get dao(): BaseDao<Datastream> {
return new DatastreamDao(this._service);
}
}
63 changes: 63 additions & 0 deletions src/model/FeatureOfInterest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Feature } from "@turf/helpers";
import { SensorThingsService } from "..";
import { BaseDao } from "../dao/BaseDao";
import { FeatureOfInterestDao } from "../dao/FeatureOfInterestDao";
import { Entity } from "./Entity";
import { FeatureOfInterestObservationsList } from "./list/FeatureOfInterestObservationsList";

/**
* An Observation results in a value being assigned to a phenomenon. The phenomenon is a property of a feature,
* the latter being the FeatureOfInterest of the Observation [OGC and ISO 19156:2011].
*
* In the context of the Internet of Things, many Observations’ FeatureOfInterest can be the Location of the Thing.
* For example, the FeatureOfInterest of a wifi-connect thermostat can be the Location of the thermostat (i.e., the
* living room where the thermostat is located in). In the case of remote sensing, the FeatureOfInterest can be the
* geographical area or volume that is being sensed.
*
* http://docs.opengeospatial.org/is/15-078r6/15-078r6.html#32
*/
export class FeatureOfInterest extends Entity<FeatureOfInterest> {
/**
* A property provides a label for FeatureOfInterest entity, commonly a descriptive name.
*/
public name: string;

/**
* The description about the FeatureOfInterest.
*/
public description: string;

/**
* The encoding type of the feature property.
*/
public readonly encodingType: string;

/**
* The detailed description of the feature.
*/
public feature: Feature;


/**
* An Observation observes on one-and-only-one FeatureOfInterest. One FeatureOfInterest could be observed by zero-to-many Observations.
*/
public observations: FeatureOfInterestObservationsList;

constructor(
service: SensorThingsService,
name: string,
description: string,
feature: Feature
) {
super(service);
this.name = name;
this.description = description;
this.encodingType = this._service.compatibility.encodingType;
this.feature = feature;
this.observations = new FeatureOfInterestObservationsList(this, this._service);
}

get dao(): BaseDao<FeatureOfInterest> {
return new FeatureOfInterestDao(this._service);
}
}
24 changes: 20 additions & 4 deletions src/model/HistoricalLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,36 @@ import { SensorThingsService } from "../service/SensorThingsService";
import { Entity } from "./Entity";
import { HistoricalLocationLocationsList } from "./list/HistoricalLocationLocationsList";
import { HistoricalLocationThingsList } from "./list/HistoricalLocationThingsList";
import { TimeChecker } from "./utils/TimeChecker";

/**
* A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and previous locations of the Thing.
*
* https://docs.opengeospatial.org/is/15-078r6/15-078r6.html#27
*/
export class HistoricalLocation extends Entity<HistoricalLocation> {
/**
* The time when the Thing is known at the Location.
*/
public time: string;


/**
* A HistoricalLocation has one-and-only-one Thing. One Thing MAY have zero-to-many HistoricalLocations.
*/
public things: HistoricalLocationThingsList;

/**
* A Location can have zero-to-many HistoricalLocations. One HistoricalLocation SHALL have one or many Locations.
*/
public locations: HistoricalLocationLocationsList;

constructor(service: SensorThingsService, time: string) {
super(service);
try {
this.time = new Date(time).toISOString();
} catch (err) {
if (!new TimeChecker().checkISODate(time))
throw new RangeError(`"${time}" is not a valid time value.`);
}
this.time = time;

this.things = new HistoricalLocationThingsList(this, this._service);
this.locations = new HistoricalLocationLocationsList(this, this._service);
}
Expand Down
Loading