Switch branches/tags
Nothing to show
Clone or download
Pull request Compare This branch is 3 commits ahead of cmda-minor-web:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
images
js
styles
README.md
index.html

README.md

API Stadsarchief Amsterdam

link to the project

In de week van 5 tot 9 maart 2018 mochten wij aan een project werken in de OBA, waar we met ingeladen data web apps hebben gemaakt.

Mijn project

preview of the page Mijn project richt zich op de collectie "documentaire foto-opdrachten" binnen de Beeldbank van het Stadsarchief. De data wordt ingeladen door een tijdlijn, waarop de gebruiker een jaar selecteerd en daarmee de foto-series van dat jaar ophaalt.

De dataset

Na te hebben gezocht in de beeldbank, kwam ik veel interessante en mooie foto's tegen uit collecties zoals

Mijn collectie

De door mij gekozen collectie gaat over foto's die gemaakt zijn voor documentaire series. Bijna al deze foto's zijn gemaakt in opdracht van het Amsterdams Fonds voor de Kunst.

Documentaires kunnen een goed beeld geven van de tijd waarin ze zijn gemaakt. Zo werd er in 1960 een documentaire-serie gemaakt over "Havenarbeid"1960

In 1970 werd onder andere de serie "Amsterdam voor het voorbij is" gemaakt met foto's zoals deze hieronder, maar ook veel foto's van de normale mens die over straat loopt. 1970

In 1996 werd onder andere deze fotoserie gemaakt, die erg intiem is en dichtbij de kwetsbaarheid van mensen komt. 1996

Tot slot, een serie in 2011, waarin opgravingen van de constructie rondom de Noord/Zuidlijn zijn gefotografeerd.2011

Nog een ander groot voordeel van deze collectie, is dat bij 90% van de foto's de beschrijving hetzelfde is opgesteld. De naam van de serie is in dezelfde zin uitgedrukt en is dus op te zoeken in de dataset. beschrijving

De applicatie

Ophalen van de data

Ik ben begonnen met de data ophalen via een sparql query en deze te printen in de console, zodat ik de architectuur van de data kan zien en kan inplannen welke stappen ik moet zetten.

var sparqlquery = `PREFIX dc: <http://purl.org/dc/elements/1.1/>
            PREFIX dct: <http://purl.org/dc/terms/>
            PREFIX sem: <http://semanticweb.cs.vu.nl/2009/11/sem/>
            PREFIX foaf: <http://xmlns.com/foaf/0.1/>
            PREFIX void: <http://rdfs.org/ns/void#>
            SELECT ?cho ?year ?img ?title ?description ?creator WHERE {
                ?cho dc:description ?description .
                ?cho dc:title ?title .
                ?cho sem:hasBeginTimeStamp ?start .
                ?cho foaf:depiction ?img .
                BIND (year(xsd:dateTime(?start)) AS ?year) .
                ?cho void:inDataset <https://data.adamlink.nl/saa/beeldbank/> .
                ?cho dct:provenance "Collectie Stadsarchief Amsterdam: documentaire foto-opdrachten"^^xsd:string .
                OPTIONAL { ?cho dc:creator ?creator }
            }`

In deze variabele verklaar ik welke aspecten van de data ik wil hebben:

  • dc titel: bovenste stukje van de beschrijving
  • dc: description: onderste stukje van de beschrijving
  • hasBeginTimeStamp & BIND (year(xsd:dateTime(?start)) AS ?year): het eerst genoemde jaar, als deze beschikbaar is
  • dct: provenance: selecteer alleen deze collectie uit de beeldbank
  • `dc: creator': de fotograaf
De slider

In het object slider, wordt eerst activeyear gegeven op 1960, zodat de applicatie bij het opstarten begint met deze data in te laden en op het scherm te zetten. Daarna begint een functie die selectYear heet.

var slider = {
    activeYear: 1960,
    selectYear: function(data) {
        var sliderInput = document.getElementById("year");
        var result = document.getElementById("result");

        sliderInput.addEventListener("input", sliderResult);
        
        function sliderResult() {
            var integerValue = parseInt(sliderInput.value);
            result.innerHTML = integerValue;
            slider.activeYear =  sliderInput.value;
            var yearlyData = data.filter(collection.filterYear);
            var resultArray = collection.groupBy(yearlyData, function(item)
            {
                return [item.creator.value];
            });

            template.section(resultArray);
        }
        
    }
}

In deze functie worden de elementen uit de HTML opgevraagt en staat er een eventListener op de input (de range slider). De waarde vanuit deze slider wordt opgevraagd en opgeslagen nadat het event getriggerd wordt. Dit geselecteerde jaar wordt doorgestuurd naar een ander object, daar wordt de data gegroepeerd op fotograaf.

Het plan om de foto's op serie te selecteren wordt verhinderd omdat niet elke foto een serie vermeld heeft staan. Wel hebben alle foto's een fotograaf vermeld en zijn series altijd door dezelfde persoon gemaakt. Deze persoon maakt in elk geval maar 1x per jaar een serie.

Groeperen

Op deze manier is gegroepeerd op fotograaf:

groupBy: function(yearlyData, f) {
            var groups = {};
            yearlyData.forEach(function (o) {
                var group = f(o);
                groups[group] = groups[group] || [];
                groups[group].push( o ); 
            });
            return Object.keys(groups).map(function(group) {
                return groups[group]; 
            })
        },

Voor elke regel van de data die geselecteerd is op jaar, wordt een functie uitgevoerd. Al in het vorige object wordt gespecifieerd dat het om de fotograaf gaat.

Data in de DOM injecteren

Door de diepe nesting van de objecten in de arrays gebruik ik een forEach, nog een forEach en dan een .push om de uitkomst buiten de laatste forEach te kunnen gebruiken.

items.forEach(function(obj, i) {
                    objects.push({
                        image: obj.img.value,
                        description: obj.description.value,
                        title: obj.title.value,
                        source: obj.cho.value,
                        serie: serieValue[i],
                        creator: obj.creator.value
                    })
                })

Op deze manier zijn alle values uit de dataset verbonden aan elementen die communiceren met de HTML via Transparency.

Transparency.render(document.getElementById('section'), objects, directive)
            var loader = document.querySelectorAll('#loader');
            loader.forEach(function(i){
                i.classList.add("hidden")
            })

Onder de render van Transparency wordt de loader aangeroepen. Pas als de Transparency regel is verwerkt, zet hij de "hidden" class op de loader, zodat deze alleen zichtbaar is wanneer de afbeeldingen nog ontbreken.

De serie eruit filteren

In het bovenstaande stukje code refereert het element serie naar dit object:

filterSerie: function (item) {
            var serieObj = item.description.value;
            var findSerie = /uit de serie '(.*?)'/g;
            var serie = findSerie.exec(serieObj);
            if (!serie) {
                return;
            } else {
                console.log(1, serie[1])
                return serie[0]
            }
        }

De precieze zoekterm wordt opgeslagen in een variabele en deze wordt met .exec verbonden aan de description van de afbeelding. Wanneer deze overeenkomt, staat de afbeelding gelijk aan serie. Wanneer dit niet zo is, krijgt de regel niks terug en blijft dus leeg. Als de afbeelding hier wel mee overeen komt, vraagt de functie de eerste regel van het object terug. Dit wordt geinjecteerd in de HTML.

Features

Licence

All the rights go to Stadsarchief Amsterdam for the images. All rights for features used in the library go to W3 Sparql. Copyright © 2018 Leonie Smits. Released under the MIT license