SI25 Urban Small Talk

From XPUB & Lens-Based wiki
Ust-sticker(1).png

Urban Small Talk

Description:

Close your eyes, take a breath… the ambience has something to say. URBAN SMALL TALK is a digital archive of field recordings collected around Rotterdam, offering a new perspective into experiencing the city. Take a stroll around the soundmap and reconnect with Rotterdam, whether you are a fresh acquaintance or an old friend.
Urbansmalltalk1.png

Cookbook

change of plans

Initial Steps taken

  1. Signed up to UMAP and created a new map
  2. Customized the map, centered it on Rotterdam
  3. Created a csv file on cerealbox, where the data would go
  4. Linked the csv file to the UMAP
  5. Created HTML page on the cerealbox and embeded the map

Version 1

Next Steps:

Scrapped the whole thing, unfortunately. I started from scratch, following this documentation: OpenLayers Simple Example
and then moved on to leafletjs.com

Latest Version

the map on browser v0000
current layout

Eleni used leaflet js library to write a snippet of code and use a .csv file as the database which can be found here: https://pzwiki.wdka.nl/mediadesign/User:Eleni/Special_Issue_25/Soundmap/Data

This is how the code looks like right now:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  
  <title>Urban Small Talk</title>
  
  <link rel="stylesheet" href="style.css">

  <meta charset="UTF-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
  integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
  crossorigin=""/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js">
  </script>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.4.1/papaparse.min.js" integrity="sha512-dfX5uYVXzyU8+KHqj8bjo7UkOdg18PaOtpa48djpNbZHwExddghZ+ZmzWT06R5v6NSk3ZUfsH6FNEDepLx9hPQ==" crossorigin="anonymous" referrerpolicy="no-referrer">
  </script>
  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
  integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
  crossorigin="">
  </script>
  <script src="https://unpkg.com/leaflet@latest/dist/leaflet.js"></script>
  <script src="https://unpkg.com/leaflet-providers@latest/leaflet-providers.js"></script>

  <title>Document</title>
</head>

<body>

  <button id="superbutton" data-dialog="dialogOne">About the project</button>
  
  <!-- info popup -->
  <dialog id="dialogOne">
    <h2>Close your eyes,<br>take a breath… </h2>
    <p>The ambience has something to say. <span style="font-size: 1.1em; color:#161616;">Urban Small Talk</span> is a digital archive of field recordings collected around Rotterdam, offering a new perspective into experiencing the city. Take a stroll around the soundmap and reconnect with Rotterdam, whether you are a fresh acquaintance or an old friend.</p>
    <p><span style="font-size: 1.1em; color:#161616;">What would happen if Rotterdam heard you?</span> Would the city change? Would your existence in it change? <span style="font-size: 1.1em; color:#161616;">Does Rotterdam hear you?</span> How can you tell? If so, where are you heard? If not, where would you want to be heard?<span style="font-size: 1.1em; color:#161616;">If you could speak with Rotterdam,</span> how would the conversation go? Do you make the city yours by recording it? When has the city recorded you? If you can't communicate with sound, how else can you? <span style="font-size: 1.1em; color:#161616;">Does Rotterdam understand you?</span> Where does Rotterdam understand you? <span style="font-size: 1.1em; color:#161616;">Do you understand Rotterdam?</span> Where do you understand Rotterdam? <span style="font-size: 1.1em; color:#161616;">How do you defy the city?</span> How does the city defy you?</p>
    <button class="closeDialog">x</button>
  </dialog>

  <!-- urban small talk png -->
  <div class="pic" onmouseover="document.getElementById('xpub').style.display = 'block';" onmouseleave="document.getElementById('xpub').style.display='none';">
    <img src="resources/pic.png"/>
  </div>
  <!-- the xpub that appears on hover -->
  <div id="xpub">
    <img src="resources/xpub.png">
  </div>

  <!-- map div -->
  <div id="map"></div>
  <script>
  // setting the center of the map
    var map = L.map('map').setView([51.924444, 4.469444], 13);
    L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
      minZoom: 11,
	    maxZoom: 22,
      attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
  }).addTo(map);

  // Read markers data from data.csv
  $.get('data.csv', function(csvString) {

  // console.log(csvString);

  // Use PapaParse to convert string to array of objects
  var data = Papa.parse(csvString, {header: true, dynamicTyping: true}).data;

  // For each row in data, create a marker and add it to the map
  for (var i in data) {
    if(i != 0){
      var row = data[i];
    console.log(row['']); // gets title
    console.log(row.__parsed_extra) //this is the object data

    // code from https://gist.github.com/uafrazier/d589caa322f1b1e7c651
    var customPopup = "<h2>"+row['']+"</h2><p>"+row.__parsed_extra[0]+"</p>"+"<audio id='player' controls>"+row.__parsed_extra[3]+"<source src='" + row.__parsed_extra[3] + "' type='audio/ogg'>";
    
    // specify popup options 
    var customOptions =
        {
        'maxWidth': '250',
        'minWidth':'150',
        'className' : 'custom'
        }

    // making markers, using parsed data for latitude and longitude
    var marker = L.marker([row.__parsed_extra[1], row.__parsed_extra[2]], {
      opacity: 1,

    // this part is for custom marker icon
    icon: L.icon({
      iconUrl: 'resources/map.png',
      iconSize: [60, 60]
    })
    
    }).bindPopup(customPopup,customOptions).addTo(map);
    }

  }});

  map.attributionControl.setPrefix(
  'View <a href="https://github.com/HandsOnDataViz/leaflet-map-csv" target="_blank">code on GitHub</a>'
  );
  
