阿加莎克里斯月 發表於 2025-11-24 11:39:00

JSAPIThree 地图投影学习笔记:理解坐标系统

<blockquote>
<p>作为一个刚开始学习 mapvthree 的小白,今天要学习地图投影了!听说这个系统可以控制地图的坐标系统,不同的投影方式有不同的效果!想想就好奇!</p>
</blockquote>
<h2 id="第一次听说地图投影">第一次听说地图投影</h2>
<p>今天在文档里看到了"投影"这个词,一开始我还以为是投影仪那种投影,结果查了一下才知道,原来这是地图学里的概念!</p>
<p>文档说地图投影是:</p>
<ul>
<li>将地球表面的地理坐标(经纬度)转换为平面坐标的数学方法</li>
<li>不同的投影方式适合不同的应用场景</li>
<li>选择合适的投影对准确展示地理数据很重要</li>
</ul>
<p><strong>我的理解</strong>:简单说就是把地球这个球面"展开"成平面的方法!就像把橘子皮剥下来摊平一样,不同的剥法会有不同的效果!</p>
<h2 id="第一步为什么需要投影">第一步:为什么需要投影?</h2>
<p>作为一个初学者,我一开始很困惑:为什么需要投影?直接用经纬度不行吗?</p>
<p><strong>我的疑问</strong>:经纬度不是已经很准确了吗?为什么还要转换?</p>
<p>看了文档才知道:</p>
<ul>
<li>经纬度是球面坐标,不能直接在平面上显示</li>
<li>不同的投影方式有不同的特点(有的保持角度,有的保持面积)</li>
<li>选择合适的投影可以让地图更准确、更美观</li>
</ul>
<p><strong>我的理解</strong>:就像拍照一样,不同的角度拍出来的效果不一样,投影就是选择"拍照角度"!</p>
<h2 id="第二步发现引擎支持的投影类型">第二步:发现引擎支持的投影类型</h2>
<p>文档说 mapvthree 支持多种投影方式,我数了数,主要有这几种:</p>
<h3 id="投影-1web-墨卡托投影epsg3857">投影 1:Web 墨卡托投影(EPSG:3857)</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:3857', // Web 墨卡托投影(默认)
    },
});
</code></pre>
<p><strong>我的理解</strong>:这是最常用的网络地图投影,也是引擎的默认投影。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>适合低纬度地区(赤道附近)</li>
<li>高纬度地区会有严重变形</li>
<li>大多数在线地图都用这个投影</li>
</ul>
<p><strong>我的想法</strong>:如果做普通的网络地图,用这个投影就够了!</p>
<h3 id="投影-2ecef-投影epsg4978">投影 2:ECEF 投影(EPSG:4978)</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // ECEF 投影(3D 地球)
    },
});
</code></pre>
<p><strong>我的理解</strong>:ECEF 是地心地固坐标系,是一个三维直角坐标系统。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>能准确表达地球形状</li>
<li>所有区域几乎无形变</li>
<li>适合精确的三维空间定位和计算</li>
<li>是三维数据可视化的理想投影</li>
</ul>
<p><strong>我的想法</strong>:如果做 3D 地球效果,应该用这个投影!</p>
<p><strong>我的尝试</strong>:</p>
<pre><code class="language-js">import * as mapvthree from '@baidumap/mapv-three';

const container = document.getElementById('container');

