Skip to content

Mexico City High Capacity Transit Storymap by Zhanchao Yang#30

Open
zyang91 wants to merge 8 commits intoWeitzman-MUSA-JavaScript:mainfrom
zyang91:main
Open

Mexico City High Capacity Transit Storymap by Zhanchao Yang#30
zyang91 wants to merge 8 commits intoWeitzman-MUSA-JavaScript:mainfrom
zyang91:main

Conversation

@zyang91
Copy link

@zyang91 zyang91 commented Oct 4, 2025

Please access the Storymap through the link: https://zyang91.github.io/story-map-Mexico-City/

Submit checklist

  • Pushed latest code to the main branch of your repository
  • Updated the README.md file with a description of your project, and data citations.
  • Linted JS and CSS code
  • Verified a11y of your site
  • Turned on GitHub Pages for the repository and verified that your site works when deployed
  • Submitted a pull request to the original repository in the class organization
  • In the PR title, included your name at least
  • In the PR description, included a brief description of your topic, and your target audience

Brief Description of the topic

This interactive story map explores Mexico City's comprehensive high-capacity transit system, featuring both the Metro and Metrobús (Bus Rapid Transit) networks. Through data visualization and narrative storytelling, the project illustrates how these transportation systems anchor daily life at a metropolitan scale, connecting distant neighborhoods and shaping urban flows across one of the world's largest cities. This project is deployed via GitHub Pages.

Target Audience

  • Urban planning professionals seeking insights into large-scale transit system design and implementation
  • Mexico City residents wanting better to understand their transit system's evolution and future
  • International visitors planning to navigate the city's public transportation

@zyang91
Copy link
Author

zyang91 commented Oct 4, 2025

@mjumbewu, Thank you so much for reviewing. Finally, I made it. Let me know if the links don't work

