Mumu Li n3xta
v2.0.0-20260926
← Project notes

BrooklynđŸ’©PoopđŸ’©Map

Project is live here:

Screenshots

Inspiration

Initially I wanted to make a proper, respectable community page, like the one I pitched in my proposal. A landing page for the IMA/ITP Open Source Club, a hub for discussions, events, code repositories, all that good stuff. I had a few ideas for interactive elements, maybe a real-time project showcase, maybe some kind of collaborative coding space. Then I talked to Yu, the current club president, and turns out they don’t really need it. And to be honest, neither do I
 The more I thought about it the more it felt painfully dull.

So I kept walking, thinking maybe there was a way to make open source club interesting. Maybe I just wasn’t thinking hard enough, maybe there was something I could do to make it feel alive, maybe
 and then I stepped in it. Full weight full force no warning no time to react it just happened I looked down and my shoe was gone not literally but spiritually that shoe was finished and I stood there watching my life choices collapse around me thinking about how I got to this exact point in time and space and suddenly it was so clear so obvious like the universe had been trying to tell me something this entire time and I just wasn’t listening

Forget open source club, forget community landing pages, I’m making a Brooklyn Poop Map

Creating the Community

My original vision was that The Watch Your Step Society (TWYSS) would be a fictional community. But technically speaking, anyone who pins a poop location is an instant member. So, that’s how TWYSS became this half-imaginary, half-very-real collective.

  • Insiders: The people who actively submit sightings, read the stats, and basically treat this like a communal vigil. They’re my main focus. For them, I want a straightforward, no-bullshit layout, something that feels almost like reading a daily newspaper.
  • Outsiders: They might stumble in out of sheer curiosity or necessity (like stepping in something and deciding they never want that experience again).

References

are.na has been a huge help! I’ve basically dumped everything in there.

BrooklynđŸ’©PoopđŸ’©Map | Are.na

The San Francisco Poop Map

The OG concept: crowdsourcing and mapping where human waste is spotted on the streets.

A strong civic horror angle, it exposes urban neglect, inequality, and crumbling infrastructure.

Can BKMP adopt a similar government-shaming* function? Maybe an automatic report function that emails 311?

*Government Shaming

“Eric Adams slashed city budgets at the end of last year and the Department of Sanitation is now implementing a 3 percent cut. Along with axing community composting programs and delaying brown bin pickup, the department will be reducing its sidewalk trash can collection service by 40 percent. “

Crime Mapping

The SF Poop Map won’t tell you what’s actually there or why it was marked, so I took inspiration from this:

The New Inquiry

But here comes the horror story. I bookmarked this last year and now found out It’s gone. It’s wiped clean. And we don’t ask, we don’t speak, we don’t know. Here, have a screenshot.

Useless Websites

The Useless Web

collection of sébastien de ganay, paper toilet .com by rafaël rozendaal, 2006

This paper towel made me realize that we need something that grows, something that stimulates our brains, so I need to make a counter. And also, because poop itself is useless but important.

Honestly, I don’t even care if this thing is “useful” or not. I just want to entertain the shit on the streets. If it changes something, great, however the shoe is already gone and there’s no getting it back


Design Mood Board

I’m leaning into a design language that says both “public service announcement” and “check this out, it’s weird.”

Newspaper + Grids

Newspapers: I want it to give an official vibe. They report, they archive, they tell you what’s happening whether you like it or not. I eventually added a grid at the background becuase I want this to feel like it’s running on pure urban logic.

I also like this hand-drawn style map better than the default OpenStreetMap color scheme. I’ll get to how I achieved the final effect later in the Process part.

poop pin

I wanted this poop pin to happen from the very start.


Sitemaps & Wireframes

graph TD;
  A[Home Page] -->|Read about the project| B[About the Community];
  A -->|See statistics| C[Poop Count];
  A -->|Navigate to Report Page| D[Report Poop];
  A -->|View existing reports| E[Map View];

  D -->|Select location| F[Use the Map];
  D -->|Describe the sighting| G[Write a Report];
  D -->|Submit report| H[Send it in];

  E -->|See reported locations| I[View Map Data];
  E -->|Go back home| A;
  E -->|Report a new sighting| D;

Process

At first I focused on getting something functional rather than perfect. The goal was to make it work first & refine later.

Once I had the basic map up and running I got obsessed with small details**,** things like how reports should be displayed, making the UI feel seamless, and making sure interactions felt natural.

Map styling

Why I Switched from OpenStreetMap to MapTiler

I started with OpenStreetMap since it’s free and widely used and Sam recommended it. But pretty quickly, I ran into some issues:

  • OSM’s default tiles weren’t quite fitting the black-and-white, print-like aesthetic I wanted.
  • Customizing styles was possible, but required setting up TileServer or using third-party styling tools, which felt like overkill for what I needed.