const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // 3D 地球模式
      center: ,
      range: 30000000, // 很远的距离,能看到整个地球
    },
});
</code></pre>
<p><strong>我的发现</strong>:地图变成了一个球体!可以旋转看整个地球,太酷了!</p>
<p><strong>我的感受</strong>:这个投影真的很适合做 3D 地球效果!</p>
<h3 id="投影-3wgs84-地理坐标系epsg4326">投影 3:WGS84 地理坐标系(EPSG:4326)</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4326', // WGS84 地理坐标系
    },
});
</code></pre>
<p><strong>我的理解</strong>:WGS84 是最常用的地理坐标系统,使用经纬度表示位置。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>全球统一的标准</li>
<li>跨应用数据兼容性最好</li>
<li>经纬度数据需要投影转换才能在平面地图上显示</li>
</ul>
<p><strong>我的想法</strong>:如果数据是经纬度格式,用这个投影比较方便!</p>
<h3 id="投影-4utm-投影">投影 4:UTM 投影</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:32633', // UTM 33N 带
    },
});
</code></pre>
<p><strong>我的理解</strong>:UTM 投影将地球分为 60 个等分带,每个带覆盖 6 度经度。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>能够保持较好的距离和面积比例</li>
<li>适合局部区域的地图</li>
<li>高纬度地区变形较大</li>
</ul>
<p><strong>我的想法</strong>:如果做局部区域的地图,可以考虑用 UTM 投影!</p>
<h3 id="投影-5高斯克吕格投影">投影 5:高斯克吕格投影</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4491', // 高斯克吕格六度带投影
    },
});
</code></pre>
<p><strong>我的理解</strong>:高斯克吕格投影是一种等角投影,角度保持不变,适合进行测量和制图。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>分为六度带和三度带投影</li>
<li>分为标准投影和截取投影</li>
<li>适合中国地区的地图</li>
</ul>
<p><strong>我的想法</strong>:如果做中国地区的地图,可以考虑用这个投影!</p>
<h3 id="投影-6equalearth-投影epsg8857">投影 6:EqualEarth 投影(EPSG:8857)</h3>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:8857', // EqualEarth 投影
    },
});
</code></pre>
<p><strong>我的理解</strong>:EqualEarth 投影是一种等面积投影,面积保持不变。</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>适合进行面积计算和制图</li>
<li>面积比例准确</li>
</ul>
<p><strong>我的想法</strong>:如果要做面积相关的计算,可以用这个投影!</p>
<h2 id="第三步如何设置投影">第三步:如何设置投影</h2>
<p>看到这么多投影类型后,我开始好奇:怎么设置投影?</p>
<p>文档说目标投影只能在引擎初始化时设置,之后不能修改!</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // 设置目标投影
    },
});
</code></pre>
<p><strong>我的理解</strong>:投影必须在创建引擎时设置,创建后不能改。</p>
<p><strong>我的尝试</strong>:</p>
<pre><code class="language-js">import * as mapvthree from '@baidumap/mapv-three';

const container = document.getElementById('container');

// 设置为 3D 地球模式
const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // ECEF 投影
      center: ,
      range: 30000000,
    },
});
</code></pre>
<p><strong>我的发现</strong>:设置后,地图的显示方式完全变了!</p>
<p><strong>我的注意</strong>:投影设置后不能修改,所以要在初始化时就确定好!</p>
<h2 id="第四步理解投影的作用">第四步:理解投影的作用</h2>
<p>看到可以设置投影后,我想:不同的投影会有什么不同的效果?</p>
<p>我试了几个不同的投影:</p>
<pre><code class="language-js">// Web 墨卡托投影(默认)
const engine1 = new mapvthree.Engine(container1, {
    map: {
      projection: 'EPSG:3857',
      center: ,
      range: 10000000,
    },
});

// ECEF 投影(3D 地球)
const engine2 = new mapvthree.Engine(container2, {
    map: {
      projection: 'EPSG:4978',
      center: ,
      range: 30000000,
    },
});
</code></pre>
<p><strong>我的发现</strong>:</p>
<ul>
<li><code>EPSG:3857</code>:平面地图,像普通的地图</li>
<li><code>EPSG:4978</code>:球体地图,像真实的地球</li>
</ul>
<p><strong>我的感受</strong>:不同的投影真的有完全不同的视觉效果!</p>
<p><strong>我的理解</strong>:投影决定了地图的"形状",选择合适的投影很重要!</p>
<h2 id="第五步数据源的投影设置">第五步:数据源的投影设置</h2>
<p>看到可以设置目标投影后,我想:如果我的数据不是经纬度,怎么办?</p>
<p>文档说数据源可以设置自己的投影!</p>
<h3 id="geojson-数据源">GeoJSON 数据源</h3>
<p>对于 GeoJSON 数据,可以在数据中声明 <code>crs</code> 信息:</p>
<pre><code class="language-js">const geojson = {
    type: 'FeatureCollection',
    crs: {
      type: 'name',
      properties: {
            name: 'EPSG:3857', // 声明数据源的投影
      },
    },
    features: [
      // ... 数据
    ],
};

