如何在Openlayers 3中显示ESRI矢量底图
How to display ESRI Vector base map in Openlayers 3
我正在尝试添加由 OpenLayers 发布的新 ESRI Vector Basemaps in OpenLayers 3. I have gotten so far as to display the layer un-styled by modifying the Mapbox Example。
显然,我必须删除 style: createMapboxStreetsV6Style()
选项才能显示 esri 图层。所以基本上地图不知道正确显示图层的样式信息。
我认为应该可以做到,因为ESRI's Leaflet port and example is doing this already. I think information on esri's style IDs is available in here Leaflet code.
OpenLayers 应该已经能够使用所有这些信息,因为它能够显示 Mapbox 图层。我需要帮助的是,如何让它使用 ESRI 的样式信息。
这是我目前的情况 (codepen here):
var map = new ol.Map({
layers: [
new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
tilePixelRatio: 16,
url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf'
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
.map {
background: #f8f4f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
有一个单独的库,https://npmjs.com/package/ol-mapbox-style,这使得在 OpenLayers 中使用矢量切片地图(包括它们的样式)变得容易。它读取样式文档并从中构建整个地图。对于上面链接的其中一张 ESRI 地图,在 OpenLayers 中获取该地图的代码是
var map = new ol.Map({
target: 'map'
});
olms.apply(map, 'https://www.arcgis.com/sharing/rest/content/items/4f4843d99c34436f82920932317893ae/resources/styles/root.json?f=json');
您可以将 4f4843d99c34436f82920932317893ae
替换为 Leaflet 示例中列出的其他地图 ID 之一,以获取其他地图。
您也可以使用该代码 - 我创建了一个 CodePen:https://codepen.io/ahocevar/pen/xLaBVV。
@ahocevar 的建议很完美,
esri 的 root.json,精灵和字形不完整 URL,只有最后一部分,如下所示
在你的示例中,那些不完整的 URL 可以工作,但是,我已经在 mapbox js api 中对其进行了测试,它失败了,错误是无法解析 URL,
我必须将那些 url 更改为完整的 URL,才能使其正常工作。
root_json = {
"version" : 8,
"name": "test",
//"sprite" : original_rootJson.sprite, // original is not a full URL, not work "../sprites/sprite"
// "sprite" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/sprites/sprite",
"sprite" : _sprite,
// "glyphs" : original_rootJson.glyphs, // original is not a full URL, not work "../fonts/{fontstack}/{range}.pbf"
// "glyphs" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
"glyphs" : _glyphs,
// root json specification : https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/
"sources" : {
"esri" : {
"type" : "vector",
// By supplying TileJSON properties such as "tiles", "minzoom", and "maxzoom" directly in the source:
"tiles": [
// "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/tile/{z}/{y}/{x}.pbf"
_tile_pbf
],
// "maxzoom": 14
// By providing a "url" to a TileJSON resource
// not work,yet
// "url" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Esri_Childrens_Map/VectorTileServer/tile/{z}/{y}/{x}.pbf"
// "url": "http://api.example.com/tilejson.json"
}
},
"layers": original_rootJson.layers
} // root_json
我正在尝试添加由 OpenLayers 发布的新 ESRI Vector Basemaps in OpenLayers 3. I have gotten so far as to display the layer un-styled by modifying the Mapbox Example。
显然,我必须删除 style: createMapboxStreetsV6Style()
选项才能显示 esri 图层。所以基本上地图不知道正确显示图层的样式信息。
我认为应该可以做到,因为ESRI's Leaflet port and example is doing this already. I think information on esri's style IDs is available in here Leaflet code.
OpenLayers 应该已经能够使用所有这些信息,因为它能够显示 Mapbox 图层。我需要帮助的是,如何让它使用 ESRI 的样式信息。
这是我目前的情况 (codepen here):
var map = new ol.Map({
layers: [
new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
tilePixelRatio: 16,
url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf'
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
.map {
background: #f8f4f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
有一个单独的库,https://npmjs.com/package/ol-mapbox-style,这使得在 OpenLayers 中使用矢量切片地图(包括它们的样式)变得容易。它读取样式文档并从中构建整个地图。对于上面链接的其中一张 ESRI 地图,在 OpenLayers 中获取该地图的代码是
var map = new ol.Map({
target: 'map'
});
olms.apply(map, 'https://www.arcgis.com/sharing/rest/content/items/4f4843d99c34436f82920932317893ae/resources/styles/root.json?f=json');
您可以将 4f4843d99c34436f82920932317893ae
替换为 Leaflet 示例中列出的其他地图 ID 之一,以获取其他地图。
您也可以使用该代码 - 我创建了一个 CodePen:https://codepen.io/ahocevar/pen/xLaBVV。
@ahocevar 的建议很完美,
esri 的 root.json,精灵和字形不完整 URL,只有最后一部分,如下所示
在你的示例中,那些不完整的 URL 可以工作,但是,我已经在 mapbox js api 中对其进行了测试,它失败了,错误是无法解析 URL,
我必须将那些 url 更改为完整的 URL,才能使其正常工作。
root_json = {
"version" : 8,
"name": "test",
//"sprite" : original_rootJson.sprite, // original is not a full URL, not work "../sprites/sprite"
// "sprite" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/sprites/sprite",
"sprite" : _sprite,
// "glyphs" : original_rootJson.glyphs, // original is not a full URL, not work "../fonts/{fontstack}/{range}.pbf"
// "glyphs" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
"glyphs" : _glyphs,
// root json specification : https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/
"sources" : {
"esri" : {
"type" : "vector",
// By supplying TileJSON properties such as "tiles", "minzoom", and "maxzoom" directly in the source:
"tiles": [
// "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/tile/{z}/{y}/{x}.pbf"
_tile_pbf
],
// "maxzoom": 14
// By providing a "url" to a TileJSON resource
// not work,yet
// "url" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Esri_Childrens_Map/VectorTileServer/tile/{z}/{y}/{x}.pbf"
// "url": "http://api.example.com/tilejson.json"
}
},
"layers": original_rootJson.layers
} // root_json