Files
my_openplace/scripts/import-regions.ts
T
2025-10-02 19:27:15 -07:00

173 lines
4.5 KiB
TypeScript

#!/usr/bin/env tsx
/**
* Import region data from CSV files into the database.
* Run after generating CSVs with scrape_regions.py
*
* Usage: npm run import:regions
*/
import { PrismaClient } from "@prisma/client";
import { readFileSync } from "fs";
import { parse } from "csv-parse/sync";
const prisma = new PrismaClient();
interface RegionRow {
id: string;
city_id: string;
name: string;
number: string;
country_id: string;
flag_id: string;
}
interface TileRow {
tile_x: string;
tile_y: string;
region_id: string;
city_id: string;
region_name: string;
region_number: string;
country_id: string;
flag_id: string;
}
async function importRegions() {
console.log("Importing regions from regions.csv...");
const csvContent = readFileSync("regions.csv", "utf-8");
const records = parse(csvContent, {
columns: true,
skip_empty_lines: true
}) as RegionRow[];
console.log(`Found ${records.length} unique regions`);
let imported = 0;
let skipped = 0;
for (const record of records) {
try {
await prisma.region.upsert({
where: { cityId: Number.parseInt(record.city_id) },
create: {
id: Number.parseInt(record.id),
cityId: Number.parseInt(record.city_id),
name: record.name,
number: Number.parseInt(record.number),
countryId: Number.parseInt(record.country_id)
},
update: {
name: record.name,
number: Number.parseInt(record.number),
countryId: Number.parseInt(record.country_id)
}
});
imported++;
} catch (error) {
console.error(`Error importing region ${record.name}:`, error);
skipped++;
}
}
console.log(`✓ Imported ${imported} regions (${skipped} skipped)`);
}
async function analyzeTileMappings() {
console.log("\nAnalyzing tile mappings from tile_region_mapping.csv...");
const csvContent = readFileSync("tile_region_mapping.csv", "utf-8");
const records = parse(csvContent, {
columns: true,
skip_empty_lines: true
}) as TileRow[];
console.log(`Found ${records.length} tile mappings`);
// Build a map of region tile counts
const regionTileCounts = new Map<number, {
name: string;
tiles: number;
minTileX: number;
maxTileX: number;
minTileY: number;
maxTileY: number;
}>();
for (const record of records) {
const regionId = Number.parseInt(record.region_id);
const tileX = Number.parseInt(record.tile_x);
const tileY = Number.parseInt(record.tile_y);
const existing = regionTileCounts.get(regionId);
if (!existing) {
regionTileCounts.set(regionId, {
name: record.region_name,
tiles: 1,
minTileX: tileX,
maxTileX: tileX,
minTileY: tileY,
maxTileY: tileY
});
} else {
existing.tiles++;
existing.minTileX = Math.min(existing.minTileX, tileX);
existing.maxTileX = Math.max(existing.maxTileX, tileX);
existing.minTileY = Math.min(existing.minTileY, tileY);
existing.maxTileY = Math.max(existing.maxTileY, tileY);
}
}
console.log("\nRegion coverage analysis:");
console.log("Region ID | Region Name | Tiles | Tile X Range | Tile Y Range");
console.log("-".repeat(90));
// Sort by tile count descending
const sorted = [...regionTileCounts.entries()].sort((a, b) => b[1].tiles - a[1].tiles);
for (const [regionId, coverage] of sorted.slice(0, 20)) {
const name = coverage.name.padEnd(24).substring(0, 24);
const xRange = `${coverage.minTileX}-${coverage.maxTileX}`.padStart(15);
const yRange = `${coverage.minTileY}-${coverage.maxTileY}`;
console.log(`${regionId.toString().padStart(9)} | ${name} | ${coverage.tiles.toString().padStart(5)} | ${xRange} | ${yRange}`);
}
if (sorted.length > 20) {
console.log(`... and ${sorted.length - 20} more regions`);
}
console.log("\n📊 This shows which tiles belong to which regions.");
console.log("💡 You can use this data to implement getRegionForCoordinates().");
}
async function main() {
try {
await importRegions();
await analyzeTileMappings();
console.log("\n✅ Import complete!");
console.log("\nNext steps:");
console.log("1. Create a TileRegion lookup table in your database");
console.log("2. Import the tile_region_mapping.csv data");
console.log("3. Update getRegionForCoordinates() to query TileRegion table");
console.log("\nExample Prisma schema addition:");
console.log(`
model TileRegion {
tileX Int
tileY Int
regionId Int
region Region @relation(fields: [regionId], references: [id])
@@unique([tileX, tileY])
}
`);
} catch (error) {
console.error("Error during import:", error);
process.exit(1);
} finally {
await prisma.$disconnect();
}
}
main();