npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

three-tile

v0.5.1

Published

A lightweight tile map using threejs

Downloads

25

Readme

three-tile V0.5

1 简介

three-tile 是一个基于 threejs 的轻量级三维瓦片地图框架,具有使用简单、资源占用少等优点,适用于基于 threejs 开发三维地图应用。

  • three-tile 本质上是一个动态 LOD 模型,核心代码与地图是无关的,适用范围并不仅限于地图,但最典型的应用还是三维地图。

  • three-tile 不是一个 GIS 框架,它并不提供图层管理、空间分析等 GIS 相关功能。正因为如此,它的核心可以做的很轻量级,能轻松集成到已有项目中。

  • three-tile 参考了大量开源 GIS 的开发思路,但仅仅是思路,除了数据源定义,未 copy 一行代码,更不是 Cesium、MapBox 等套壳。

免责声明:

  • 本框架不含任何地图数据,Example 中使用的地图均为直接调用第三方数据,使用中请遵循法律法规要求。
  • Example 中使用的图片和模型,均来自互联网,若涉及版权问题请通知我。

1.1 优点

  • 轻量级:地图以一个三维模型方式提供,不会对你的程序架构产生任何影响。
  • 依赖少:整个框架仅有 threejs(R152)一个依赖。
  • 速度快:对资源占用做极致优化,核显也能轻松跑到 60FPS。
  • 使用简单:熟悉 threejs 基本上没有学习成本。
  • 扩展性强:数据、模型、纹理、材质、渲染过程均能根据自己需要扩展和替换。

1.3 开发环境

  • 语言:TypeScript 100%
  • IDE: VSCode
  • 打包:Vite 4.0
  • 依赖:three^0.152

2 安装

建议使用 typescript 开发,原生 JavaScript 写的代码 BUG 防不胜防,至少使用 ES6。

2.1 直接引用

<script src="./three.js"></script>
<script src="./three-tile.umd.js"></script>

2.2 npm

npm i three-tile -S

https://www.npmjs.com/package/three-tile


3 使用

和一般 threejs 应用一样,初始化 threejs 三维场景后,将地图模型加入场景即可完成地图的显示。

TileMap 类是 three-tile 地图模型,它是一个 Mesh,按 threejs 的套路初始化场景,并将 TileMap 的实例加入场景即可。

为了便于使用,three-tile 还提供一个 GLViewer 类,它封装了场景初始化过程,一般可直接使用它进行初始化。但如果你熟悉 threejs,最好自己写,跟普通 threejs 程序并无太大差异。

3.1 约定和限制

  • 坐标轴:地图模型为东北上坐标系,即 X 轴指向东,Y 轴指向北,Z 轴指向上。与 threejs 默认坐标不同需要注意。
  • 坐标单位:角度单位为弧度,经纬度为度,3857 投影(默认)距离单位为公里,4326 投影距离单位为 0.01 度,高度单位均为公里。
  • 瓦片数据:内建的地图影像和地形数据均使用图片格式(jpg、png、webp 等),支持 3854 和 4326 投影,暂不支持矢量瓦片。
  • 瓦片属性:默认情况瓦片模型纹理透明属性开启,请注意渲染顺序。
  • 地图清晰度:清晰度与本框架无关,取决数据源精度。
  • 地图标注源:大部分国内厂商地图数据的地名、边界、道路有一定偏移,与地形无法完全匹配。
  • 地图 token:大部分厂商的地图数据需要申请开发 key 才能使用,three-tile 示例包含一些厂商的 token,访问的人多了厂商会封掉它们,使用者一定要自己申请(又不要钱)避免直接使用。

3.2 地图创建

一般应用,可使用 TileMap 的工厂方法 create 创建地图,用 GLViewer 初始化三维场景,并将地图加入场景。

import 方式:

import * as tt from "three-tile";

// 取得地图dom容器
const glContainer = document.querySelector<HTMLElement>("#map");
// 初始化三维场景(调用three-tile内置的初始化类)
const viewer = new tt.plugin.GLViewer(glContainer!);

// MapBoxToken 请更换为你自己申请的key
const MAPBOXKEY = "xxxxxxxxxx";

// mapbox 影像数据源
const mapBoxImgSource = new tt.plugin.MapBoxSource({
	token: MAPBOXKEY,
	dataType: "image",
	style: "mapbox.satellite",
});

