Skip to content

Commit add9ba6

Browse files
committed
Add support for Item Collections
1 parent 238569b commit add9ba6

File tree

4 files changed

+69
-16
lines changed

4 files changed

+69
-16
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ Add to your project with `npm install @radiantearth/stac-migrate --save`
1212

1313
Import the library: `const Migrate = require('@radiantearth/stac-migrate');`
1414

15-
* Migrate (auto-detection): `Migrate.stac(stac: object) => object`<br />
15+
* Migrate (auto-detection): `Migrate.stac(stac: object, updateVersionNumber: boolean = true) => object`<br />
1616
*This method does not migrate the Commons extension - use `Migrate.item` if you have used the Commons extension.*
17-
* Migrate a STAC Collection: `Migrate.collection(collection: object) => object`
18-
* Migrate a STAC Catalog: `Migrate.catalog(catalog: object) => object`
19-
* Migrate a STAC Item: `Migrate.item(item: object, collection: object = null) => object`<br />
17+
* Migrate a STAC Collection: `Migrate.collection(collection: object, updateVersionNumber: boolean = true) => object`
18+
* Migrate a STAC Catalog: `Migrate.catalog(catalog: object, updateVersionNumber: boolean = true) => object`
19+
* Migrate a STAC Item: `Migrate.item(item: object, collection: object = null, updateVersionNumber: boolean = true) => object`<br />
2020
*The `collection` parameter is only required to migrate the Commons extension. Otherwise, you don't need to pass this paramater.*
21+
* Migrate a STAC ItemCollection: `Migrate.itemCollection(catalog: object, updateVersionNumber: boolean = true) => object`
2122