const dataSource = mapvthree.GeoJSONDataSource.fromGeoJSON(geojson);
</code></pre>
<p><strong>我的理解</strong>:在 GeoJSON 中声明 <code>crs</code>,引擎会自动识别并转换。</p>
<p><strong>我的发现</strong>:引擎会自动将数据源的投影转换为目标投影!</p>
<p><strong>我的想法</strong>:这样就不用手动转换坐标了,引擎会自动处理!</p>
<h3 id="dataitem-的投影设置">DataItem 的投影设置</h3>
<p>文档说 <code>DataItem</code> 也支持在属性字段设置 <code>crs</code> 信息。</p>
<p><strong>我的理解</strong>:每个数据项都可以有自己的投影设置。</p>
<p><strong>我的发现</strong>:这样就能处理混合投影的数据了!</p>
<h2 id="第六步底图的投影处理">第六步:底图的投影处理</h2>
<p>看到数据源的投影后,我想:底图的投影怎么处理?</p>
<p>文档说底图的投影由 <code>TileProvider</code> 处理,大部分 <code>TileProvider</code> 内部都能自动处理投影转换!</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // 目标投影是 ECEF
      provider: new mapvthree.BaiduVectorTileProvider(), // 底图 Provider
    },
});
</code></pre>
<p><strong>我的理解</strong>:<code>TileProvider</code> 会自动处理底图的投影转换。</p>
<p><strong>我的发现</strong>:不需要手动设置底图的投影,Provider 会自动处理!</p>
<p><strong>我的想法</strong>:这样就很方便了,不用关心底图的投影问题!</p>
<h2 id="第七步实际应用场景">第七步:实际应用场景</h2>
<p>学到这里,我开始想:不同的投影适合什么场景?</p>
<h3 id="场景-1普通网络地图">场景 1:普通网络地图</h3>
<p>如果做普通的网络地图,用 Web 墨卡托投影:</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:3857', // Web 墨卡托投影(默认)
    },
});
</code></pre>
<p><strong>我的想法</strong>:这是最常用的投影,适合大多数场景!</p>
<h3 id="场景-23d-地球效果">场景 2:3D 地球效果</h3>
<p>如果做 3D 地球效果,用 ECEF 投影:</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // ECEF 投影
      center: ,
      range: 30000000,
    },
});
</code></pre>
<p><strong>我的想法</strong>:这个投影最适合做 3D 地球,效果最真实!</p>
<h3 id="场景-3精确计算">场景 3:精确计算</h3>
<p>如果要做精确的空间计算,用 ECEF 投影:</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:4978', // ECEF 投影,精度高
    },
});
</code></pre>
<p><strong>我的想法</strong>:ECEF 投影精度最高,适合做精确计算!</p>
<h3 id="场景-4面积计算">场景 4:面积计算</h3>
<p>如果要做面积计算,用 EqualEarth 投影:</p>
<pre><code class="language-js">const engine = new mapvthree.Engine(container, {
    map: {
      projection: 'EPSG:8857', // EqualEarth 投影
    },
});
</code></pre>
<p><strong>我的想法</strong>:这个投影面积比例准确,适合做面积相关的计算!</p>
<h2 id="第八步做一个完整的示例">第八步:做一个完整的示例</h2>
<p>我想写一个完整的示例,展示不同投影的效果:</p>
<pre><code class="language-js">import * as mapvthree from '@baidumap/mapv-three';

// 创建多个容器展示不同投影
const container1 = document.getElementById('container1');
const container2 = document.getElementById('container2');

// Web 墨卡托投影(平面地图)
const engine1 = new mapvthree.Engine(container1, {
    map: {
      projection: 'EPSG:3857',
      center: ,
      range: 10000,
    },
});

// ECEF 投影(3D 地球)
const engine2 = new mapvthree.Engine(container2, {
    map: {
      projection: 'EPSG:4978',
      center: ,
      range: 1000000,
    },
});

// 添加一些测试点
const points = [
    , // 北京
    , // 上海
    , // 广州
];

const geojson = {
    type: 'FeatureCollection',
    features: points.map(coord =&gt; ({
      type: 'Feature',
      properties: {},
      geometry: {
            type: 'Point',
            coordinates: coord,
      },
    })),
};

const dataSource = mapvthree.GeoJSONDataSource.fromGeoJSON(geojson);

// 在两个引擎中都添加点
const point1 = engine1.add(new mapvthree.SimplePoint({ size: 20 }));
point1.dataSource = dataSource;