</script>

<script>
  document.querySelectorAll("[data-dialog]").forEach(button => {
  button.addEventListener("click", ()=> {
    const dialog = document.querySelector(`#${button.dataset.dialog}`);
    dialog.showModal();
    
    document.body.style.overflow = "hidden";
    document.documentElement.style.overflow = "hidden";
    
    dialog.querySelector(".closeDialog").addEventListener("click", () => {
      dialog.close();
      document.body.style.removeProperty("overflow");
      document.documentElement.style.removeProperty("overflow");
    })
  })
})
</script>
  </body>
</html>

One of the issues Eleni had was that the code wouldn't work even though she had everything right. It was:

  <script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

that was missing from the head.

Even though the code provided by leafletjs uses row.Latitude[x], Papaparse has a kind of weird way of making Arrays, hence the row.__parsed_extra[x] weird data names.

style.css
@import url('https://fonts.googleapis.com/css2?family=Montaga');
@import url('https://fonts.googleapis.com/css2?family=Syne+Tactile&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Syne+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');



html, body, #map {
    width: 100%;
    height: 100%;
    margin: 0;
}

body{
    background-color:#555555;
    color: rgb(113, 112, 112);
}

h2{
    text-transform: capitalize;
    font-family: "VT323", monospace;
    font-weight: 400;
    font-style: normal;
    font-size: 2em;
    line-height: 0.8;
}

p{
    font-family: 'Arial', sans-serif;
    font-size: 12px;
    text-align: justify;
    color:rgb(155, 151, 151);
    line-height: 140%;
    font-weight: 100;
}

#map{
    opacity: 80%;
    /* filter: grayscale(1) invert(1); */
    /* sepia(40%); */
}

.pic{
    opacity: 100%;
    position: absolute;
    z-index: 1;
    left:0.5vh;
    bottom:1vh;
    margin: 3vh;
    transition: filter 0.5s ease;
}

.pic img{
    width: 25vw;
    z-index: 2;
}

.pic:hover{
    filter: blur(2px);
}

#xpub{
    position: absolute;
    bottom: 5vh;
    left: 4.5vw;
    display: none;
    z-index: 3;
  }

#xpub img{
    width: 15vw;
}

#player{
    height:18px;
    width:100%;
    mix-blend-mode:lighten;
}

/* popup customization!!!! */

div.leaflet-popup-content-wrapper, .leaflet-popup-tip {
    font-family: 'Arial', sans-serif;
    font-size: 12px;
    line-height: 1;
    background: rgb(54, 51, 51);
    color: #dcd7d7;
    box-shadow: 0 3px 14px rgba(0,0,0,0.4);
    border-radius: 0;
    /* border:solid 2px #000 ; */
    padding: 1px;
    padding-left: 0px;
    padding-right: 0px;
    }

div.leaflet-popup-tip{
    background-color:rgb(54, 51, 51);;
}

