胜群爱经典 發表於 2025-12-11 15:57:00

JSAPIThree 加载 WMS、WMTS 和通用栅格图学习笔记:标准地图服务与切图规则

<blockquote>
<p>在实际项目中,我们经常需要加载各种标准地图服务,比如 WMS、WMTS,或者自定义的 XYZ 格式瓦片。今天就来学习一下如何在 mapvthree 中使用这些服务,以及理解不同的瓦片切图规则。</p>
</blockquote>
<h2 id="了解标准地图服务">了解标准地图服务</h2>
<p>在 GIS 领域,有几种常见的地图服务标准:</p>
<ul>
<li><strong>WMS(Web Map Service)</strong>:Web 地图服务,通过 HTTP 请求获取地图图片</li>
<li><strong>WMTS(Web Map Tile Service)</strong>:Web 地图瓦片服务,提供预切好的瓦片</li>
<li><strong>XYZ</strong>:通用的瓦片格式,通过 URL 模板直接访问瓦片</li>
</ul>
<p><strong>我的理解</strong>:WMS 是动态生成地图图片,WMTS 和 XYZ 是使用预切好的瓦片,性能更好。</p>
<h2 id="第一步加载-wms-服务">第一步:加载 WMS 服务</h2>
<p>WMS 是 OGC 标准的 Web 地图服务,通过参数化的 HTTP 请求获取地图图片。</p>
<h3 id="基本使用">基本使用</h3>
<pre><code class="language-js">import * as mapvthree from '@baidumap/mapv-three';

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

const engine = new mapvthree.Engine(container, {
    map: {
      center: ,
      range: 500000,
      provider: null,
      projection: 'EPSG:3857',
    },
});

// 添加 WMS 服务
const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMSImageryTileProvider({
      url: 'https://ows.mundialis.de/services/service',
      params: {
            LAYERS: 'TOPO-WMS,OSM-Overlay-WMS',
            SRS: 'EPSG:3857',
            VERSION: '1.1.1',
            WIDTH: 256,
            HEIGHT: 256,
      },
    }),
}));
</code></pre>
<p><strong>我的发现</strong>:WMS 需要配置服务 URL 和请求参数,包括图层名称、坐标系、版本等。</p>
<p><strong>参数说明</strong>:</p>
<ul>
<li><code>url</code>:WMS 服务地址</li>
<li><code>params.LAYERS</code>:要加载的图层名称,多个图层用逗号分隔</li>
<li><code>params.SRS</code>:空间参考系统,常用 <code>EPSG:3857</code>(Web 墨卡托)或 <code>EPSG:4326</code>(WGS84)</li>
<li><code>params.VERSION</code>:WMS 版本,常用 <code>1.1.1</code> 或 <code>1.3.0</code></li>
<li><code>params.WIDTH</code> 和 <code>params.HEIGHT</code>:请求图片的尺寸,通常为 256</li>
</ul>
<h2 id="第二步加载-wmts-服务">第二步:加载 WMTS 服务</h2>
<p>WMTS 是 OGC 标准的 Web 地图瓦片服务,提供预切好的瓦片,性能比 WMS 更好。</p>
<h3 id="基本使用-1">基本使用</h3>
<pre><code class="language-js">const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMTSImageryTileProvider({
      url: 'https://mrdata.usgs.gov/mapcache/wmts?LAYER=sgmc2&amp;TILEMATRIX={z}',
      params: {
            STYLE: 'default',
            TILEMATRIXSET: 'GoogleMapsCompatible',
            VERSION: '1.0.0',
            FORMAT: 'image/png',
      },
    }),
}));
</code></pre>
<p><strong>我的发现</strong>:WMTS 的 URL 中可以使用 <code>{z}</code> 占位符,引擎会自动替换为对应的缩放级别。</p>
<p><strong>参数说明</strong>:</p>
<ul>
<li><code>url</code>:WMTS 服务地址,可以使用 <code>{z}</code>、<code>{x}</code>、<code>{y}</code> 占位符</li>
<li><code>params.STYLE</code>:图层样式</li>
<li><code>params.TILEMATRIXSET</code>:瓦片矩阵集,常用 <code>GoogleMapsCompatible</code></li>
<li><code>params.VERSION</code>:WMTS 版本,通常为 <code>1.0.0</code></li>
<li><code>params.FORMAT</code>:图片格式,如 <code>image/png</code>、<code>image/jpeg</code></li>
</ul>
<p><strong>我的理解</strong>:</p>
<ul>
<li>WMTS 使用预切好的瓦片,加载速度更快</li>
<li>URL 中的占位符会在请求时被替换为实际的瓦片坐标</li>
<li>不同的 WMTS 服务可能有不同的参数要求</li>
</ul>
<h2 id="第三步加载-xyz-格式瓦片">第三步:加载 XYZ 格式瓦片</h2>
<p>XYZ 是最通用的瓦片格式,通过 URL 模板直接访问瓦片,支持各种自定义瓦片服务。</p>
<h3 id="基本使用-2">基本使用</h3>
<pre><code class="language-js">const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://server.arcgisonline.com/ArcGIS/rest/services/' +
            'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    }),
}));
</code></pre>
<p><strong>我的发现</strong>:XYZ 格式使用 <code>{z}/{y}/{x}</code> 占位符,分别代表缩放级别、行号、列号。</p>
<h3 id="切图规则y-和-reversey">切图规则:y 和 reverseY</h3>
<p>不同的瓦片服务可能使用不同的切图规则,主要体现在 Y 轴的起始位置:</p>
<ul>
<li><strong>y(默认)</strong>:Y 轴从左上角开始,向下递增(如谷歌地图)</li>
<li><strong>reverseY</strong>:Y 轴从左下角开始,向上递增(如 TMS 标准)</li>
</ul>
<pre><code class="language-js">// 使用 y 规则(左上角为原点)
const mapView1 = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://example.com/tiles/{z}/{x}/{y}.png',
      // 默认使用 y 规则
    }),
}));

