Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Validate camera sync script
run: node --check scripts/sync-cameras.mjs

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
Expand Down
89 changes: 0 additions & 89 deletions .github/workflows/sync-cameras.yml

This file was deleted.

32 changes: 0 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,35 +74,3 @@ The project exposes crawlable resources in addition to the JavaScript camera dir
- `manifest.webmanifest` and `favicon.svg` — app/site identity metadata.

The homepage and detail pages include canonical URLs, social metadata and Schema.org JSON-LD.

## Đồng bộ tọa độ & địa chỉ

`data-camera.json` lưu tọa độ gốc từ `Location.Shape` của nguồn camera TP.HCM:

```json
{
"Latitude": 10.7918902432446,
"Longitude": 106.691054105759
}
```

`scripts/sync-cameras.mjs` thực hiện:

1. Gọi `SearchQuery` với `Publish:true`.
2. Parse AjaxPro `DataTable` và lấy `POINT(longitude latitude)`.
3. Thêm camera mới và cập nhật tọa độ nguồn.
4. Giữ lại camera cũ không còn xuất hiện ở nguồn để review thủ công.
5. Nếu có `VIETMAP_API_KEY`, gọi VietMap Reverse v4 (`display_type=6`) để bổ sung `Address`, `Ward`, `District` và `Province`.
6. Chỉ reverse-geocode camera chưa có địa chỉ hoặc camera có tọa độ thay đổi.

GitHub Actions chạy mỗi 6 giờ và chỉ tạo/update PR `data/auto-sync-cameras` khi `data-camera.json` thực sự thay đổi.

### Repository secrets

Vào **Settings → Secrets and variables → Actions** và thêm:

- `VIETMAP_API_KEY` — API key VietMap. Không được commit key vào repository.
- `HCM_TRAFFIC_COOKIE` — tùy chọn; chỉ cần nếu endpoint nguồn bắt buộc session/cookie khi chạy từ GitHub Actions.

Có thể chạy tay workflow **Sync camera data** và bật `force_geocode` khi muốn reverse-geocode lại toàn bộ camera có tọa độ.

38 changes: 5 additions & 33 deletions camera.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,13 @@ function cameraDistrict(array $camera): string
$canonical = BASE_URL . '/';
$cameraName = 'Không tìm thấy camera';
$district = 'TP.HCM';
$address = '';
$ward = '';
$province = 'Hồ Chí Minh';
$latitude = null;
$longitude = null;
$imageUrl = '';
$related = [];
} else {
$cameraName = trim((string) $camera['CamName']);
$district = cameraDistrict($camera);
$address = trim((string) ($camera['Address'] ?? ''));
$ward = trim((string) ($camera['Ward'] ?? ''));
$province = trim((string) ($camera['Province'] ?? 'Hồ Chí Minh'));
$latitude = isset($camera['Latitude']) && is_numeric($camera['Latitude']) ? (float) $camera['Latitude'] : null;
$longitude = isset($camera['Longitude']) && is_numeric($camera['Longitude']) ? (float) $camera['Longitude'] : null;
$locationText = $address !== '' ? $address : $district . ', TP.HCM';
$pageTitle = 'Camera ' . $cameraName . ' – ' . $district . ' | TP.HCM';
$pageDescription = 'Xem camera giao thông ' . $cameraName . ' tại ' . $locationText . '. Hình ảnh camera được cập nhật tự động để tiện theo dõi tình hình giao thông.';
$pageDescription = 'Xem camera giao thông ' . $cameraName . ' tại ' . $district . ', TP.HCM. Hình ảnh camera được cập nhật tự động để tiện theo dõi tình hình giao thông.';
$canonical = BASE_URL . '/camera.php?id=' . rawurlencode($cameraId);
$imageUrl = BASE_URL . '/proxy.php?id=' . rawurlencode($cameraId);

Expand Down Expand Up @@ -95,20 +84,12 @@ function cameraDistrict(array $camera): string
'about' => [
'@type' => 'Place',
'name' => $cameraName,
'address' => array_filter([
'address' => [
'@type' => 'PostalAddress',
'streetAddress' => $address,
'addressLocality' => $ward !== '' ? $ward : $district,
'addressRegion' => $province,
'addressLocality' => 'Hồ Chí Minh',
'addressRegion' => $district,
'addressCountry' => 'VN',
], static fn ($value): bool => $value !== ''),
...($latitude !== null && $longitude !== null ? [
'geo' => [
'@type' => 'GeoCoordinates',
'latitude' => $latitude,
'longitude' => $longitude,
],
] : []),
],
],
'primaryImageOfPage' => [
'@type' => 'ImageObject',
Expand Down Expand Up @@ -243,12 +224,6 @@ function cameraDistrict(array $camera): string
.content { padding: clamp(18px, 4vw, 30px); }
.eyebrow { color: var(--primary); font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
h1 { margin: 7px 0 10px; font-size: clamp(1.45rem, 4vw, 2.15rem); line-height: 1.25; }
.address-line {
margin: -4px 0 18px;
color: var(--muted);
line-height: 1.6;
}
.address-line strong { color: var(--text); }
.lead { margin: 0; color: var(--muted); line-height: 1.7; }
.meta {
display: flex;
Expand Down Expand Up @@ -322,9 +297,6 @@ function cameraDistrict(array $camera): string
<div class="eyebrow">Camera giao thông TP.HCM</div>
<h1><?= h($cameraName) ?></h1>
<p class="lead"><?= h($pageDescription) ?></p>
<?php if ($address !== ''): ?>
<p class="address-line"><strong>Địa chỉ:</strong> <?= h($address) ?></p>
<?php endif; ?>
<div class="meta">
<span class="pill"><?= h($district) ?></span>
<span class="pill">Mã camera: <?= h(strtoupper(substr($cameraId, -6))) ?></span>
Expand Down
Loading
Loading