.leaflet-container .leaflet-control-attribution {
    filter: invert();
    opacity: 80%;
    color: #6f6f6f;
  }
  .leaflet-container .leaflet-control-attribution a{
    color: #171717;
  }


button {
    background:#ffffff;
    height:2vh;
    width:2vh;
    border:0;
    border-radius:3px;
    color:rgb(54, 51, 51);
    padding:0 10px;
    cursor:pointer;

}

#superbutton{
    background-color: transparent;
    color: #f1f0f0;
    font-family:"vt323";
    font-size: 18px;
    text-decoration: underline;
    position:absolute;
    bottom:30px;
    left: 0;
    right: 0;
    margin: auto;
    width:400px;
    height: 30px;
    z-index: 1000;
    transition: filter 0.2s;
}

#superbutton:hover{
    filter: blur(3px);
}

dialog{
    width:20vw;
    max-height:60vh;
    padding:0px 20px 20px 20px;
    box-shadow:0 0 10px rgba(0,0,0,0.2);
    border: solid 1px rgb(54, 51, 51);;
    border-radius:3px;
    position:relative;  
  }
  
  dialog button{
    position:absolute;
    top:20px;
    right:20px;
    /* padding: 5px; */
    /* background:rgb(54, 51, 51);; */
    color:rgb(54, 51, 51);
    border: 0px;
  }

  ::selection{
    background-color:gainsboro;
  }
data.py
import urllib.request
import json
from bs4 import BeautifulSoup

# wiki api call
url = "https://pzwiki.wdka.nl/mw-mediadesign/api.php?action=parse&page=User:Eleni/Special_Issue_25/Soundmap/Data&format=json"

response = urllib.request.urlopen(url).read()

data = json.loads(response)

#cleaning up the json response
text = data["parse"]["text"]["*"]

#turning response into clean/pretty html
soup=BeautifulSoup(text,'html.parser')

#keeping only the <p> elements
csv = ''.join([p.get_text() for p in soup.find_all('p')])

#cleaning up so that the format is good for csv
csv = csv.replace("\n\n","\n")
csv = csv.replace("  ","")
csv = csv.replace(", ",",")

with open("data.csv", "w") as output:
    output.write(csv)

IRL Map

Imre and Sevgi are working on the map and how we can make it interesting to collect 'sound related memories' during the event.

We are thinking about the physical map, maybe we can use legends as a way to guide the audience into adding their memories to the map.

https://rotterdamkaart.nl/kaart-1936/

https://commons.wikimedia.org/wiki/File:Plattegrond_van_Rotterdam_in_1940_(2).jpg

Legend

If the city could hear me?

questions;

What would happen if Rotterdam heard you?

Would the city change?

Would your existence in it change?

Does Rotterdam hear you? How can you tell?

If so, where are you heard?

If not, where would you want to be heard?

If you could speak with Rotterdam, how would the conversation go?

Do you make the city yours by recording it?

When have the city recorded you?

If you can't communicate with sound, how else can you?

Does Rotterdam understand you/Where does Rotterdam understand you?

Do you understand Rotterdam/Where do you understand Rotterdam?

How do you defy the city?

How does the city defy you?

Can be connected back to issues of belonging, feeling heard by the city, being used by it, hearing it, using it. Existing in a city is an interactive experience. How have you made the city yours, how did you fail? Have the city made you its own property? Do you feel agency, control over, controlled by? Do you shape how you interact with it, or does the city shape your interactions within it? Can be further tied to mobility, can you move around Rotterdam, do you let the city move within you? Are you yourself in Rotterdam, where exactly, which version of yourself are you? How did you let the city change you?

Refs and resources

Protocols for Collective Performance: Radio Broadcast 2

Radio Aporee https://aporee.org/maps/

Leaflet

Leaflet Maps with CSV

DIY Soundmap : https://saralana.xyz/sound-map

Event Rider

Items

- dreaming of a huge touch screen

- A device w internet connection

-a map to pin memories irl, during the expo

legend: stays rest of the map: skeleton of Rotterdam, laid over cork? buy pins

Space

- 1m x 1m

- Internet Connection

- Power outlet for screen

- Headphones - from XML

Time

- Will run asynchronously throughout the event