// 使用 reverseY 规则(左下角为原点,TMS 标准)
const mapView2 = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://example.com/tms/{z}/{x}/{reverseY}.png',
      // 使用 reverseY 占位符
    }),
}));
</code></pre>
<p><strong>我的理解</strong>:</p>
<ul>
<li>如果瓦片服务使用左上角为原点(Y 向下递增),使用 <code>{y}</code></li>
<li>如果瓦片服务使用左下角为原点(Y 向上递增,TMS 标准),使用 <code>{reverseY}</code></li>
<li>使用错误的规则会导致瓦片位置错乱</li>
</ul>
<h3 id="tms-示例">TMS 示例</h3>
<pre><code class="language-js">const mapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/tms-bj/{z}/{x}/{reverseY}.png',
      startLevel: 7,
      maxLevel: 12,
    }),
}));
</code></pre>
<p><strong>我的发现</strong>:可以设置 <code>startLevel</code> 和 <code>maxLevel</code> 来限制瓦片的缩放级别范围。</p>
<h2 id="第四步理解切图规则">第四步:理解切图规则</h2>
<p>作为一个初学者,理解切图规则很重要,这决定了瓦片能否正确显示。</p>
<h3 id="坐标系和原点">坐标系和原点</h3>
<p>地图瓦片通常使用两种坐标系:</p>
<ol>
<li>
<p><strong>屏幕坐标系(左上角原点)</strong></p>
<ul>
<li>X 轴:从左到右递增</li>
<li>Y 轴:从上到下递增</li>
<li>原点在左上角</li>
<li>如:谷歌地图、OpenStreetMap</li>
</ul>
</li>
<li>
<p><strong>地理坐标系(左下角原点)</strong></p>
<ul>
<li>X 轴:从左到右递增</li>
<li>Y 轴:从下到上递增</li>
<li>原点在左下角</li>
<li>如:TMS(Tile Map Service)标准</li>
</ul>
</li>
</ol>
<h3 id="如何判断使用哪种规则">如何判断使用哪种规则</h3>
<p><strong>我的经验</strong>:</p>
<ol>
<li>查看服务文档,通常会说明使用的切图规则</li>
<li>如果文档没有说明,可以尝试两种规则,看哪种显示正确</li>
<li>常见的服务:
<ul>
<li>谷歌地图、OpenStreetMap:使用 <code>y</code></li>
<li>TMS 标准服务:使用 <code>reverseY</code></li>
</ul>
</li>
</ol>
<h3 id="瓦片坐标计算">瓦片坐标计算</h3>
<p><strong>我的理解</strong>:</p>
<ul>
<li><code>z</code>:缩放级别,数值越大,地图越详细</li>
<li><code>x</code>:瓦片的列号,从 0 开始</li>
<li><code>y</code>:瓦片的行号,从 0 开始</li>
<li>在缩放级别 z 下,总共有 <code>2^z × 2^z</code> 个瓦片</li>
</ul>
<h2 id="第五步完整示例">第五步:完整示例</h2>
<p>我想写一个完整的示例,展示三种服务的使用:</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: {
      center: ,
      range: 500000,
      provider: null,
      projection: 'EPSG:3857',
    },
});

// 示例 1:WMS 服务
const wmsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMSImageryTileProvider({
      url: 'https://ows.mundialis.de/services/service',
      params: {
            LAYERS: 'TOPO-WMS',
            SRS: 'EPSG:3857',
            VERSION: '1.1.1',
            WIDTH: 256,
            HEIGHT: 256,
      },
    }),
}));