const point2 = engine2.add(new mapvthree.SimplePoint({ size: 20 }));
point2.dataSource = dataSource;
</code></pre>
<p><strong>我的感受</strong>:写一个完整的示例,对比不同投影的效果,感觉很有成就感!</p>
<p><strong>我的发现</strong>:</p>
<ul>
<li>不同的投影有不同的视觉效果</li>
<li>数据会自动转换到目标投影</li>
<li>选择合适的投影很重要</li>
</ul>
<p>虽然代码还很简单,但是已经能展示不同投影的效果了!</p>
<h2 id="第九步踩过的坑">第九步:踩过的坑</h2>
<p>作为一个初学者,我踩了不少坑,记录下来避免再犯:</p>
<h3 id="坑-1投影设置后不能修改">坑 1:投影设置后不能修改</h3>
<p><strong>原因</strong>:不知道投影只能在初始化时设置。</p>
<p><strong>解决</strong>:在创建引擎时就确定好投影方式,之后不能修改。</p>
<h3 id="坑-2数据投影设置错误">坑 2:数据投影设置错误</h3>
<p><strong>原因</strong>:数据源的投影设置错误,导致显示位置不对。</p>
<p><strong>解决</strong>:确保数据源的投影设置正确,或者在 GeoJSON 中正确声明 <code>crs</code>。</p>
<h3 id="坑-3选择了不合适的投影">坑 3:选择了不合适的投影</h3>
<p><strong>原因</strong>:不了解不同投影的特点,选择了不合适的投影。</p>
<p><strong>解决</strong>:根据应用场景选择合适的投影:</p>
<ul>
<li>普通地图:EPSG:3857</li>
<li>3D 地球:EPSG:4978</li>
<li>面积计算:EPSG:8857</li>
</ul>
<h3 id="坑-4高纬度地区变形严重">坑 4:高纬度地区变形严重</h3>
<p><strong>原因</strong>:使用 Web 墨卡托投影显示高纬度地区。</p>
<p><strong>解决</strong>:高纬度地区建议使用 ECEF 投影或其他适合的投影。</p>
<h3 id="坑-5坐标转换问题">坑 5:坐标转换问题</h3>
<p><strong>原因</strong>:数据投影和目标投影不一致,但没有正确设置。</p>
<p><strong>解决</strong>:确保数据源的投影设置正确,引擎会自动转换。</p>
<h2 id="我的学习总结">我的学习总结</h2>
<p>经过这一天的学习,我掌握了:</p>
<ol>
<li><strong>地图投影的作用</strong>:将地球表面的地理坐标转换为平面坐标</li>
<li><strong>引擎支持的投影类型</strong>:
<ul>
<li>Web 墨卡托投影(EPSG:3857)- 默认,适合普通地图</li>
<li>ECEF 投影(EPSG:4978)- 适合 3D 地球和精确计算</li>
<li>WGS84 地理坐标系(EPSG:4326)- 经纬度格式</li>
<li>UTM 投影 - 适合局部区域</li>
<li>高斯克吕格投影 - 适合中国地区</li>
<li>EqualEarth 投影(EPSG:8857)- 适合面积计算</li>
</ul>
</li>
<li><strong>如何设置投影</strong>:在引擎初始化时通过 <code>map.projection</code> 设置</li>
<li><strong>数据源的投影</strong>:可以在 GeoJSON 中声明 <code>crs</code>,引擎会自动转换</li>
<li><strong>底图的投影</strong>:由 <code>TileProvider</code> 自动处理</li>
</ol>
<p><strong>我的感受</strong>:地图投影虽然概念有点抽象,但是用起来其实不难。关键是要理解不同投影的特点,然后根据应用场景选择合适的投影!</p>
<p><strong>下一步计划</strong>:</p>
<ol>
<li>深入学习不同投影的数学原理</li>
<li>尝试在不同投影下做数据可视化</li>
<li>做一个完整的投影对比项目</li>
</ol>
<hr>
<blockquote>
<p>学习笔记就到这里啦!作为一个初学者,我觉得地图投影虽然概念有点抽象,但是用起来其实不难。关键是要理解不同投影的特点,然后根据应用场景选择合适的投影!希望我的笔记能帮到其他初学者!大家一起加油!</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/map-3d-vis/p/19263293
頁: [1]
查看完整版本: JSAPIThree 地图投影学习笔记:理解坐标系统