2223
**Note:** All changes will be applied in-place! If you don't want the input object to change, make a deep clone before. If you don't have a library which supports this (e.g. [lodash](https://lodash.com/docs/4.17.15#cloneDeep)) you can simply use `var clone = JSON.parse(JSON.stringify(object));`.
2324

@@ -31,6 +32,7 @@ The commands follow the different methods above and has the same "restrictions"
3132
* Migrate a STAC Collection: `npx stac-migrate <source_path> <dest_path> --collection`
3233
* Migrate a STAC Catalog: `npx stac-migrate <source_path> <dest_path> --catalog`
3334
* Migrate a STAC Item: `npx stac-migrate <source_path> <dest_path> --item --collection_path <collection_path>`
35+
* Migrate a STAC Item Collection: `npx stac-migrate <source_path> <dest_path> --item_collection`
3436

3537
## Supported Extensions
3638

bin/cli.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,28 @@ const args = yargs(hideBin(process.argv))
1818
.option('collection', {
1919
type: 'boolean',
2020
description: 'Enforce the collection migration',
21-
conflicts: ['catalog', 'item'],
21+
conflicts: ['catalog', 'item', 'item_collection'],
2222

2323
})
2424
.option('catalog', {
2525
type: 'boolean',
2626
description: 'Enforce the catalog migration',
27-
conflicts: ['collection', 'item',]
27+
conflicts: ['collection', 'item', 'item_collection']
2828
})
2929
.option('item', {
3030
type: 'boolean',
3131
description: 'Enforce the item migration',
32-
conflicts: ['catalog', 'collection']
32+
conflicts: ['catalog', 'collection', 'item_collection']
33+
})
34+
.option('item_collection', {
35+
type: 'boolean',
36+
description: 'Enforce the item collection migration',
37+
conflicts: ['catalog', 'collection', 'item']
3338
})
3439
.option('collection_path', {
3540
type: 'string',
3641
description: 'Pass the path to a collection to the item, only possible if --item has been specified.',
37-
conflicts: ['catalog', 'collection']
42+
conflicts: ['catalog', 'collection', 'item_collection']
3843
})
3944
.option('indent', {
4045
type: 'number',
@@ -48,9 +53,12 @@ run(args);
4853

4954
function run(args) {
5055
console.log("STAC Migrate v" + package.version);
51-
let fn = ['collection', 'catalog', 'item'].find(type => Boolean(args[type])) || 'stac';
56+
let fn = ['collection', 'catalog', 'item', 'item_collection'].find(type => Boolean(args[type])) || 'stac';
57+
if (fn === 'item_collection') {
58+
fn = 'itemCollection';
59+
}
5260
if (args._.length !== 1) {
53-
throw new Error("Please provide exatctly one source file.");
61+
throw new Error("Please provide exactly one source file.");
5462
}
5563
let src = args._[0];
5664
let dest = args.dest || src;

migrate.js

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ var Catalog = {
402402
_.runAll(Catalog, catalog, catalog);
403403

404404
V.before('0.8.0') && _.populateExtensions(catalog, 'catalog') && DONE;
405+
406+
return catalog;
405407
},
406408

407409
openeo(obj) {
@@ -442,6 +444,8 @@ var Collection = {
442444

443445
V.before('0.8.0') && _.populateExtensions(collection, 'collection') && DONE;
444446
V.before('1.0.0-beta.1') && _.mapValues(collection, 'stac_extensions', ['assets'], ['item-assets']) && DONE;
447+
448+
return collection;
445449
},
446450

447451
extent(collection) {
@@ -652,10 +656,28 @@ var Item = {
652656

653657
// Also populate extensions if commons has been implemented
654658
(V.before('0.8.0') || commons) && _.populateExtensions(item, 'item') && DONE;
659+
660+
return item;
655661
}
656662

657663
};
658664

665+
var ItemCollection = {
666+
667+
migrate(itemCollection, updateVersionNumber = true) {
668+
_.ensure(itemCollection, 'type', 'FeatureCollection') && DONE;
669+
_.ensure(itemCollection, 'features', []) && DONE;
670+
_.ensure(itemCollection, 'links', []) && DONE;
671+
672+
_.runAll(ItemCollection, itemCollection, itemCollection);
673+
674+
itemCollection.features = itemCollection.features.map(feature => Item.migrate(feature, null, updateVersionNumber));
675+
676+
return itemCollection;
677+
},
678+
679+
};
680+
659681
var Asset = {
660682

661683
migrateAll(context, field = 'assets') {
@@ -666,7 +688,10 @@ var Asset = {
666688

667689
migrate(asset, context) {
668690
_.runAll(Asset, asset, context);
691+
669692
Fields.migrate(asset, context);
693+
694+
return asset;
670695
},
671696

672697
mediaTypes(asset) {
@@ -699,6 +724,8 @@ var Fields = {
699724

700725
migrate(obj, context, summaries = false) {
701726
_.runAll(Fields, obj, context, summaries);
727+
728+
return obj;
702729
},
703730

704731
_commonMetadata(obj) {
@@ -892,24 +919,28 @@ var Fields = {
892919
var Migrate = {
893920

894921
item(item, collection = null, updateVersionNumber = true) {
895-
Item.migrate(item, collection, updateVersionNumber);
896-
return item;
922+
return Item.migrate(item, collection, updateVersionNumber);
897923
},
898924

899925
catalog(catalog, updateVersionNumber = true) {
900-
Catalog.migrate(catalog, updateVersionNumber);
901-
return catalog;
926+
return Catalog.migrate(catalog, updateVersionNumber);
902927
},
903928

904929
collection(collection, updateVersionNumber = true) {
905-
Collection.migrate(collection, updateVersionNumber);
906-
return collection;
930+
return Collection.migrate(collection, updateVersionNumber);
931+
},
932+
933+
itemCollection(itemCollection, updateVersionNumber = true) {
934+
return ItemCollection.migrate(itemCollection, updateVersionNumber);
907935
},
908936

909937
stac(object, updateVersionNumber = true) {
910938
if (object.type === 'Feature') {
911939
return Migrate.item(object, null, updateVersionNumber);
912940
}
941+
else if (object.type === 'FeatureCollection') {
942+
return Migrate.itemCollection(object, updateVersionNumber);
943+
}
913944
else if (object.type === 'Collection' || _.isDefined(object.extent) || _.isDefined(object.license)) {
914945
return Migrate.collection(object, updateVersionNumber);
915946
}

tests/migrate.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,16 @@ describe('STAC Migrations', () => {
3333
const legacyCollection09 = loadJson('legacy/collection-sar-0.9.json');
3434
expect(Migrate.item(legacyItem, legacyCollection09)).toEqual(latestItem);
3535
});
36+
37+
test('ItemCollection', () => {
38+
const legacy1 = loadJson('legacy/item-minimal.json');
39+
const latest1 = loadJson('latest/item-minimal.json');
40+
const legacy2 = loadJson('legacy/item-sample.json');
41+
const latest2 = loadJson('latest/item-sample.json');
42+
const legacy = {type: "FeatureCollection", features: [legacy1, legacy2]};
43+
const latest = {type: "FeatureCollection", features: [latest1, latest2], links: []};
44+
45+
expect(Migrate.itemCollection(legacy)).toEqual(latest);
46+
expect(Migrate.stac(legacy)).toEqual(latest);
47+
});
3648
});

0 commit comments

Comments
 (0)