// 示例 2:WMTS 服务
const wmtsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.WMTSImageryTileProvider({
      url: 'https://mrdata.usgs.gov/mapcache/wmts?LAYER=sgmc2&amp;TILEMATRIX={z}',
      params: {
            STYLE: 'default',
            TILEMATRIXSET: 'GoogleMapsCompatible',
            VERSION: '1.0.0',
            FORMAT: 'image/png',
      },
    }),
}));

// 示例 3:XYZ 格式(y 规则)
const xyzMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://server.arcgisonline.com/ArcGIS/rest/services/' +
            'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    }),
}));

// 示例 4:XYZ 格式(reverseY 规则,TMS)
const tmsMapView = engine.add(new mapvthree.MapView({
    imageryProvider: new mapvthree.XYZImageryTileProvider({
      url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/tms-bj/{z}/{x}/{reverseY}.png',
      startLevel: 7,
      maxLevel: 12,
    }),
}));
</code></pre>
<p><strong>我的感受</strong>:掌握了这三种服务的使用方法,就可以加载各种标准地图服务了!</p>
<h2 id="第六步踩过的坑">第六步:踩过的坑</h2>
<p>作为一个初学者,我踩了不少坑,记录下来避免再犯:</p>
<h3 id="坑-1wms-地图不显示">坑 1:WMS 地图不显示</h3>
<p><strong>原因</strong>:参数配置错误,比如图层名称不对、坐标系不匹配。</p>
<p><strong>解决</strong>:</p>
<ol>
<li>检查 WMS 服务的 GetCapabilities 文档,确认正确的参数</li>
<li>确保 <code>SRS</code> 参数与引擎的投影设置一致</li>
<li>确认 <code>LAYERS</code> 参数中的图层名称正确</li>
</ol>
<h3 id="坑-2wmts-瓦片位置错乱">坑 2:WMTS 瓦片位置错乱</h3>
<p><strong>原因</strong>:URL 占位符使用错误,或者 <code>TILEMATRIXSET</code> 不匹配。</p>
<p><strong>解决</strong>:</p>
<ol>
<li>确认 URL 中的占位符格式正确(<code>{z}</code>、<code>{x}</code>、<code>{y}</code>)</li>
<li>检查 <code>TILEMATRIXSET</code> 是否与服务提供的一致</li>
<li>查看服务的 GetCapabilities 文档</li>
</ol>
<h3 id="坑-3xyz-瓦片上下颠倒">坑 3:XYZ 瓦片上下颠倒</h3>
<p><strong>原因</strong>:切图规则选择错误,应该用 <code>y</code> 却用了 <code>reverseY</code>,或者相反。</p>
<p><strong>解决</strong>:</p>
<ol>
<li>查看服务文档,确认使用的切图规则</li>
<li>如果文档没有说明,尝试两种规则,看哪种显示正确</li>
<li>记住:左上角原点用 <code>y</code>,左下角原点用 <code>reverseY</code></li>
</ol>
<h3 id="坑-4瓦片加载很慢">坑 4:瓦片加载很慢</h3>
<p><strong>原因</strong>:服务地址访问慢,或者网络问题。</p>
<p><strong>解决</strong>:</p>
<ol>
<li>检查服务地址是否可访问</li>
<li>考虑使用 CDN 加速</li>
<li>对于自定义服务,确保服务器性能足够</li>
</ol>
<h3 id="坑-5某些缩放级别没有瓦片">坑 5:某些缩放级别没有瓦片</h3>
<p><strong>原因</strong>:服务只提供了特定缩放级别的瓦片。</p>
<p><strong>解决</strong>:使用 <code>startLevel</code> 和 <code>maxLevel</code> 限制缩放级别范围。</p>
<h2 id="我的学习总结">我的学习总结</h2>
<p>经过这一天的学习,我掌握了:</p>
<ol>
<li><strong>WMS 服务</strong>:动态生成地图图片,需要配置服务 URL 和请求参数</li>
<li><strong>WMTS 服务</strong>:使用预切好的瓦片,性能更好,支持 URL 占位符</li>
<li><strong>XYZ 格式</strong>:最通用的瓦片格式,支持自定义服务</li>
<li><strong>切图规则</strong>:理解 <code>y</code> 和 <code>reverseY</code> 的区别,正确选择切图规则</li>
<li><strong>参数配置</strong>:了解各种服务的参数含义和配置方法</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/19337015
頁: [1]
查看完整版本: JSAPIThree 加载 WMS、WMTS 和通用栅格图学习笔记:标准地图服务与切图规则