@three-tile/lib
    Preparing search index...

    @three-tile/lib

    three-tile

    npm version License: MIT

    一个基于 Three.js 开发的轻量级三维瓦片地图库,专为 Three.js 应用程序提供高性能的地图渲染能力。

    • 🚀 轻量级设计 - 仅依赖 Three.js,核显即可流畅运行 60FPS
    • 📦 零侵入集成 - 以 Three.js 对象形式提供,不影响现有架构
    • 🎯 TypeScript 原生支持 - 100% TypeScript 开发,完整类型定义
    • 🔧 高度可扩展 - 模块化加载器系统,支持自定义数据源和渲染
    • Web Workers 优化 - 复杂计算异步处理,保持主线程流畅
    • 🌍 多投影支持 - 支持 WGS84、Web Mercator 等常用投影系统
    • 📊 多数据格式 - 内置 Terrain-RGB、LERC、DEM 等地形加载器
    npm i three-tile -S
    # 或
    yarn add three-tile -S
    • Three.js: >=0.171.0
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
    <meta />
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
    <title>three-tile最小化应用</title>
    </head>
    <style>
    html,
    body {
    background-color: #333;
    height: 100%;
    width: 100%;
    padding: 0;
    margin: 0;
    display: flex;
    overflow: hidden;
    }
    #map {
    height: 100%;
    width: 100%;
    }
    </style>

    <script type="importmap">
    {
    "imports": {
    "three": "https://unpkg.com/three@0.171.0/build/three.module.js",
    "three/addons/": "https://unpkg.com/three@0.171.0/examples/jsm/",
    "three-tile": "https://unpkg.com/three-tile@0.11.10/dist"
    }
    }
    </script>

    <body>
    <div id="map"></div>
    <script type="module">
    import * as THREE from "three";
    import * as tt from "three-tile";
    import { MapControls } from "three/addons/controls/MapControls.js";

    console.log(`three-tile v${tt.version} start!`);

    // 创建场景
    const createViewer = container => {
    const width = container.clientWidth;
    const height = container.clientHeight;

    // scene
    const scene = new THREE.Scene();

    // renderer
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);

    // camera
    const camera = new THREE.PerspectiveCamera(60, width / height, 10, 4e7);
    camera.position.set(0, camera.far / 2, 0);

    // ambient light
    const ambLight = new THREE.AmbientLight(0xffffff);
    scene.add(ambLight);

    // directional light
    const dirLight = new THREE.DirectionalLight(0xffffff);
    dirLight.position.set(0, 5e6, 1e5);
    dirLight.target.position.set(0, 0, -5e6);
    scene.add(dirLight);

    // controls
    const controls = new MapControls(camera, renderer.domElement);
    controls.maxDistance = 2e7;
    controls.minDistance = 10;
    controls.enableDamping = true;
    // add renderer to container
    container.appendChild(renderer.domElement);

    return {
    scene,
    camera,
    renderer,
    controls,
    ambLight,
    dirLight,
    };
    };

    const createMap = () => {
    // 创建影像数据源
    const imgSource = new tt.TileSource({
    url: "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
    dataType: "image",
    minLevel: 0,
    maxLevel: 18,
    });

    // 创建地形数据源(可选)
    const demSource = new tt.TileSource({
    url: "https://server.arcgisonline.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer/tile/{z}/{y}/{x}",
    dataType: "lerc",
    minLevel: 5,
    maxLevel: 13,
    });

    // 创建地图
    const map = tt.TileMap.create({
    // 影像数据源
    imgSource: imgSource,
    // 地形数据源
    demSource: demSource,
    lon0: 90,
    });

    return map;
    };

    // 初始化场景
    const viewer = createViewer(document.querySelector("#map"));
    // 创建地图
    const map = createMap();
    // 地图旋转到xz平面
    map.rotateX(-Math.PI / 2);
    // 地图添加到场景
    viewer.scene.add(map);

    // 动画循环
    viewer.renderer.setAnimationLoop(() => {
    viewer.controls.update();
    viewer.renderer.render(viewer.scene, viewer.camera);
    });
    </script>
    </body>
    </html>

    TileMap 是整个库的核心类,继承自 THREE.Object3D,负责瓦片的加载、渲染和管理。

    const map =  TileMap.create(params: MapParams)
    
    interface MapParams {
    // 影像数据源
    imgSource: ISource[] | ISource;
    // 地形数据源(可选),默认undefined
    demSource?: ISource;
    // 中央子午线经度,默认0
    lon0?: 0 | 90 | -90;
    // 最小缩放级别,默认2
    minLevel?: number;
    // 地图范围 [minLon, minLat, maxLon, maxLat]
    bounds?: [number, number, number, number];
    // 调试级别 0:关闭, 1+:开启,默认0
    debug?: number;
    }

    数据源定义了瓦片数据的获取方式和元数据信息:

    const source = new tt.TileSource(params: SourceOptions );
    
    interface SourceOptions {
    /** 数据类型标识,指示用哪个加载器加载,默认为"image" */
    dataType?: string;
    /** 数据所有者 */
    attribution?: string;
    /** 瓦片最大级别 */
    minLevel?: number;
    /** 瓦片最小级别 */
    maxLevel?: number;
    /** 投影方式,默认3857 */
    projectionID?: ProjectionType;
    /** 图层显示时的透明度,0-1 */
    opacity?: number;
    /* 数据经纬度范围 [minLon,minLat,maxLon,maxLat] */
    bounds?: [number, number, number, number];
    /** 瓦片url模板 */
    url?: string;
    /** 瓦片url子域 */
    subdomains?: string[] | string;
    }
    类/接口 描述 主要方法
    TileMap 地图核心类,继承自 THREE.Object3D geo2world(), world2geo(), getLocalInfoFromScreen(), addEventListener()
    TileSource 数据源类,定义瓦片数据来源 getUrl(), getBounds()
    interface MapParams {
    imgSource: ISource[] | ISource; // 影像数据源
    demSource?: ISource; // 地形数据源(可选)
    lon0?: 0 | 90 | -90; // 中央子午线经度
    minLevel?: number; // 最小缩放级别
    maxLevel?: number; // 最大缩放级别(废弃,自动计算)
    bounds?: [number, number, number, number]; // 地图范围 [minLon, minLat, maxLon, maxLat]
    debug?: number; // 调试级别 0:关闭, 1+:开启
    }
    // 坐标转换
    geo2world(geo: Vector3): Vector3; // 地理坐标转世界坐标
    world2geo(world: Vector3): Vector3; // 世界坐标转地理坐标
    getLocalInfoFromScreen(camera: Camera, pointer: Vector2): LocationInfo | undefined;
    getLocalInfoFromGeo(geo: Vector3): LocationInfo | undefined;
    getLocalInfoFromWorld(pos: Vector3): LocationInfo | undefined;

    // 地图控制
    reload(): void; // 重新加载地图
    update(): void; // 手动更新地图
    addEventListener(type: string, listener: Function): void;
    removeEventListener(type: string, listener: Function): void;
    interface ISource {
    dataType: string; // 数据类型标识 ('image', 'terrain-rgb', 'lerc', 'dem' 等)
    url: string; // URL 模板,支持 {x}, {y}, {z} 占位符
    attribution: string; // 版权信息
    minLevel: number; // 最小级别
    maxLevel: number; // 最大级别
    projectionID: "3857" | "4326"; // 投影系统
    opacity?: number; // 透明度
    transparent?: boolean; // 是否透明
    isTMS?: boolean; // 是否为 TMS 服务
    bounds?: [number, number, number, number]; // 数据范围 [minLon,minLat,maxLon,maxLat]
    getUrl(x: number, y: number, z: number): string | undefined;
    }
    // 地图事件类型
    type MapEventTypes = "ready" | "tile-loaded" | "tile-unloaded" | "update";

    // 监听地图事件
    map.addEventListener("ready", () => {
    console.log("地图就绪");
    });

    map.addEventListener("tile-loaded", event => {
    console.log("瓦片加载完成:", event.tile.x, event.tile.y, event.tile.z);
    });

    map.addEventListener("update", () => {
    console.log("地图更新");
    });
    import {
    waitFor, // 等待条件成立
    registerImgLoader, // 注册影像加载器
    registerDEMLoader, // 注册地形加载器
    getImgLoader, // 获取影像加载器
    getDEMLoader, // 获取地形加载器
    getTileLoaders, // 获取所有加载器
    } from "three-tile";

    // 等待地图就绪
    await waitFor(() => map.isReady);

    // 获取特定类型的加载器
    const imageLoader = getImgLoader<TileImageLoader>("image");
    const terrainLoader = getDEMLoader<TerrainRGBLoader>("terrain-rgb");

    // 获取所有加载器信息
    const loaders = getTileLoaders();
    console.log("影像加载器:", loaders.imgLoaders);
    console.log("地形加载器:", loaders.demLoaders);
    interface LocationInfo extends Intersection {
    location: Vector3; // 经纬度信息 (经度, 纬度, 高度米)
    // 继承自 Intersection:
    // - distance: 射线投射原点和相交部分之间的距离
    // - point: 相交部分的点(世界坐标)
    // - face: 相交的面
    // - faceIndex: 相交的面的索引
    // - object: 相交的物体
    // - uv: 相交部分的点的 UV 坐标
    // - normal: 交点处的内插法向量
    }

    感谢以下开源项目的启发和支持:

    • Three.js - 强大的 3D 图形库,本项目的基础
    • Mapbox Martini - 优秀的地形网格算法
    • Cesium - 专业的 3D 地球引擎,提供了很多设计灵感
    • Mapbox GL JS - 矢量瓦片渲染技术参考
    • Leaflet - 轻量级地图库,API 设计参考
    • Geo-three - Three.js 地球引擎,架构参考

    注意: 本库不含任何地图数据,示例中使用的地图数据均为第三方服务,使用时请遵守相关法律法规和版权要求。

    • 使用商业地图数据时请遵守相应服务商的条款
    • 自定义数据源的使用请确保拥有合法授权

    Made with ❤️ by Guo Jiangfeng