// mapbox 高程数据源
export const mapBoxDemSource = new tt.plugin.MapBoxSource({
	token: MAPBOXKEY,
	dataType: "terrain-rgb",
	style: "mapbox.terrain-rgb",
	maxLevel: 15,
});

// 创建地图
const map = tt.TileMap.create({
	// 影像数据源
	imgSource: mapBoxImgSource,
	// 地形数据源
	demSource: mapBoxDemSource,
	// 地图投影中心经度
	centralMeridian: 90,
	// 最小缩放级别
	minLevel: 2,
	// 最大缩放级别
	maxLevel: 18,
});

// 将地图加入三维场景
viewer.scene.add(map);

浏览器引入方式:

<!DOCTYPE html>
<html lang="zh-cn">
	<head>
		<meta charset="utf-8" />
		<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;
		}
		#map {
			flex: 1;
		}
	</style>
	<body>
		<div id="map"></div>
		<script src="./three.js"></script>
		<script src="./three-tile/three-tile.umd.cjs"></script>
		<script>
			console.log("three-tile start!");

			// MapBoxToken 请更换为你自己申请的key
			const MAPBOXKEY =
				"pk.eyJ1Ijoic2hhbmUwMjIwNzIiLCJhIjoiY2p5amF6YnFiMDB0YjNkcGU1ZWxoMWl0NiJ9.TsmgK5-HJKWOE-DscbNbTA";

			// mapbox影像数据源
			const mapBoxImgSource = new tt.plugin.MapBoxSource({
				token: MAPBOXKEY,
				dataType: "image",
				style: "mapbox.satellite",
			});
			// mapbox地形数据源
			const mapBoxDemSource = new tt.plugin.MapBoxSource({
				token: MAPBOXKEY,
				dataType: "terrain-rgb",
				style: "mapbox.terrain-rgb",
				maxLevel: 15,
			});

			// 创建地图
			const map = tt.TileMap.create({
				// 影像数据源
				imgSource: mapBoxImgSource,
				// 地形数据源
				demSource: mapBoxDemSource,
				// 地图投影中心经度
				centralMeridian: 90,
				// 最小缩放级别
				minLevel: 2,
				// 最大缩放级别
				maxLevel: 18,
			});

			// 地图中心经纬度转为场景坐标
			const center = map.geo2pos(new THREE.Vector3(108.942, 34.2855));
			const container = document.querySelector("#map");
			const viewer = new tt.plugin.GLViewer(
				container,
				new THREE.Vector3(center.x, center.y, 0),
				new THREE.Vector3(center.x, center.y, 3e4),
			);

			viewer.scene.add(map);

			// 添加地图坐标轴
			const helper = new THREE.AxesHelper(1000);
			helper.position.set(center.x, center.y, 1);
			viewer.scene.add(helper);

			// 动画漫游到3500km高空
			(() => {
				const timer = setInterval(() => {
					const pos = viewer.camera.position;
					pos.z -= 500;
					pos.y -= 10;
					if (pos.z < 100) {
						clearInterval(timer);
					}
				}, 10);
			})();
		</script>
	</body>
</html>

3.3 三维场景

三维场景的初始化与 threejs 的没有太大区别,three-tile 内置一个 GLView 插件,实现三维场景初始化,能满足普通应用,有特殊要求的可以自行实现。需要以下部分需要注意:

  • 为了使地图坐标系与一般人类理解一致,地图坐标方向采用东(x)北(y)上(z)方向,即地面在 x-y 平面上,海拔高度在 z 轴。而 threejs 一般平面在 xz 平面上,高度为 y 轴,所以初始化时需要使场景默认 up 指向 z 轴,可添加:Object3D.DEFAULT_UP.set(0, 0, 1) 即可。如果你的应用不能调整 up 值,可以将地图旋转-π/2° 完成。
  • 地图添加光照才能显示。一般至少要有一个环境光,另外最好加一个直射光以通过地形法向量增强凹凸感。
  • 场景控制器一般应用可使用 threejs 内置的 MapControls,其它控制器如 OrbitControls、FlyControls、PointerLockControls、TransformControls、FirstPersonControls 都能完美支持。

更多使用方法见 example