# CLAUDE.md

Development guidelines for the Mapbox Globe Visualization project.

## Running the Visualization

### Local Development Server

Start a local server from the project root:

```bash
# Python 3 (recommended)
python -m http.server 8000

# Python 2
python -m SimpleHTTPServer 8000

# Node.js
npx http-server -p 8000

# PHP
php -S localhost:8000
```

Open browser to: `http://localhost:8000`

### Mapbox Token Setup

**IMPORTANT**: Before running, replace the placeholder token in `src/index.js`:

```javascript
// Line 5 in src/index.js
mapboxgl.accessToken = 'YOUR_ACTUAL_MAPBOX_TOKEN';
```

Get a free token at: [https://account.mapbox.com/](https://account.mapbox.com/)

## Code Guidelines

### JavaScript Style
- **ES6+ syntax**: Use modern JavaScript features
- **Naming conventions**:
  - camelCase for variables and functions
  - PascalCase for classes
  - UPPER_CASE for constants
- **Comments**: Explain "why" not "what"
- **Async patterns**: Use async/await where appropriate

### Mapbox-Specific Notes

#### Globe Projection
```javascript
// Always specify projection for globe view
const map = new mapboxgl.Map({
    projection: 'globe',  // Required for 3D globe
    // ... other options
});
```

#### Coordinate Order
GeoJSON uses `[longitude, latitude]` order (NOT lat/lng):
```javascript
"coordinates": [139.6917, 35.6895]  // Tokyo: [lng, lat]
```

#### Layer Management
```javascript
// Always check if source exists before adding layer
if (!map.getSource('my-source')) {
    map.addSource('my-source', { /* ... */ });
}

// Remove layers before sources
if (map.getLayer('my-layer')) {
    map.removeLayer('my-layer');
}
if (map.getSource('my-source')) {
    map.removeSource('my-source');
}
```

#### Event Handling
```javascript
// Use 'load' event for initial setup
map.on('load', () => {
    // Add sources and layers here
});

// Use 'style.load' for style-dependent features
map.on('style.load', () => {
    // Configure fog, terrain, etc.
});
```

### Data Patterns

#### GeoJSON Structure
```javascript
const data = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [lng, lat]  // Note order!
            },
            "properties": {
                // Custom properties here
            }
        }
    ]
};
```

#### Expression Syntax
```javascript
// Interpolation for continuous values
'circle-radius': [
    'interpolate',
    ['linear'],           // Interpolation type
    ['get', 'value'],     // Property to interpolate
    0, 5,                 // value: 0 -> radius: 5
    100, 20               // value: 100 -> radius: 20
]

// Step function for discrete values
'circle-color': [
    'step',
    ['get', 'category'],
    '#blue',              // default
    'A', '#red',          // category A
    'B', '#green'         // category B
]
```

## Project Structure

```
mapbox_globe_1/
├── index.html              # Main entry point
│   ├── Mapbox GL JS CDN links
│   ├── UI overlay elements (title, legend, info)
│   └── Script imports
│
├── src/
│   ├── index.js           # Main application logic
│   │   ├── Map initialization
│   │   ├── Globe configuration (fog, projection)
│   │   ├── Data layer setup
│   │   ├── Interaction handlers
│   │   └── Auto-rotation logic
│   │
│   └── data/
│       └── population-data.js  # GeoJSON data
│           └── 100 city features with properties
│
├── README.md              # User documentation
└── CLAUDE.md              # This file (dev guidelines)
```

## Common Tasks

### Adding New Data Points
Edit `src/data/population-data.js`:
```javascript
{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [lng, lat]
    },
    "properties": {
        "city": "City Name",
        "country": "Country",
        "population": 1000000,
        "year": 2024
    }
}
```

### Modifying Visual Style

#### Change Circle Colors
Edit `src/index.js`, find `circle-color` property:
```javascript
'circle-color': [
    'interpolate',
    ['linear'],
    ['get', 'population'],
    1000000, '#new-color-1',
    30000000, '#new-color-2'
]
```

#### Adjust Circle Sizes
Edit `src/index.js`, find `circle-radius` property:
```javascript
'circle-radius': [
    'interpolate',
    ['linear'],
    ['get', 'population'],
    1000000, 6,    // Increase from 4
    30000000, 30   // Increase from 24
]
```

#### Change Atmosphere
Edit `src/index.js`, find `map.setFog()`:
```javascript
map.setFog({
    color: 'rgb(255, 255, 255)',        // Lighter atmosphere
    'high-color': 'rgb(100, 150, 255)',  // Different sky color
    'space-color': 'rgb(0, 0, 10)',     // Darker space
    'star-intensity': 0.8               // More visible stars
});
```

### Customizing Rotation

#### Adjust Speed
Edit `src/index.js`, find `startRotation()`:
```javascript
center.lng += 0.5;  // Increase for faster rotation
```

#### Change Duration
```javascript
map.easeTo({
    center: center,
    duration: 1000,  // Decrease for faster, increase for slower
    easing: (t) => t
});
```

#### Disable Auto-Rotation
Comment out in `src/index.js`:
```javascript
// startRotation();  // Disable this line
```

## Performance Optimization

### For Large Datasets (500+ points)
```javascript
// Use clustering
map.addSource('population', {
    type: 'geojson',
    data: populationData,
    cluster: true,
    clusterMaxZoom: 14,
    clusterRadius: 50
});
```

### For Mobile Devices
```javascript
// Reduce circle quality on mobile
const isMobile = window.innerWidth < 768;
'circle-radius': [
    'interpolate',
    ['linear'],
    ['get', 'population'],
    1000000, isMobile ? 3 : 4,
    30000000, isMobile ? 18 : 24
]
```

## Debugging Tips

### Check Map Load Status
```javascript
console.log('Map loaded:', map.loaded());
console.log('Style loaded:', map.isStyleLoaded());
```

### Inspect Layers and Sources
```javascript
console.log('Layers:', map.getStyle().layers);
console.log('Sources:', Object.keys(map.getStyle().sources));
```

### Monitor Events
```javascript
map.on('error', (e) => console.error('Map error:', e));
map.on('dataloading', () => console.log('Data loading...'));
map.on('idle', () => console.log('Map idle'));
```

## API References

- [Mapbox GL JS API](https://docs.mapbox.com/mapbox-gl-js/api/)
- [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/)
- [Mapbox Expressions](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/)
- [GeoJSON Specification](https://datatracker.ietf.org/doc/html/rfc7946)

## Version Information

- Mapbox GL JS: v3.0.1
- GeoJSON: RFC 7946
- Browser: Modern ES6+ support required

## Troubleshooting

### Issue: Map not loading
- Check Mapbox token is valid
- Verify internet connection for CDN resources
- Check browser console for errors

### Issue: Globe not appearing
- Ensure `projection: 'globe'` is set
- Check browser supports WebGL
- Verify style has loaded (`map.isStyleLoaded()`)

### Issue: Circles not showing
- Verify data is valid GeoJSON
- Check coordinates are [lng, lat] order
- Ensure layer is added after map loads

### Issue: Popups not appearing
- Check feature properties exist
- Verify layer ID matches event listener
- Test with `map.queryRenderedFeatures()`

## Contributing Guidelines

When modifying this project:
1. Test on multiple browsers
2. Verify mobile responsiveness
3. Update documentation
4. Check console for errors
5. Test with different data sizes
6. Validate GeoJSON structure
7. Ensure accessibility (ARIA labels, keyboard nav)

## Security Notes

- Never commit Mapbox tokens to version control
- Use environment variables for production
- Implement token rotation for public apps
- Monitor token usage on Mapbox dashboard
