diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..d73e2c36
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,71 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ master, cedeql ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ master, cedeql ]
+ schedule:
+ - cron: '29 6 * * 2'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'csharp' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
+ # Learn more:
+ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d2f0c24..87f3b233 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
-## [1.0.0](https://github.com/Terradue/DotNetStac/compare/1.0.0-rc.4...1.0.0)
+## [1.1.0](https://github.com/Terradue/DotNetStac/compare/1.0.0...1.1.0)
+
+### Merged
+
+- Code QL analysis [`#9`](https://github.com/Terradue/DotNetStac/pull/9)
+
+### Commits
+
+- Stac Items clone functions [`6f37ac4`](https://github.com/Terradue/DotNetStac/commit/6f37ac4c5d9af6139bd3773a868fb83d492d2091)
+- tests order [`ceb7ad5`](https://github.com/Terradue/DotNetStac/commit/ceb7ad514c793f22f70a70ae99d4c63ec38fc52d)
+- Create codeql-analysis.yml [`d3890fe`](https://github.com/Terradue/DotNetStac/commit/d3890fee3f829f1ea27e0e61d6cfffca80cacb68)
+- do not load schema at extension load [`8b3884b`](https://github.com/Terradue/DotNetStac/commit/8b3884b0c7060e437950f98df7e951bca36a8a93)
+- GetCollection [`d94457d`](https://github.com/Terradue/DotNetStac/commit/d94457da52d2084d2ce5ede79c9764d4243b8a71)
+- more formatting [`77c0722`](https://github.com/Terradue/DotNetStac/commit/77c07227a2e1a8c983814c2206fb4f8e95618a71)
+- removed profile [`b40f4e0`](https://github.com/Terradue/DotNetStac/commit/b40f4e0d967720296bb852aab6803214343d990b)
+- moved in workflow folder [`baf822b`](https://github.com/Terradue/DotNetStac/commit/baf822be0cc188ce49f8a68735b7e8d0ea725313)
+- cedeql [`ed83c03`](https://github.com/Terradue/DotNetStac/commit/ed83c0347ed2f5540b8e69606f4e4354d3b4f2fa)
+
+## [1.0.0](https://github.com/Terradue/DotNetStac/compare/1.0.0-rc.4...1.0.0) - 2021-06-07
### Commits
@@ -35,12 +53,21 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- convertible array [`b0386b6`](https://github.com/Terradue/DotNetStac/commit/b0386b621f91aa5a6cc1a35cdc7f8dbe7d3400a3)
-## [1.0.0-rc.1](https://github.com/Terradue/DotNetStac/compare/0.9.1...1.0.0-rc.1) - 2021-05-26
+## [1.0.0-1](https://github.com/Terradue/DotNetStac/compare/0.9.1...1.0.0-1) - 2021-06-07
### Commits
+- do not load schema at extension load [`8b3884b`](https://github.com/Terradue/DotNetStac/commit/8b3884b0c7060e437950f98df7e951bca36a8a93)
+- SATC 1.0.0! [`fddd916`](https://github.com/Terradue/DotNetStac/commit/fddd9169bd51063c2f23034fffbc43c920409bb1)
+- format checking [`f7c1bd1`](https://github.com/Terradue/DotNetStac/commit/f7c1bd1e39c0b3156c89bc268189b27d4cd6127d)
+- fixed version extension [`820f5e0`](https://github.com/Terradue/DotNetStac/commit/820f5e011f2952da0f850a3cbc669874264b5d23)
- stac 1.0.0! [`e083b45`](https://github.com/Terradue/DotNetStac/commit/e083b45feea591604133013814ccba8c7215b060)
- API home page [`fddef27`](https://github.com/Terradue/DotNetStac/commit/fddef27b6a91c431c3d3bfd658d5f267baebff67)
+- more coverage for eo extension [`ab73316`](https://github.com/Terradue/DotNetStac/commit/ab733160535d44c4df85b18ebce63f69ff436d1a)
+- cloud cover nullable [`246f536`](https://github.com/Terradue/DotNetStac/commit/246f5367df481cdd88ea2a0b7ea27de11a404cef)
+- fixes for assets [`c9fe721`](https://github.com/Terradue/DotNetStac/commit/c9fe721657f1750abccf1ee85f27c2255bd46046)
+- convertible array [`b0386b6`](https://github.com/Terradue/DotNetStac/commit/b0386b621f91aa5a6cc1a35cdc7f8dbe7d3400a3)
+- linting [`38a998b`](https://github.com/Terradue/DotNetStac/commit/38a998ba12970bf8a3353c40c14c842d721f0a1f)
## [0.9.1](https://github.com/Terradue/DotNetStac/compare/0.9.0...0.9.1) - 2021-05-26
diff --git a/README.md b/README.md
index 798090cd..3371d96f 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,9 @@
-![Build Status](https://github.com/Terradue/DotNetStac/actions/workflows/build.yaml/badge.svg?branch=hotfix/1.0.0-1)
+![Build Status](https://github.com/Terradue/DotNetStac/actions/workflows/build.yaml/badge.svg?branch=release/1.1.0)
[![NuGet](https://img.shields.io/nuget/vpre/DotNetStac)](https://www.nuget.org/packages/DotNetStac/)
-[![codecov](https://codecov.io/gh/Terradue/DotNetStac/branch/hotfix/1.0.0-1/graph/badge.svg)](https://codecov.io/gh/Terradue/DotNetStac)
+[![codecov](https://codecov.io/gh/Terradue/DotNetStac/branch/release/1.1.0/graph/badge.svg)](https://codecov.io/gh/Terradue/DotNetStac)
[![Gitter](https://img.shields.io/gitter/room/SpatioTemporal-Asset-Catalog/Lobby?color=yellow)](https://gitter.im/SpatioTemporal-Asset-Catalog/Lobby)
[![License](https://img.shields.io/badge/license-AGPL3-blue.svg)](LICENSE)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Terradue/DotNetStac/master?filepath=example.ipynb)
diff --git a/src/DotNetStac.Test/Catalog/CatalogTests.cs b/src/DotNetStac.Test/Catalog/CatalogTests.cs
index 34cc01ac..249aebfd 100644
--- a/src/DotNetStac.Test/Catalog/CatalogTests.cs
+++ b/src/DotNetStac.Test/Catalog/CatalogTests.cs
@@ -67,5 +67,26 @@ public void CatalogStacObjectLink()
StacObjectLink stacObjectLink = (StacObjectLink)StacLink.CreateObjectLink(simpleCollection, new Uri("file:///test"));
}
+ [Fact]
+ public void CatalogClone()
+ {
+ var simpleJson = GetJson("Catalog", "CanDeserializeMinimalSample");
+ ValidateJson(simpleJson);
+ StacCatalog simpleCollection = StacConvert.Deserialize(simpleJson);
+ StacCatalog simpleCollectionClone = new StacCatalog(simpleCollection);
+
+ var clonedJson = JsonConvert.SerializeObject(simpleCollectionClone);
+ ValidateJson(clonedJson);
+
+ JsonAssert.AreEqual(simpleJson, clonedJson);
+
+ simpleCollectionClone = (StacCatalog)simpleCollection.Clone();
+
+ clonedJson = JsonConvert.SerializeObject(simpleCollectionClone);
+ ValidateJson(clonedJson);
+
+ JsonAssert.AreEqual(simpleJson, clonedJson);
+ }
+
}
}
diff --git a/src/DotNetStac.Test/Collection/CollectionTests.cs b/src/DotNetStac.Test/Collection/CollectionTests.cs
index 4b31e11c..f9adcbd2 100644
--- a/src/DotNetStac.Test/Collection/CollectionTests.cs
+++ b/src/DotNetStac.Test/Collection/CollectionTests.cs
@@ -237,7 +237,26 @@ public void CollectionStacObjectLink()
StacObjectLink stacObjectLink = (StacObjectLink)StacLink.CreateObjectLink(simpleCollection, new Uri("file:///test"));
}
+ [Fact]
+ public void CollectionClone()
+ {
+ var simpleJson = GetJson("Collection");
+ ValidateJson(simpleJson);
+ StacCollection simpleCollection = StacConvert.Deserialize(simpleJson);
+ StacCollection simpleCollectionClone = new StacCollection(simpleCollection);
+
+ var clonedJson = StacConvert.Serialize(simpleCollectionClone);
+ ValidateJson(clonedJson);
+ JsonAssert.AreEqual(simpleJson, clonedJson);
+
+ simpleCollectionClone = (StacCollection)simpleCollection.Clone();
+
+ clonedJson = StacConvert.Serialize(simpleCollectionClone);
+ ValidateJson(clonedJson);
+
+ JsonAssert.AreEqual(simpleJson, clonedJson);
+ }
}
}
diff --git a/src/DotNetStac.Test/Item/ItemTests.cs b/src/DotNetStac.Test/Item/ItemTests.cs
index a49ac4d0..621a1a18 100644
--- a/src/DotNetStac.Test/Item/ItemTests.cs
+++ b/src/DotNetStac.Test/Item/ItemTests.cs
@@ -299,5 +299,27 @@ public void Geometry()
// extent = StacGeometryHelpers.GetBoundingBox(gcollection);
// Assert.Equal(extentCheck.First().ToArray(), extent);
}
+
+ [Fact]
+ public void ItemClone()
+ {
+ var simpleJson = GetJson("Item", "ItemCloneIn");
+ ValidateJson(simpleJson);
+ StacItem simpleItem = StacConvert.Deserialize(simpleJson);
+ StacItem simpleItemClone = new StacItem(simpleItem);
+
+ var clonedJson = StacConvert.Serialize(simpleItemClone);
+ ValidateJson(clonedJson);
+
+ var expectedJson = GetJson("Item");
+ JsonAssert.AreEqual(simpleJson, expectedJson);
+
+ simpleItemClone = (StacItem)simpleItem.Clone();
+
+ clonedJson = StacConvert.Serialize(simpleItemClone);
+ ValidateJson(clonedJson);
+
+ JsonAssert.AreEqual(simpleJson, expectedJson);
+ }
}
}
diff --git a/src/DotNetStac.Test/JsonAssert.cs b/src/DotNetStac.Test/JsonAssert.cs
index 72457784..d76c41a7 100644
--- a/src/DotNetStac.Test/JsonAssert.cs
+++ b/src/DotNetStac.Test/JsonAssert.cs
@@ -1,4 +1,7 @@
-using System.Linq;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xunit;
@@ -25,16 +28,27 @@ public static void AreEqual(string expectJson, string actualJson)
JsonConvert.SerializeObject(JObject.Parse(expectJson).SortProperties(),
new JsonSerializerSettings
{
- DateTimeZoneHandling = DateTimeZoneHandling.Utc
+ DateTimeZoneHandling = DateTimeZoneHandling.Utc,
+ Culture = CultureInfo.CreateSpecificCulture("en-US"),
+ Converters = GetConverters()
}),
JsonConvert.SerializeObject(JObject.Parse(actualJson).SortProperties(),
new JsonSerializerSettings
{
- DateTimeZoneHandling = DateTimeZoneHandling.Utc
+ DateTimeZoneHandling = DateTimeZoneHandling.Utc,
+ Culture = CultureInfo.CreateSpecificCulture("en-US"),
+ Converters = GetConverters()
})
);
}
+ private static IList GetConverters()
+ {
+ return new List()
+ {
+ };
+ }
+
///
/// Asserts that contains
///
diff --git a/src/DotNetStac.Test/Resources/Collection/CollectionTests_CollectionClone.json b/src/DotNetStac.Test/Resources/Collection/CollectionTests_CollectionClone.json
new file mode 100644
index 00000000..838f129d
--- /dev/null
+++ b/src/DotNetStac.Test/Resources/Collection/CollectionTests_CollectionClone.json
@@ -0,0 +1,147 @@
+{
+ "stac_version": "1.0.0",
+ "type": "Collection",
+ "id": "COPERNICUS/S2",
+ "title": "Sentinel-2 MSI: MultiSpectral Instrument, Level-1C",
+ "description": "Sentinel-2 is a wide-swath, high-resolution, multi-spectral\nimaging mission supporting Copernicus Land Monitoring studies,\nincluding the monitoring of vegetation, soil and water cover,\nas well as observation of inland waterways and coastal areas.\n\nThe Sentinel-2 data contain 13 UINT16 spectral bands representing\nTOA reflectance scaled by 10000. See the [Sentinel-2 User Handbook](https://sentinel.esa.int/documents/247904/685211/Sentinel-2_User_Handbook)\nfor details. In addition, three QA bands are present where one\n(QA60) is a bitmask band with cloud mask information. For more\ndetails, [see the full explanation of how cloud masks are computed.](https://sentinel.esa.int/web/sentinel/technical-guides/sentinel-2-msi/level-1c/cloud-masks)\n\nEach Sentinel-2 product (zip archive) may contain multiple\ngranules. Each granule becomes a separate Earth Engine asset.\nEE asset ids for Sentinel-2 assets have the following format:\nCOPERNICUS/S2/20151128T002653_20151128T102149_T56MNN. Here the\nfirst numeric part represents the sensing date and time, the\nsecond numeric part represents the product generation date and\ntime, and the final 6-character string is a unique granule identifier\nindicating its UTM grid reference (see [MGRS](https://en.wikipedia.org/wiki/Military_Grid_Reference_System)).\n\nFor more details on Sentinel-2 radiometric resoltuon, [see this page](https://earth.esa.int/web/sentinel/user-guides/sentinel-2-msi/resolutions/radiometric).\n",
+ "license": "proprietary",
+ "keywords": [
+ "copernicus",
+ "esa",
+ "eu",
+ "msi",
+ "radiance",
+ "sentinel"
+ ],
+ "providers": [
+ {
+ "name": "European Union/ESA/Copernicus",
+ "roles": [
+ "producer",
+ "licensor"
+ ],
+ "url": "https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi"
+ }
+ ],
+ "extent": {
+ "spatial": {
+ "bbox": [
+ [
+ -180.0,
+ -56.0,
+ 180.0,
+ 83.0
+ ]
+ ]
+ },
+ "temporal": {
+ "interval": [
+ [
+ "2015-06-23T00:00:00Z",
+ null
+ ]
+ ]
+ }
+ },
+ "summaries": {
+ "datetime": {
+ "minimum": "2015-06-23T00:00:00Z",
+ "maximum": "2019-07-10T13:44:56Z"
+ },
+ "platform": ["sentinel-2a","sentinel-2b"],
+ "constellation": ["sentinel-2"],
+ "instruments": ["msi"],
+ "view:off_nadir": {
+ "minimum": 0.0,
+ "maximum": 100
+ },
+ "view:sun_elevation": {
+ "minimum": 6.78,
+ "maximum": 89.9
+ },
+ "sci:citation": ["Copernicus Sentinel data [Year]"],
+ "gsd": [10,30,60],
+ "proj:epsg": [32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,32660],
+ "eo:bands": [
+ {
+ "name": "B1",
+ "common_name": "coastal",
+ "center_wavelength": 4.439
+ },
+ {
+ "name": "B2",
+ "common_name": "blue",
+ "center_wavelength": 4.966
+ },
+ {
+ "name": "B3",
+ "common_name": "green",
+ "center_wavelength": 5.6
+ },
+ {
+ "name": "B4",
+ "common_name": "red",
+ "center_wavelength": 6.645
+ },
+ {
+ "name": "B5",
+ "center_wavelength": 7.039
+ },
+ {
+ "name": "B6",
+ "center_wavelength": 7.402
+ },
+ {
+ "name": "B7",
+ "center_wavelength": 7.825
+ },
+ {
+ "name": "B8",
+ "common_name": "nir",
+ "center_wavelength": 8.351
+ },
+ {
+ "name": "B8A",
+ "center_wavelength": 8.648
+ },
+ {
+ "name": "B9",
+ "center_wavelength": 9.45
+ },
+ {
+ "name": "B10",
+ "center_wavelength": 1.3735
+ },
+ {
+ "name": "B11",
+ "common_name": "swir16",
+ "center_wavelength": 1.6137
+ },
+ {
+ "name": "B12",
+ "common_name": "swir22",
+ "center_wavelength": 2.2024
+ }
+ ]
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "https://storage.cloud.google.com/earthengine-test/catalog/COPERNICUS_S2.json"
+ },
+ {
+ "rel": "parent",
+ "href": "https://storage.cloud.google.com/earthengine-test/catalog/catalog.json"
+ },
+ {
+ "rel": "root",
+ "href": "https://storage.cloud.google.com/earthengine-test/catalog/catalog.json"
+ },
+ {
+ "rel": "license",
+ "href": "https://scihub.copernicus.eu/twiki/pub/SciHubWebPortal/TermsConditions/Sentinel_Data_Terms_and_Conditions.pdf",
+ "title": "Legal notice on the use of Copernicus Sentinel Data and Service Information"
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/src/DotNetStac.Test/Resources/Item/ItemTests_ItemClone.json b/src/DotNetStac.Test/Resources/Item/ItemTests_ItemClone.json
new file mode 100644
index 00000000..5ce267bb
--- /dev/null
+++ b/src/DotNetStac.Test/Resources/Item/ItemTests_ItemClone.json
@@ -0,0 +1,662 @@
+{
+ "type": "Feature",
+ "stac_version": "1.0.0",
+ "stac_extensions": [
+ "https://stac-extensions.github.io/eo/v1.0.0/schema.json",
+ "https://stac-extensions.github.io/projection/v1.0.0/schema.json",
+ "https://stac-extensions.github.io/sat/v1.0.0/schema.json"
+ ],
+ "id": "S2A_30VWN_20200830_0_L2A",
+ "bbox": [
+ -3.000355032202007,
+ 60.33378967715628,
+ -0.9494552273687494,
+ 61.33443350563737
+ ],
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -1.0115813842949837,
+ 60.33378967715628
+ ],
+ [
+ -3.000344266875852,
+ 60.34865379793714
+ ],
+ [
+ -3.000355032202007,
+ 61.33443350563737
+ ],
+ [
+ -0.9494552273687494,
+ 61.31895930227699
+ ],
+ [
+ -1.0115813842949837,
+ 60.33378967715628
+ ]
+ ]
+ ]
+ },
+ "properties": {
+ "datetime": "2020-08-30T11:34:28Z",
+ "platform": "sentinel-2a",
+ "constellation": "sentinel-2",
+ "instruments": [
+ "msi"
+ ],
+ "gsd": 10,
+ "view:off_nadir": 0,
+ "proj:epsg": 32630,
+ "sat:relative_orbit": 80,
+ "sentinel:utm_zone": 30,
+ "sentinel:latitude_band": "V",
+ "sentinel:grid_square": "WN",
+ "sentinel:sequence": "0",
+ "sentinel:product_id": "S2A_MSIL2A_20200830T113321_N0214_R080_T30VWN_20200830T121958",
+ "sentinel:data_coverage": 100,
+ "eo:cloud_cover": 0,
+ "sentinel:valid_cloud_cover": false,
+ "created": "2020-08-31T09:57:42.772Z",
+ "updated": "2020-08-31T09:57:42.772Z"
+ },
+ "collection": "sentinel-s2-l2a-cogs",
+ "assets": {
+ "thumbnail": {
+ "title": "Thumbnail",
+ "type": "image/png",
+ "roles": [
+ "thumbnail"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l1c/tiles/30/V/WN/2020/8/30/0/preview.jpg"
+ },
+ "overview": {
+ "title": "True color image",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "overview"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ },
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ },
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/L2A_PVI.tif",
+ "proj:shape": [
+ 343,
+ 343
+ ],
+ "proj:transform": [
+ 320,
+ 0,
+ 499980,
+ 0,
+ -320,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "info": {
+ "title": "Original JSON metadata",
+ "type": "application/json",
+ "roles": [
+ "metadata"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/WN/2020/8/30/0/tileInfo.json"
+ },
+ "metadata": {
+ "title": "Original XML metadata",
+ "type": "application/xml",
+ "roles": [
+ "metadata"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/WN/2020/8/30/0/metadata.xml"
+ },
+ "visual": {
+ "title": "True color image",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "overview"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ },
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ },
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/TCI.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B01": {
+ "title": "Band 1 (coastal)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 60,
+ "eo:bands": [
+ {
+ "name": "B01",
+ "common_name": "coastal",
+ "center_wavelength": 0.4439,
+ "full_width_half_max": 0.027
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B01.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B02": {
+ "title": "Band 2 (blue)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B02.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B03": {
+ "title": "Band 3 (green)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B03.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B04": {
+ "title": "Band 4 (red)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B04.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B05": {
+ "title": "Band 5",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B05",
+ "center_wavelength": 0.7039,
+ "full_width_half_max": 0.019
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B05.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B06": {
+ "title": "Band 6",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B06",
+ "center_wavelength": 0.7402,
+ "full_width_half_max": 0.018
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B06.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B07": {
+ "title": "Band 7",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B07",
+ "center_wavelength": 0.7825,
+ "full_width_half_max": 0.028
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B07.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B08": {
+ "title": "Band 8 (nir)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B08",
+ "common_name": "nir",
+ "center_wavelength": 0.8351,
+ "full_width_half_max": 0.145
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B08.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B8A": {
+ "title": "Band 8A",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B8A",
+ "center_wavelength": 0.8648,
+ "full_width_half_max": 0.033
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B8A.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B09": {
+ "title": "Band 9",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 60,
+ "eo:bands": [
+ {
+ "name": "B09",
+ "center_wavelength": 0.945,
+ "full_width_half_max": 0.026
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B09.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B11": {
+ "title": "Band 11 (swir16)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B11",
+ "common_name": "swir16",
+ "center_wavelength": 1.6137,
+ "full_width_half_max": 0.143
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B11.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B12": {
+ "title": "Band 12 (swir22)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B12",
+ "common_name": "swir22",
+ "center_wavelength": 2.22024,
+ "full_width_half_max": 0.242
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B12.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "AOT": {
+ "title": "Aerosol Optical Thickness (AOT)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/AOT.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "WVP": {
+ "title": "Water Vapour (WVP)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/WVP.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "SCL": {
+ "title": "Scene Classification Map (SCL)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/SCL.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ }
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs/items/S2A_30VWN_20200830_0_L2A"
+ },
+ {
+ "rel": "canonical",
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "rel": "canonical",
+ "href": "https://cirrus-v0-data-1qm7gekzjucbq.s3.us-west-2.amazonaws.com/sentinel-s2-l2a/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "title": "Source STAC Item",
+ "rel": "derived_from",
+ "href": "https://cirrus-v0-data-1qm7gekzjucbq.s3.us-west-2.amazonaws.com/sentinel-s2-l2a/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "rel": "parent",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs"
+ },
+ {
+ "rel": "collection",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs"
+ },
+ {
+ "rel": "root",
+ "href": "https://earth-search.aws.element84.com/v0/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/DotNetStac.Test/Resources/Item/ItemTests_ItemCloneIn.json b/src/DotNetStac.Test/Resources/Item/ItemTests_ItemCloneIn.json
new file mode 100644
index 00000000..5ce267bb
--- /dev/null
+++ b/src/DotNetStac.Test/Resources/Item/ItemTests_ItemCloneIn.json
@@ -0,0 +1,662 @@
+{
+ "type": "Feature",
+ "stac_version": "1.0.0",
+ "stac_extensions": [
+ "https://stac-extensions.github.io/eo/v1.0.0/schema.json",
+ "https://stac-extensions.github.io/projection/v1.0.0/schema.json",
+ "https://stac-extensions.github.io/sat/v1.0.0/schema.json"
+ ],
+ "id": "S2A_30VWN_20200830_0_L2A",
+ "bbox": [
+ -3.000355032202007,
+ 60.33378967715628,
+ -0.9494552273687494,
+ 61.33443350563737
+ ],
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -1.0115813842949837,
+ 60.33378967715628
+ ],
+ [
+ -3.000344266875852,
+ 60.34865379793714
+ ],
+ [
+ -3.000355032202007,
+ 61.33443350563737
+ ],
+ [
+ -0.9494552273687494,
+ 61.31895930227699
+ ],
+ [
+ -1.0115813842949837,
+ 60.33378967715628
+ ]
+ ]
+ ]
+ },
+ "properties": {
+ "datetime": "2020-08-30T11:34:28Z",
+ "platform": "sentinel-2a",
+ "constellation": "sentinel-2",
+ "instruments": [
+ "msi"
+ ],
+ "gsd": 10,
+ "view:off_nadir": 0,
+ "proj:epsg": 32630,
+ "sat:relative_orbit": 80,
+ "sentinel:utm_zone": 30,
+ "sentinel:latitude_band": "V",
+ "sentinel:grid_square": "WN",
+ "sentinel:sequence": "0",
+ "sentinel:product_id": "S2A_MSIL2A_20200830T113321_N0214_R080_T30VWN_20200830T121958",
+ "sentinel:data_coverage": 100,
+ "eo:cloud_cover": 0,
+ "sentinel:valid_cloud_cover": false,
+ "created": "2020-08-31T09:57:42.772Z",
+ "updated": "2020-08-31T09:57:42.772Z"
+ },
+ "collection": "sentinel-s2-l2a-cogs",
+ "assets": {
+ "thumbnail": {
+ "title": "Thumbnail",
+ "type": "image/png",
+ "roles": [
+ "thumbnail"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l1c/tiles/30/V/WN/2020/8/30/0/preview.jpg"
+ },
+ "overview": {
+ "title": "True color image",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "overview"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ },
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ },
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/L2A_PVI.tif",
+ "proj:shape": [
+ 343,
+ 343
+ ],
+ "proj:transform": [
+ 320,
+ 0,
+ 499980,
+ 0,
+ -320,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "info": {
+ "title": "Original JSON metadata",
+ "type": "application/json",
+ "roles": [
+ "metadata"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/WN/2020/8/30/0/tileInfo.json"
+ },
+ "metadata": {
+ "title": "Original XML metadata",
+ "type": "application/xml",
+ "roles": [
+ "metadata"
+ ],
+ "href": "https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/WN/2020/8/30/0/metadata.xml"
+ },
+ "visual": {
+ "title": "True color image",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "overview"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ },
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ },
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/TCI.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B01": {
+ "title": "Band 1 (coastal)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 60,
+ "eo:bands": [
+ {
+ "name": "B01",
+ "common_name": "coastal",
+ "center_wavelength": 0.4439,
+ "full_width_half_max": 0.027
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B01.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B02": {
+ "title": "Band 2 (blue)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B02",
+ "common_name": "blue",
+ "center_wavelength": 0.4966,
+ "full_width_half_max": 0.098
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B02.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B03": {
+ "title": "Band 3 (green)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B03",
+ "common_name": "green",
+ "center_wavelength": 0.56,
+ "full_width_half_max": 0.045
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B03.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B04": {
+ "title": "Band 4 (red)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B04",
+ "common_name": "red",
+ "center_wavelength": 0.6645,
+ "full_width_half_max": 0.038
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B04.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B05": {
+ "title": "Band 5",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B05",
+ "center_wavelength": 0.7039,
+ "full_width_half_max": 0.019
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B05.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B06": {
+ "title": "Band 6",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B06",
+ "center_wavelength": 0.7402,
+ "full_width_half_max": 0.018
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B06.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B07": {
+ "title": "Band 7",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B07",
+ "center_wavelength": 0.7825,
+ "full_width_half_max": 0.028
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B07.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B08": {
+ "title": "Band 8 (nir)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 10,
+ "eo:bands": [
+ {
+ "name": "B08",
+ "common_name": "nir",
+ "center_wavelength": 0.8351,
+ "full_width_half_max": 0.145
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B08.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B8A": {
+ "title": "Band 8A",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B8A",
+ "center_wavelength": 0.8648,
+ "full_width_half_max": 0.033
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B8A.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B09": {
+ "title": "Band 9",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 60,
+ "eo:bands": [
+ {
+ "name": "B09",
+ "center_wavelength": 0.945,
+ "full_width_half_max": 0.026
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B09.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B11": {
+ "title": "Band 11 (swir16)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B11",
+ "common_name": "swir16",
+ "center_wavelength": 1.6137,
+ "full_width_half_max": 0.143
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B11.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "B12": {
+ "title": "Band 12 (swir22)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "gsd": 20,
+ "eo:bands": [
+ {
+ "name": "B12",
+ "common_name": "swir22",
+ "center_wavelength": 2.22024,
+ "full_width_half_max": 0.242
+ }
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/B12.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "AOT": {
+ "title": "Aerosol Optical Thickness (AOT)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/AOT.tif",
+ "proj:shape": [
+ 1830,
+ 1830
+ ],
+ "proj:transform": [
+ 60,
+ 0,
+ 499980,
+ 0,
+ -60,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "WVP": {
+ "title": "Water Vapour (WVP)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/WVP.tif",
+ "proj:shape": [
+ 10980,
+ 10980
+ ],
+ "proj:transform": [
+ 10,
+ 0,
+ 499980,
+ 0,
+ -10,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ },
+ "SCL": {
+ "title": "Scene Classification Map (SCL)",
+ "type": "image/tiff; application=geotiff; profile=cloud-optimized",
+ "roles": [
+ "data"
+ ],
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/SCL.tif",
+ "proj:shape": [
+ 5490,
+ 5490
+ ],
+ "proj:transform": [
+ 20,
+ 0,
+ 499980,
+ 0,
+ -20,
+ 6800040,
+ 0,
+ 0,
+ 1
+ ]
+ }
+ },
+ "links": [
+ {
+ "rel": "self",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs/items/S2A_30VWN_20200830_0_L2A"
+ },
+ {
+ "rel": "canonical",
+ "href": "https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "rel": "canonical",
+ "href": "https://cirrus-v0-data-1qm7gekzjucbq.s3.us-west-2.amazonaws.com/sentinel-s2-l2a/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "title": "Source STAC Item",
+ "rel": "derived_from",
+ "href": "https://cirrus-v0-data-1qm7gekzjucbq.s3.us-west-2.amazonaws.com/sentinel-s2-l2a/30/V/WN/2020/8/S2A_30VWN_20200830_0_L2A/S2A_30VWN_20200830_0_L2A.json",
+ "type": "application/json"
+ },
+ {
+ "rel": "parent",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs"
+ },
+ {
+ "rel": "collection",
+ "href": "https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs"
+ },
+ {
+ "rel": "root",
+ "href": "https://earth-search.aws.element84.com/v0/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/DotNetStac/Collection/StacExtent.cs b/src/DotNetStac/Collection/StacExtent.cs
index d8667771..203b6e65 100644
--- a/src/DotNetStac/Collection/StacExtent.cs
+++ b/src/DotNetStac/Collection/StacExtent.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
@@ -9,30 +10,41 @@ namespace Stac.Collection
/// STAC Extent Object
///
[JsonObject]
- public class StacExtent
+ public class StacExtent : ICloneable
{
///
/// Initialise a new instance of the class.
///
- /// Spatial Extent
- /// Temporal Extent
+ /// Spatial Extent.
+ /// Temporal Extent.
+ [JsonConstructor]
public StacExtent(StacSpatialExtent spatial, StacTemporalExtent temporal)
{
- Spatial = spatial;
- Temporal = temporal;
+ this.Spatial = spatial;
+ this.Temporal = temporal;
}
///
- /// Potential covered by the Collection.
+ /// Initialize a new Stac Extent from an existing one (clone).
///
- /// Gets/sets the spatial extent
+ ///
+ public StacExtent(StacExtent extent)
+ {
+ this.Spatial = new StacSpatialExtent(extent.Spatial);
+ this.Temporal = new StacTemporalExtent(extent.Temporal);
+ }
+
+ ///
+ /// Gets or sets Potential covered by the Collection.
+ ///
+ /// The spatial extent.
[JsonProperty("spatial")]
public StacSpatialExtent Spatial { get; set; }
///
- /// Potential covered by the Collection.
+ /// Gets or sets Potential covered by the Collection.
///
- /// Gets/sets the temporal extent
+ /// The temporal extent.
[JsonProperty("temporal")]
public StacTemporalExtent Temporal { get; set; }
@@ -51,5 +63,10 @@ public static StacExtent Create(IEnumerable items)
new StacTemporalExtent(items.Min(i => i.DateTime.Start), items.Max(i => i.DateTime.End))
);
}
+
+ public object Clone()
+ {
+ return new StacExtent(this);
+ }
}
}
diff --git a/src/DotNetStac/Collection/StacSpatialExtent.cs b/src/DotNetStac/Collection/StacSpatialExtent.cs
index 7689d562..dee4025f 100644
--- a/src/DotNetStac/Collection/StacSpatialExtent.cs
+++ b/src/DotNetStac/Collection/StacSpatialExtent.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using System;
+using Newtonsoft.Json;
namespace Stac.Collection
{
@@ -7,7 +8,7 @@ namespace Stac.Collection
/// Spatial Extent Object
///
[JsonObject]
- public class StacSpatialExtent
+ public class StacSpatialExtent : ICloneable
{
///
/// Initialize a new instance of the class with a single extent.
@@ -22,11 +23,29 @@ public StacSpatialExtent(double minX, double minY, double maxX, double maxY)
BoundingBoxes = new double[1][] { new double[4] { minX, minY, maxX, maxY } };
}
+ ///
+ /// Initialize a new Stac Spatial extent from an existing one (clone)
+ ///
+ ///
+ public StacSpatialExtent(StacSpatialExtent spatial)
+ {
+ this.BoundingBoxes = (double[][])spatial.BoundingBoxes.Clone();
+ }
+
///
/// Potential spatial extents.
///
/// Gets/sets double entry array of coordinates
[JsonProperty("bbox")]
public double[][] BoundingBoxes { get; set; }
+
+ ///
+ /// Clone this Extent
+ ///
+ ///
+ public object Clone()
+ {
+ return new StacSpatialExtent(this);
+ }
}
}
diff --git a/src/DotNetStac/Collection/StacTemporalExtent.cs b/src/DotNetStac/Collection/StacTemporalExtent.cs
index c860efb9..228d7f91 100644
--- a/src/DotNetStac/Collection/StacTemporalExtent.cs
+++ b/src/DotNetStac/Collection/StacTemporalExtent.cs
@@ -10,6 +10,8 @@ namespace Stac.Collection
[JsonObject]
public class StacTemporalExtent
{
+
+
///
/// Initialize a new instance of the class with a single extent.
///
@@ -21,6 +23,15 @@ public StacTemporalExtent(DateTime? start, DateTime? end)
Interval = new DateTime?[1][] { new DateTime?[2] { start, end } };
}
+ ///
+ /// Intialize a new Stac Temporal Extent from an exisiting one (clone)
+ ///
+ ///
+ public StacTemporalExtent(StacTemporalExtent temporal)
+ {
+ this.Interval = (System.DateTime?[][])temporal.Interval.Clone();
+ }
+
///
/// Potential temporal extents.
///
diff --git a/src/DotNetStac/Converters/ContentTypeConverter.cs b/src/DotNetStac/Converters/ContentTypeConverter.cs
index 80c58789..ddc8d472 100644
--- a/src/DotNetStac/Converters/ContentTypeConverter.cs
+++ b/src/DotNetStac/Converters/ContentTypeConverter.cs
@@ -1,4 +1,7 @@
using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
using System.Net.Mime;
using Newtonsoft.Json;
@@ -15,7 +18,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
{
try
{
- return new ContentType((string)reader.Value);
+ var ct = new ContentType((string)reader.Value);
+ return ct;
}
catch (Exception e)
{
diff --git a/src/DotNetStac/DotNetStac.csproj b/src/DotNetStac/DotNetStac.csproj
index a666f9c9..5a4d55b2 100644
--- a/src/DotNetStac/DotNetStac.csproj
+++ b/src/DotNetStac/DotNetStac.csproj
@@ -4,7 +4,7 @@
DotNetStac
Terradue .Net library for working with any SpatioTemporal Asset Catalog
LICENSE
- 1.0.0
+ 1.1.0
Emmanuel Mathot
emmanuelmathot
diff --git a/src/DotNetStac/StacAccessorsHelpers.cs b/src/DotNetStac/StacAccessorsHelpers.cs
index 568b2cb4..80c09c5c 100644
--- a/src/DotNetStac/StacAccessorsHelpers.cs
+++ b/src/DotNetStac/StacAccessorsHelpers.cs
@@ -106,6 +106,16 @@ public static void SetCollection(this StacItem stacItem, string collectionId, Ur
stacItem.Collection = collectionId;
}
+ ///
+ /// Gets the collection of the Item as a StacLink
+ ///
+ ///
+ /// a Stac Link
+ public static StacLink GetCollection(this StacItem stacItem)
+ {
+ return stacItem.Links.FirstOrDefault(l => l.RelationshipType == "collection");
+ }
+
public static void AddRange(this ICollection collection, IEnumerable items)
{
if (collection is List list)
diff --git a/src/DotNetStac/StacCatalog.CommonMetadata.cs b/src/DotNetStac/StacCatalog.CommonMetadata.cs
index 48967611..efe5e003 100644
--- a/src/DotNetStac/StacCatalog.CommonMetadata.cs
+++ b/src/DotNetStac/StacCatalog.CommonMetadata.cs
@@ -10,7 +10,7 @@ namespace Stac
/// They are often used in STAC Item properties, but can also be used in other places, e.g. an Item Asset or Collection Asset.
/// STAC Common Metadata
///
- public partial class StacCatalog : IStacObject, IStacParent, IStacCatalog
+ public partial class StacCatalog : IStacObject, IStacParent, IStacCatalog, ICloneable
{
public string Title
@@ -143,5 +143,9 @@ public Itenso.TimePeriod.ITimePeriod DateTime
}
}
+ public object Clone()
+ {
+ return new StacCatalog(this);
+ }
}
}
diff --git a/src/DotNetStac/StacCatalog.cs b/src/DotNetStac/StacCatalog.cs
index f75e3c72..b3dc1061 100644
--- a/src/DotNetStac/StacCatalog.cs
+++ b/src/DotNetStac/StacCatalog.cs
@@ -19,7 +19,7 @@ public partial class StacCatalog : IStacObject, IStacParent, IStacCatalog
///
/// Catalog Media-Type string
///
- public const string MEDIATYPE = "application/json; profile=stac-catalog";
+ public const string MEDIATYPE = "application/json";
///
/// Catalog Media-Type Object
@@ -48,6 +48,20 @@ public StacCatalog(string id, string description, IEnumerable links =
this.StacExtensions = new SortedSet();
}
+ ///
+ /// Initialize a new Stac Catalog from an existing one (clone)
+ ///
+ /// existing Stac Catalog
+ public StacCatalog(StacCatalog stacCatalog)
+ {
+ this.Id = stacCatalog.Id;
+ this.StacExtensions = new SortedSet(stacCatalog.StacExtensions);
+ this.StacVersion = stacCatalog.StacVersion;
+ this.Links = new Collection(stacCatalog.Links.ToList());
+ this.Summaries = new Dictionary(stacCatalog.Summaries);
+ this.Properties = new Dictionary(stacCatalog.Properties);
+ }
+
# region IStacObject
///
diff --git a/src/DotNetStac/StacCollection.CommonMetadata.cs b/src/DotNetStac/StacCollection.CommonMetadata.cs
index ace9318e..717f84d8 100644
--- a/src/DotNetStac/StacCollection.CommonMetadata.cs
+++ b/src/DotNetStac/StacCollection.CommonMetadata.cs
@@ -10,7 +10,7 @@ namespace Stac
/// They are often used in STAC Item properties, but can also be used in other places, e.g. an Item Asset or Collection Asset.
/// STAC Common Metadata
///
- public partial class StacCollection : IStacObject, IStacParent, IStacCatalog
+ public partial class StacCollection : IStacObject, IStacParent, IStacCatalog, ICloneable
{
///
@@ -155,5 +155,6 @@ public Itenso.TimePeriod.ITimePeriod DateTime
}
}
+
}
}
diff --git a/src/DotNetStac/StacCollection.cs b/src/DotNetStac/StacCollection.cs
index dc7f825d..bcaeb355 100644
--- a/src/DotNetStac/StacCollection.cs
+++ b/src/DotNetStac/StacCollection.cs
@@ -16,7 +16,7 @@ namespace Stac
/// STAC Collection Object implementing STAC Collection spec (https://github.com/radiantearth/stac-spec/blob/master/collection-spec/collection-spec.md)
///
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore, MemberSerialization = MemberSerialization.OptIn)]
- public partial class StacCollection : IStacObject, IStacParent, IStacCatalog
+ public partial class StacCollection : IStacObject, IStacParent, IStacCatalog, ICloneable
{
public const string MEDIATYPE = "application/json";
public readonly static ContentType COLLECTION_MEDIATYPE = new ContentType(MEDIATYPE);
@@ -50,7 +50,26 @@ public StacCollection(string id,
this.Extent = extent;
}
- # region IStacObject
+ ///
+ /// Initialize a new Stac Collection from an existing one (clone)
+ ///
+ /// existing Stac Collection
+ public StacCollection(StacCollection stacCollection)
+ {
+ this.Id = stacCollection.Id;
+ this.StacExtensions = new SortedSet(stacCollection.StacExtensions);
+ this.StacVersion = stacCollection.StacVersion;
+ this.Links = new Collection(stacCollection.Links.ToList());
+ this.Summaries = new Dictionary(stacCollection.Summaries);
+ this.Properties = new Dictionary(stacCollection.Properties);
+ this.Assets = new Dictionary(stacCollection.Assets);
+ this.Providers = new Collection(stacCollection.Providers);
+ this.License = stacCollection.License;
+ this.Keywords = new Collection(stacCollection.Keywords);
+ this.Extent = new StacExtent(stacCollection.Extent);
+ }
+
+ #region IStacObject
///
/// Identifier for the Collection.
@@ -88,7 +107,7 @@ public ICollection Links
[JsonIgnore]
public ContentType MediaType => COLLECTION_MEDIATYPE;
- # endregion IStacObject
+ #endregion IStacObject
///
/// STAC type (Collection)
@@ -229,5 +248,14 @@ public static StacCollection Create(string id,
}
#endregion
+
+ ///
+ /// Clone this object.
+ ///
+ ///
+ public object Clone()
+ {
+ return new StacCollection(this);
+ }
}
}
diff --git a/src/DotNetStac/StacConvert.cs b/src/DotNetStac/StacConvert.cs
index 8d7da6d9..177b9ae7 100644
--- a/src/DotNetStac/StacConvert.cs
+++ b/src/DotNetStac/StacConvert.cs
@@ -1,6 +1,7 @@
namespace Stac
{
using System;
+ using System.Globalization;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -13,6 +14,7 @@ public static class StacConvert
private static JsonSerializerSettings defaultJsonSerializerSettings = new JsonSerializerSettings()
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
+ Culture = CultureInfo.CreateSpecificCulture("en-US"),
};
public static T Deserialize(string json, JsonSerializerSettings serializerSettings = null) where T : IStacObject
@@ -46,7 +48,9 @@ public static T Deserialize(string json, JsonSerializerSettings serializerSet
public static string Serialize(IStacObject stacObject, JsonSerializerSettings serializerSettings = null)
{
if (serializerSettings == null)
+ {
serializerSettings = defaultJsonSerializerSettings;
+ }
serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
return JsonConvert.SerializeObject(stacObject, serializerSettings);
}
diff --git a/src/DotNetStac/StacItem.cs b/src/DotNetStac/StacItem.cs
index 382330df..1f1c0e40 100644
--- a/src/DotNetStac/StacItem.cs
+++ b/src/DotNetStac/StacItem.cs
@@ -17,7 +17,7 @@ namespace Stac
/// STAC Item Object implementing STAC Item spec (https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md)
///
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore, MemberSerialization = MemberSerialization.OptIn)]
- public partial class StacItem : GeoJSON.Net.Feature.Feature, IStacObject
+ public partial class StacItem : GeoJSON.Net.Feature.Feature, IStacObject, ICloneable
{
public const string MEDIATYPE = "application/geo+json";
public readonly static ContentType ITEM_MEDIATYPE = new ContentType(MEDIATYPE);
@@ -162,6 +162,15 @@ public bool ShouldSerializeStacExtensions()
return StacExtensions.Count > 0;
}
+ ///
+ /// Create a new Stac Item from this existing one
+ ///
+ ///
+ public object Clone()
+ {
+ return new StacItem(this);
+ }
+
[JsonIgnore]
public IStacObject StacObjectContainer => this;
}