@zyang91 zyang91 changed the title Mexico City High Capacity transit by Zhanchao Yang Mexico City High Capacity Transit Storymap by Zhanchao Yang Oct 6, 2025
dependabot bot and others added 2 commits November 16, 2025 14:59
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](nodeca/js-yaml@4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Copy link

@mjumbewu mjumbewu left a comment

Choose a reason for hiding this comment

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

Mexico City is on my list of places to go! This is a nice tour of the Metro and I think it would be a good portfolio entry! Just a few notes below.

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Mexico City High Capacity Transit storymap</title>
<link rel="icon" type="image/svg+xml" href="pic/brt-icon.svg" />

Choose a reason for hiding this comment

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

praise: nice ✨ -- details.

@@ -0,0 +1,145 @@
import { SlideDeck } from './slidedeck.js';

const map = L.map('map', {scrollWheelZoom: false}).setView([0, 0], 0);

Choose a reason for hiding this comment

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

suggestion: Sometimes I like the idea of flying in to the place I want to focus on from way out, but if I'm honest, Leaflet can make this annoying because it doesn't fully redraw shapes until movement stops. So a while ago I put together a hack that I use to have Leaflet redraw while it's flying: https://gist.github.com/mjumbewu/01d090346fb3013bc2d1b8f5a27e5e89.

It works with L.SVG if you have just a few features (say, on the order of < 100), and with L.Canvas with a few more (say, on the order of < 1,000 features). Something like Mapbox GL can do this smooth fly with many more features because it uses a lower level rendering system, but Leaflet is fine to do it with relatively few features. Try it with and without this change and see what happens.

Suggested change
const map = L.map('map', {scrollWheelZoom: false}).setView([0, 0], 0);
const SmoothRenderer = L.SVG.extend({
// Override the default _onZoom function, which simply scales the lower
// resolution shapes. Instead, we want to reproject the shapes at each new
// zoom level, as is done by default when zooming ends.
_onZoom: function () {
this._onZoomEnd();
this._update();
}
});
const map = L.map('map', {scrollWheelZoom: false, renderer: new SmoothRenderer()}).setView([0, 0], 0);

Comment on lines +152 to +159
.credits{
font-size:0.5rem;
color:gray;
font-style:italic;
margin-top:-1rem;
margin-bottom:1rem;
display:block;
}

Choose a reason for hiding this comment

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

praise: I like these footnotes on the images.

Co-authored-by: Mjumbe Poe <mjumbewu@gmail.com>
Copilot AI review requested due to automatic review settings December 3, 2025 21:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request submits a student storymap project exploring Mexico City's high-capacity transit system (Metro and Metrobús). The PR replaces template files with a custom scrollytelling implementation featuring interactive maps, narrative content, and data visualizations of the transit network.

Key Changes

  • Custom scrollytelling storymap with 11 narrative slides covering Metro origins, current state, upgrades, rider experience, Metrobús system, integration, equity, climate impact, and future vision
  • Three GeoJSON datasets for Metro lines, Metro stations, and Metrobús corridors with custom styling and tooltips
  • Enhanced SlideDeck class supporting multiple datasets per slide with customizable layer styles and bounds
  • Custom CSS with cover page, responsive design, and enhanced typography using Playfair Display and Lora fonts

Reviewed changes

Copilot reviewed 15 out of 42 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
index.html Main storymap with cover, overview, 11 narrative slides, and acknowledgments section
js/slidedeck.js Enhanced SlideDeck class for managing scroll-based map updates with multiple datasets
js/index.js Map configuration, data loading, and slide-specific visualization options
css/index.css Comprehensive styling with cover page, slides, responsive design, and typography
README.md Complete project documentation with overview, data citations, and technical details
pic/*.svg Custom Metro and BRT icons for visual identity
package-lock.json js-yaml dependency update from 4.1.0 to 4.1.1
.pre-commit-config.yaml Pre-commit hooks configuration for code quality checks
templates/* Removed template files (expected for student submission)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2 to +6

const map = L.map('map', {scrollWheelZoom: false}).setView([0, 0], 0);

// ## The Base Tile Layer
const mapboxKey = 'pk.eyJ1IjoiemhhbmNoYW8iLCJhIjoiY21nYm1mOGNpMTlycTJtb2xuczUwdjY1aCJ9.KRjlJ3Siuf2p0OKSsngcGw';
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

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

The Mapbox API key is publicly exposed in this file. This key should be stored in an environment variable or configuration file that is excluded from version control (e.g., via .gitignore). Public exposure of API keys can lead to unauthorized usage and potential billing issues.

Consider:

  1. Moving the API key to a .env file (and adding .env to .gitignore)
  2. Using a configuration file that's gitignored
  3. Rotating this key since it's now public in the repository history
Suggested change
const map = L.map('map', {scrollWheelZoom: false}).setView([0, 0], 0);
// ## The Base Tile Layer
const mapboxKey = 'pk.eyJ1IjoiemhhbmNoYW8iLCJhIjoiY21nYm1mOGNpMTlycTJtb2xuczUwdjY1aCJ9.KRjlJ3Siuf2p0OKSsngcGw';
import dotenv from 'dotenv';
dotenv.config();
const map = L.map('map', {scrollWheelZoom: false}).setView([0, 0], 0);
// ## The Base Tile Layer
const mapboxKey = process.env.MAPBOX_KEY;
if (!mapboxKey) {
throw new Error('Mapbox API key not found. Please set MAPBOX_KEY in your .env file.');
}

Copilot uses AI. Check for mistakes.
Copy link

Choose a reason for hiding this comment

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

@zyang91 FYI, this is something that would work in a Node.js environment but not in the browser. For your reference, there are ways to keep the key out of the code you check into GitHub directly. For example, you could use a workflow where:

  • You store the key in Github Secrets
  • In your GitHub Pages deployment action you read the secret and dynamically create something like a settings.js file that you import from index.js (i.e. import settings from './settings.js';). For example, here's a sample GH action that AI gave me:
name: Dynamic Settings File

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set dynamic variables from secrets
        id: set_vars
        env:
          MAPBOX_API_KEY: ${{ secrets.MapboxApiKey }}

      - name: Create settings.js
        run: |
          echo "const settings = {" > js/settings.js
          echo "  mapboxApiKey: '${{ env.MAPBOX_API_KEY }}'," >> js/settings.js
          echo "};" >> src/settings.js
          echo "export default settings;" >> js/settings.js

      - name: Verify settings.js content
        run: cat js/settings.js

There are benefits to this:

  1. Technically this does make it slightly more difficult to steal your api key, as it's not available directly in the source repository.
  2. If you did want to rotate your API key, you could do so without modifying your code (and without alerting anyone watching your repository) by just updating your GitHub secret value, and re-running the deploy action.

However, in practice, anyone will be able to go to your app, open up the developer console, and still inspect your JS or your network traffic to grab your API key. So, for most projects it's just not worth the extra overhead of managing the GH secrets.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you so much for the detailed notice. This is pretty interesting!

zyang91 and others added 2 commits December 5, 2025 16:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants