Skip to content

Commit

Permalink
Merge pull request #368 from colonial-heritage/feat-objects-location-…
Browse files Browse the repository at this point in the history
…of-creation

feat: add location of creation to object details
  • Loading branch information
sdevalk authored Dec 14, 2023
2 parents 9539141 + 01af1c9 commit bab3703
Show file tree
Hide file tree
Showing 16 changed files with 463 additions and 312 deletions.
1 change: 1 addition & 0 deletions apps/researcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@hookform/resolvers": "3.3.2",
"@next/mdx": "14.0.1",
"classnames": "2.3.2",
"defu": "6.1.3",
"fetch-sparql-endpoint": "4.1.0",
"iso-639-1-dir": "3.0.5",
"jwt-decode": "^4.0.0",
Expand Down
3 changes: 2 additions & 1 deletion apps/researcher/src/lib/api/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type Thing = {
};

export type Term = Thing;
export type Place = Thing;
export type Place = Thing & {isPartOf?: Place};
export type Person = Thing & {type: 'Person'};
export type Unknown = Thing & {type: 'Unknown'};
export type Agent = Person | Organization | Unknown;
Expand Down Expand Up @@ -53,6 +53,7 @@ export type HeritageObject = {
materials?: Term[];
techniques?: Term[];
creators?: Agent[];
locationCreated?: Place;
dateCreated?: TimeSpan;
images?: Image[];
owner?: Agent;
Expand Down
28 changes: 18 additions & 10 deletions apps/researcher/src/lib/api/objects/fetcher.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,23 @@ describe('getById', () => {
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ultrices velit vitae vulputate tincidunt. Donec dictum tortor nec tempus mollis.',
inscriptions: ['Maecenas commodo est neque'],
types: [
types: expect.arrayContaining([
{
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
),
name: 'Canvas Painting',
},
],
subjects: [
]),
subjects: expect.arrayContaining([
{
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
),
name: 'Celebrations',
},
],
materials: [
]),
materials: expect.arrayContaining([
{
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
Expand All @@ -66,31 +66,39 @@ describe('getById', () => {
),
name: 'Canvas',
},
],
techniques: [
]),
techniques: expect.arrayContaining([
{
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
),
name: 'Albumen process',
},
],
creators: [
]),
creators: expect.arrayContaining([
{
type: 'Person',
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
),
name: 'Geeske van Châtellerault',
},
],
]),
dateCreated: {
id: expect.stringContaining(
'https://colonial-heritage.triply.cc/.well-known/genid/'
),
startDate: new Date('1901-01-01'),
endDate: new Date('1902-06-01'),
},
locationCreated: {
id: 'https://sws.geonames.org/1749659/',
name: 'Pulau Sebang',
isPartOf: {
id: 'https://sws.geonames.org/1733045/',
name: 'Malaysia',
},
},
images: expect.arrayContaining([
{
id: expect.stringContaining(
Expand Down
154 changes: 93 additions & 61 deletions apps/researcher/src/lib/api/objects/fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {ontologyUrl, HeritageObject, Term} from '../definitions';
import {HeritageObject, Term} from '../definitions';
import {
getPropertyValue,
getPropertyValues,
onlyOne,
removeUndefinedValues,
removeNullish,
} from '../rdf-helpers';
import {
createAgents,
createDatasets,
createImages,
createPlaces,
createThings,
createTimeSpans,
} from './rdf-helpers';
Expand Down Expand Up @@ -37,62 +38,71 @@ export class HeritageObjectFetcher {

private async fetchTriples(iri: string) {
const query = `
PREFIX cc: <${ontologyUrl}>
PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
PREFIX ex: <https://example.org/>
PREFIX dct: <http://purl.org/dc/terms/>
PREFIX dig: <http://www.ics.forth.gr/isl/CRMdig/>
PREFIX gn: <http://www.geonames.org/ontology#>
PREFIX la: <https://linked.art/ns/terms/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX schema: <https://schema.org/>
CONSTRUCT {
?object a cc:HeritageObject ;
cc:identifier ?identificationNumber ;
cc:name ?name ;
cc:description ?description ;
cc:inscription ?inscription ;
cc:additionalType ?type ;
cc:about ?subject ;
cc:material ?material ;
cc:technique ?technique ;
cc:creator ?creator ;
cc:dateCreated ?dateCreatedTimeSpan ;
cc:image ?digitalObject ;
cc:owner ?owner ;
cc:isPartOf ?dataset .
?type a cc:DefinedTerm ;
cc:name ?typeName .
?subject a cc:DefinedTerm ;
cc:name ?subjectName .
?material a cc:DefinedTerm ;
cc:name ?materialName .
?technique a cc:DefinedTerm ;
cc:name ?techniqueName .
?object a ex:HeritageObject ;
ex:identifier ?identificationNumber ;
ex:name ?name ;
ex:description ?description ;
ex:inscription ?inscription ;
ex:additionalType ?type ;
ex:about ?subject ;
ex:material ?material ;
ex:technique ?technique ;
ex:creator ?creator ;
ex:dateCreated ?dateCreatedTimeSpan ;
ex:locationCreated ?locationCreated ;
ex:image ?digitalObject ;
ex:owner ?owner ;
ex:isPartOf ?dataset .
?type a ex:DefinedTerm ;
ex:name ?typeName .
?subject a ex:DefinedTerm ;
ex:name ?subjectName .
?material a ex:DefinedTerm ;
ex:name ?materialName .
?technique a ex:DefinedTerm ;
ex:name ?techniqueName .
?creator a ?creatorType ;
cc:name ?creatorName .
ex:name ?creatorName .
?dateCreatedTimeSpan a cc:TimeSpan ;
cc:startDate ?dateCreatedBegin ;
cc:endDate ?dateCreatedEnd .
?dateCreatedTimeSpan a ex:TimeSpan ;
ex:startDate ?dateCreatedBegin ;
ex:endDate ?dateCreatedEnd .
?digitalObject a cc:ImageObject ;
cc:contentUrl ?contentUrl .
?locationCreated a ex:Place ;
ex:name ?locationCreatedName ;
ex:isPartOf ?countryCreated .
?countryCreated a ex:Place ;
ex:name ?countryCreatedName .
?digitalObject a ex:ImageObject ;
ex:contentUrl ?contentUrl .
?owner a ?ownerType ;
cc:name ?ownerName .
ex:name ?ownerName .
?dataset a cc:Dataset ;
cc:publisher ?publisher ;
cc:name ?datasetName .
?dataset a ex:Dataset ;
ex:publisher ?publisher ;
ex:name ?datasetName .
?publisher a ?publisherType ;
cc:name ?publisherName .
ex:name ?publisherName .
}
WHERE {
BIND(<${iri}> as ?object)
Expand Down Expand Up @@ -189,8 +199,8 @@ export class HeritageObjectFetcher {
rdf:type ?creatorTypeTemp .
VALUES (?creatorTypeTemp ?creatorType) {
(schema:Organization cc:Organization)
(crm:E21_Person cc:Person)
(schema:Organization ex:Organization)
(crm:E21_Person ex:Person)
(UNDEF UNDEF)
}
}
Expand All @@ -211,6 +221,24 @@ export class HeritageObjectFetcher {
}
}
####################
# Location of creation
####################
OPTIONAL {
?object crm:P108i_was_produced_by/crm:P7_took_place_at ?locationCreated .
?locationCreated gn:name ?locationCreatedName ;
gn:featureCode ?featureCode .
FILTER(LANG(?locationCreatedName) = "" || LANGMATCHES(LANG(?locationCreatedName), "en"))
# Country of which the location is a part
OPTIONAL {
?locationCreated gn:parentCountry ?countryCreated .
?countryCreated gn:name ?countryCreatedName .
FILTER(LANG(?countryCreatedName) = "" || LANGMATCHES(LANG(?countryCreatedName), "en"))
}
}
####################
# Digital objects (currently: images)
####################
Expand All @@ -234,8 +262,8 @@ export class HeritageObjectFetcher {
FILTER(LANG(?ownerName) = "" || LANGMATCHES(LANG(?ownerName), "en"))
VALUES (?ownerTypeTemp ?ownerType) {
(schema:Organization cc:Organization)
(schema:Person cc:Person)
(schema:Organization ex:Organization)
(schema:Person ex:Person)
(UNDEF UNDEF)
}
}
Expand Down Expand Up @@ -266,8 +294,8 @@ export class HeritageObjectFetcher {
rdf:type ?publisherTypeTemp .
VALUES (?publisherTypeTemp ?publisherType) {
(schema:Organization cc:Organization)
(schema:Person cc:Person)
(schema:Organization ex:Organization)
(schema:Person ex:Person)
(UNDEF UNDEF)
}
}
Expand All @@ -284,7 +312,7 @@ export class HeritageObjectFetcher {
) {
const loader = new RdfObjectLoader({
context: {
cc: ontologyUrl,
ex: 'https://example.org/',
rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
},
});
Expand All @@ -296,21 +324,24 @@ export class HeritageObjectFetcher {
return undefined; // No such object
}

const identifier = getPropertyValue(rawHeritageObject, 'cc:identifier');
const name = getPropertyValue(rawHeritageObject, 'cc:name');
const description = getPropertyValue(rawHeritageObject, 'cc:description');
const types = createThings<Term>(rawHeritageObject, 'cc:additionalType');
const subjects = createThings<Term>(rawHeritageObject, 'cc:about');
const inscriptions = getPropertyValues(rawHeritageObject, 'cc:inscription');
const materials = createThings<Term>(rawHeritageObject, 'cc:material');
const techniques = createThings<Term>(rawHeritageObject, 'cc:technique');
const creators = createAgents(rawHeritageObject, 'cc:creator');
const identifier = getPropertyValue(rawHeritageObject, 'ex:identifier');
const name = getPropertyValue(rawHeritageObject, 'ex:name');
const description = getPropertyValue(rawHeritageObject, 'ex:description');
const types = createThings<Term>(rawHeritageObject, 'ex:additionalType');
const subjects = createThings<Term>(rawHeritageObject, 'ex:about');
const inscriptions = getPropertyValues(rawHeritageObject, 'ex:inscription');
const materials = createThings<Term>(rawHeritageObject, 'ex:material');
const techniques = createThings<Term>(rawHeritageObject, 'ex:technique');
const creators = createAgents(rawHeritageObject, 'ex:creator');
const dateCreated = onlyOne(
createTimeSpans(rawHeritageObject, 'cc:dateCreated')
createTimeSpans(rawHeritageObject, 'ex:dateCreated')
);
const locationCreated = onlyOne(
createPlaces(rawHeritageObject, 'ex:locationCreated')
);
const images = createImages(rawHeritageObject, 'cc:image');
const owner = onlyOne(createAgents(rawHeritageObject, 'cc:owner'));
const dataset = onlyOne(createDatasets(rawHeritageObject, 'cc:isPartOf'));
const images = createImages(rawHeritageObject, 'ex:image');
const owner = onlyOne(createAgents(rawHeritageObject, 'ex:owner'));
const dataset = onlyOne(createDatasets(rawHeritageObject, 'ex:isPartOf'));

const heritageObjectWithUndefinedValues: HeritageObject = {
id: iri,
Expand All @@ -324,12 +355,13 @@ export class HeritageObjectFetcher {
techniques,
creators,
dateCreated,
locationCreated,
images,
owner,
isPartOf: dataset,
};

const heritageObject = removeUndefinedValues<HeritageObject>(
const heritageObject = removeNullish<HeritageObject>(
heritageObjectWithUndefinedValues
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('getProvenanceEventsByHeritageObjectId', () => {
'https://example.org/objects/1'
);

expect(provenanceEvents).toHaveLength(4);
expect(provenanceEvents).toHaveLength(5);
});
});

Expand Down
Loading

2 comments on commit bab3703

@vercel
Copy link

@vercel vercel bot commented on bab3703 Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on bab3703 Dec 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.