How I Used MapTiler & the Toner Style

I switched to MapTiler because it let me easily customize map styles while keeping everything lightweight and API-based.

  • Toner Style:

    • This is a high-contrast, blackand-white map style originally from Stamen Design.
    • It fits perfectly with my project’s newspaper-inspired layoutgrid
    • It removes unnecessary distractions like satellite imagery or excess colors

In map.js, I use MapTiler’s API and set the map’s base layer to Toner:

L.maptilerLayer({
  style: `https://api.maptiler.com/maps/toner-v2/style.json?key=${MAPTILER_API_KEY}`
}).addTo(map);

Geolocation Handling for Submissions

Users should be able to submit reports by either clicking on the map or using their real-time geolocation. This needs to work across different devices and browsers.

This is super helpful:

  • Leaflet.js handles map interactions (initSelectionMap in map.js).
  • Implemented an event listener on map clicks to place a marker and update hidden form fields with latitude/longitude values. in the js file
  • Added a geolocation button that triggers navigator.geolocation.getCurrentPosition(). If permission is granted, the map centers on the user’s location and places a marker.
  • Fallback: If geolocation is not supported or denied, users manually drop a pin.

Rendering Reports Dynamically on the Map

The map must dynamically display all reported locations with popups that show user-provided descriptions and images.

  • On page load (window.onload in map.js), it fetches reports via /api/reports and updates the #poop-counter dynamically.

  • Used Leaflet markers (addPoopMarkers()) to plot each report (I’m glad it’s cutomizable, so I can use the poop emoji)

  • Each marker gets a popup with the user’s description, a photo (if uploaded), and a timestamp.

  • If fetching fails, it initializes the map with an empty dataset to avoid breaking the UI.

Poop Report Counter

One feature I really wanted to implement (if you’re wondering why, check the references) is the poop report counter. The number of documented poop sightings (poopCount in index.ejs and #poop-counter in map.ejs) should update dynamically as reports are submitted.

My solution is to fetch reports on page load:

  • When the /map page loads, fetch('/api/reports') retrieves all submitted reports from the backend.
  • The length of the returned array determines the poop count, which updates #poop-counter dynamically.

map.ejs Layout Design

This page went through a lot of iterations. At first, because I set a fixed width for the content in layout.ejs, the map couldn’t fully expand. This was restrictive and didn’t look great.

I fixed this by making it absolute but It still looks weird.

I decided to go back to the SF Poop Map style and just make it fullscreen. The map view should take up the full screen while hiding unnecessary UI elements when navigating to /map.

To do this:

  • Added a body.map-fullscreen-mode class in styles.css that hides the header, nav, and footer while expanding the map container to 100% width/height.
  • The function enableFullscreenMapMode() in map.js detects if the user is on /map and applies this class dynamically.
  • Created a floating control panel (.map-controls in styles.css) for navigation and report submission without breaking fullscreen mode.

After all the whole point is to display the map properly

Styling Details

One of the first things I noticed was that the navigation felt a bit lacking—there was no way to tell which tab was currently active. And that bugged me. I kept thinking, “Shouldn’t the current tab be highlighted?” Besides, it would make the whole layout feel more balanced.

This turned out to be a slightly bigger challenge than I expected. The final solution involved adding a function in map.js (highlightCurrentNavLink()) that checks window.location.pathname and assigns the .nav-link-active class to the corresponding <a> element. Then in CSS, .nav-link-active sets a black background and white text to differentiate it. Simple, but effective.

Poopy Highlighter

Invert (headline, Q&A, etc)

Making it feel like a newspaper header. Also for visual balance

Button Interaction

They start as white with a black border, but when hovered over, they invert to a fully black button with white text.

Grid bg

Other Resources

Future Improvements

Originally I wanted to implement a locked region like SF Poop Map, so the map would stay focused on Brooklyn. But because I’m using MapTiler API, I never fully figured this out. As a result the current functionality technically makes this a worldwide poop map instead of a bk poop map.

(So yeah my friends all the way in Shanghai can contribute too.)

Also if I learn how to add user authentication, I could create a ranking system (anonymously). Imagine a “Top Poop Reporters” board.

For now though it’s still an open world poop mapđŸ’©

Thank You for Reading

if you are reading + { THIS },I want to say [thank;you]

You are about to enter the creative side of me

You’re about to leave the Index for the other half of my work: motion, sound, generative pieces and games.

⚠ Photosensitivity warningThe Studio uses flashing images, fast cuts and stepped animation. If flashing light affects you, stay on the Index.