地震情報サイト

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>地震情報 - 完全版</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: var(--bg-color, #ffffff);
            color: var(--text-color, #000000);
            transition: background-color 0.3s, color 0.3s;
        }
        .container {
            max-width: 1200px;
            margin: 20px auto;
            padding: 20px;
            background: var(--card-bg, #ffffff);
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }
        h1 {
            text-align: center;
        }
        #map {
            height: 400px;
            margin-top: 20px;
        }
        .toggle-dark-mode {
            position: fixed;
            top: 10px;
            right: 10px;
            padding: 10px;
            background: #007BFF;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        @media (max-width: 768px) {
            .container {
                padding: 10px;
            }
        }
    </style>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <button class="toggle-dark-mode" onclick="toggleDarkMode()">ダークモード切り替え</button>
    <div class="container">
        <h1>地震情報</h1>
        <div id="quakeStats">
            <canvas id="intensityChart" width="400" height="200"></canvas>
        </div>
        <div id="map"></div>
        <div id="regionData"></div>
    </div>

    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
    <script>
        const rssUrl = 'https://www.jma.go.jp/bosai/quake/data/list.xml';
        let quakeData = [];
        const regions = {};

        const map = L.map('map').setView([35.6895, 139.6917], 5);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

        async function fetchEarthquakeData() {
            try {
                const response = await fetch(`https://api.allorigins.win/get?url=${encodeURIComponent(rssUrl)}`);
                const data = await response.json();
                const parser = new DOMParser();
                const xmlDoc = parser.parseFromString(data.contents, "text/xml");

                const items = xmlDoc.getElementsByTagName('item');
                quakeData = [];

                for (let i = 0; i < items.length; i++) {
                    const title = items[i].getElementsByTagName('title')[0].textContent;
                    const description = items[i].getElementsByTagName('description')[0].textContent;
                    const pubDate = items[i].getElementsByTagName('pubDate')[0].textContent;

                    const match = description.match(/震源地:(.+?)、緯度:(.+?)、経度:(.+?)、震度:(.+?)、/);
                    if (match) {
                        const location = match[1];
                        const lat = parseFloat(match[2]);
                        const lng = parseFloat(match[3]);
                        const intensity = parseFloat(match[4]);

                        quakeData.push({ title, location, lat, lng, intensity, pubDate });
                        if (!regions[location]) {
                            regions[location] = [];
                        }
                        regions[location].push({ intensity, pubDate });
                    }
                }

                displayQuakeData();
                updateChart();
            } catch (error) {
                console.error('地震情報の取得に失敗しました:', error);
            }
        }

        function displayQuakeData() {
            map.eachLayer(layer => {
                if (layer.options && layer.options.pane === "markerPane") {
                    map.removeLayer(layer);
                }
            });

            quakeData.forEach(quake => {
                L.circle([quake.lat, quake.lng], {
                    color: 'red',
                    fillColor: '#f03',
                    fillOpacity: 0.5,
                    radius: quake.intensity * 10000
                }).addTo(map)
                .bindPopup(`<strong>${quake.title}</strong><br>震源地: ${quake.location}<br>震度: ${quake.intensity}`);
            });
        }

        function updateChart() {
            const ctx = document.getElementById('intensityChart').getContext('2d');
            const labels = quakeData.map(q => q.pubDate);
            const intensities = quakeData.map(q => q.intensity);

            new Chart(ctx, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: [{
                        label: '震度',
                        data: intensities,
                        borderColor: 'rgba(255, 99, 132, 1)',
                        borderWidth: 2,
                        fill: false
                    }]
                }
            });
        }

        function toggleDarkMode() {
            const isDarkMode = document.body.style.getPropertyValue('--bg-color') === '#ffffff';
            document.body.style.setProperty('--bg-color', isDarkMode ? '#333333' : '#ffffff');
            document.body.style.setProperty('--text-color', isDarkMode ? '#ffffff' : '#000000');
            document.body.style.setProperty('--card-bg', isDarkMode ? '#444444' : '#ffffff');
        }

        fetchEarthquakeData();
        setInterval(fetchEarthquakeData, 60000); // 1分ごとに更新
    </script>
</body>
</html>

投稿者: chosuke

趣味はゲームやアニメや漫画などです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です