109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
// import { JsonAsset, BufferAsset, resources } from "cc";
|
|
|
|
type MetaType = {
|
|
MIN_LAT: number;
|
|
MAX_LAT: number;
|
|
MIN_LNG: number;
|
|
MAX_LNG: number;
|
|
STEP_DEG: number;
|
|
ROWS: number;
|
|
COLS: number;
|
|
id2name: Record<string, string>;
|
|
};
|
|
|
|
let _ready = false;
|
|
let _meta: MetaType | null = null;
|
|
let _grid: Uint8Array | null = null;
|
|
let _ID2NAME: Record<number, string> = {};
|
|
|
|
/**
|
|
* 初始化省份定位(游戏启动时调一次)
|
|
* pathJson: resources 下的 json 路径,不含扩展名
|
|
* pathBin: resources 下的 bin 路径,不含扩展名
|
|
*/
|
|
export function initProvinceLocator(
|
|
pathJson: string = "geo/province_names",
|
|
pathBin: string = "geo/province_grid"
|
|
): Promise<void> {
|
|
return new Promise((resolve, reject) => {
|
|
// 1. 先加载 meta json
|
|
cc.resources.load(pathJson, cc.JsonAsset, (err, jsonAsset) => {
|
|
if (err) {
|
|
console.error("[ProvinceLocator] 加载 JSON 失败", err);
|
|
reject(err);
|
|
return;
|
|
}
|
|
//@ts-ignore
|
|
const meta = jsonAsset.json as MetaType;
|
|
|
|
// 2. 再加载二进制网格
|
|
cc.resources.load(pathBin, cc.BufferAsset, (err2, bufAsset) => {
|
|
if (err2) {
|
|
console.error("[ProvinceLocator] 加载 BIN 失败", err2);
|
|
reject(err2);
|
|
return;
|
|
}
|
|
|
|
// BufferAsset 的底层数据在 _nativeAsset 里,是 ArrayBuffer
|
|
const arrayBuffer = (bufAsset as any)._nativeAsset as ArrayBuffer;
|
|
const grid = new Uint8Array(arrayBuffer);
|
|
|
|
_meta = meta;
|
|
_grid = grid;
|
|
_ID2NAME = {};
|
|
for (const k in meta.id2name) {
|
|
_ID2NAME[parseInt(k, 10)] = meta.id2name[k];
|
|
}
|
|
|
|
_ready = true;
|
|
console.log(
|
|
"[ProvinceLocator] 初始化成功,网格大小",
|
|
meta.ROWS,
|
|
"x",
|
|
meta.COLS
|
|
);
|
|
resolve();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 根据经纬度返回省份名称
|
|
* 调用前务必先 initProvinceLocator
|
|
*/
|
|
export function getProvinceName(lat: number, lng: number): string {
|
|
if (!_ready || !_meta || !_grid) {
|
|
console.warn("[ProvinceLocator] 尚未初始化,返回未知");
|
|
return "其他";
|
|
}
|
|
|
|
const {
|
|
MIN_LAT,
|
|
MAX_LAT,
|
|
MIN_LNG,
|
|
MAX_LNG,
|
|
STEP_DEG,
|
|
ROWS,
|
|
COLS,
|
|
} = _meta;
|
|
|
|
if (lat < MIN_LAT || lat > MAX_LAT || lng < MIN_LNG || lng > MAX_LNG) {
|
|
return "其他";
|
|
}
|
|
|
|
let r = Math.floor((lat - MIN_LAT) / STEP_DEG);
|
|
let c = Math.floor((lng - MIN_LNG) / STEP_DEG);
|
|
|
|
// 边界保护
|
|
if (r < 0) r = 0;
|
|
if (r >= ROWS) r = ROWS - 1;
|
|
if (c < 0) c = 0;
|
|
if (c >= COLS) c = COLS - 1;
|
|
|
|
const index = r * COLS + c;
|
|
const pid = _grid[index];
|
|
|
|
if (!pid) return "其他";
|
|
return _ID2NAME[pid] || "其他";
|
|
} |