runepic头像
关注

Node 批量下载 Geoscene / ArcGIS 字体(pbf)完整方案

在使用 Geoscene / ArcGIS JS API 开发地图应用时,经常会遇到一个问题:

❗字体资源依赖远程 doc.geoscene.cn,在内网或网络受限环境下无法加载

最终导致:

  • ✔ 点正常显示
  • ❌ 中文标注不显示
  • ❌ TextSymbol 无效

🎯 一、Node 批量下载字体

核心思路:

👉 将远程 fonts 资源批量下载到本地 /public/fonts


📁 二、目标结构

最终项目结构:

public/
  fonts/
    arial-unicode-ms-regular/
      0-255.pbf
      256-511.pbf
      ...
      19968-20223.pbf

⚙️ 三、Node 下载脚本(完整可用)

📜 download-fonts.js

const fs = require("fs");
const path = require("path");
const https = require("https");

// ===== 字体 Unicode 区间(精简+中文覆盖)=====
const ranges = [
  "0-255",
  "256-511",
  "512-767",
  "768-1023",
  "1024-1279",
  "1280-1535",
  "1536-1791",
  "1792-2047",
  "2048-2303",
  "2304-2559",
  "19968-20223",
  "20224-20479",
  "20480-20735",
  "20736-20991",
  "20992-21247"
];

// ===== 字体源 =====
const baseUrl =
  "https://doc.geoscene.cn/resources/fonts/arial-unicode-ms-regular/";

// ===== 输出目录 =====
const outDir = path.resolve(
  __dirname,
  "public/fonts/arial-unicode-ms-regular"
);

fs.mkdirSync(outDir, { recursive: true });

// ===== 下载函数(带重试)=====
function download(url, filePath, retry = 2) {
  return new Promise((resolve) => {
    const file = fs.createWriteStream(filePath);

    https
      .get(url, (res) => {
        if (res.statusCode !== 200) {
          console.log("❌ missing:", url);
          file.close();
          if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
          return resolve(false);
        }

        res.pipe(file);

        file.on("finish", () => {
          file.close();
          console.log("✔", path.basename(filePath));
          resolve(true);
        });
      })
      .on("error", async () => {
        if (retry > 0) {
          console.log("🔁 retry:", url);
          resolve(await download(url, filePath, retry - 1));
        } else {
          console.log("❌ failed:", url);
          resolve(false);
        }
      });
  });
}

// ===== 主流程 =====
async function run() {
  console.log("\n🚀 Start downloading fonts...\n");

  let success = 0;
  let fail = [];

  for (const r of ranges) {
    const url = `${baseUrl}${r}.pbf`;
    const filePath = path.join(outDir, `${r}.pbf`);

    const ok = await download(url, filePath);
    if (ok) success++;
    else fail.push(r);
  }

  console.log("\n======================");
  console.log("🎉 DOWNLOAD COMPLETE");
  console.log("✔ success:", success);
  console.log("❌ failed:", fail.length);

  if (fail.length) {
    console.log("\n⚠ missing ranges:");
    console.log(fail);
  }

  console.log("\n📁 output:", outDir);
}

run();

▶️ 四、使用方法

1️⃣ 放入项目根目录

或者新建空文件夹,执行下载之后将下载的文件拷贝到需要的地方。

download-fonts.js

2️⃣ 执行下载

node download-fonts.js

3️⃣ 输出结果

✔ 0-255.pbf
✔ 19968-20223.pbf
...

⚙️ 七、前端配置

1️⃣ 设置 fontsUrl

import esriConfig from "geoscene/config";

esriConfig.fontsUrl = "/fonts";

2️⃣ TextSymbol 使用

import TextSymbol from "geoscene/symbols/TextSymbol";

const symbol = new TextSymbol({
  text: "朝阳区",
  color: "black",
  font: {
    family: "arial-unicode-ms-regular",
    size: 12
  }
});

🧠 八、关键优化点

✔ 1. 为什么要 Node 下载?

相比手动下载:

方式问题
手动下载易漏文件
浏览器点下载慢 + 不完整
Node脚本✔ 自动化 + 可重复

✔ 2. 为什么要分区间?

Geoscene 使用:

glyph 分片加载机制

Unicode区间 → 对应 pbf 文件

✔ 3. 必须包含中文区间

19968–21247 ✔ 必须

否则:

❌ 中文直接空白(无报错)


🚨 九、常见坑总结

❌ 1. fontsUrl 没配

esriConfig.fontsUrl = "/fonts"; ❌ 必须

❌ 2. 少区间文件

👉 表现:

  • 中文部分缺字
  • 无报错

❌ 3. 仍访问 doc.geoscene.cn

👉 说明:

  • 本地 fonts 没生效

🎯 十、总结

Node 下载字体的核心价值:

👉 将 Geoscene 依赖的远程字体资源本地化

最终实现:

  • ✔ 离线可用
  • ✔ 中文完整显示
  • ✔ 不依赖 doc.geoscene.cn
  • ✔ 企业可部署

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_40694662/article/details/160402397

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--