提问人:Erik Bussing 提问时间:11/14/2023 更新时间:11/16/2023 访问量:28
Azure Maps 勾勒出多边形拉伸的轮廓,或添加线拉伸层以突出显示形状的轮廓
azure maps outlining a polygon extrusion or adding a line extrusion layer to highlight the outline of shapes
问:
我目前正在尝试在 azure maps 中为建筑物创建一个映射工具,为了给它提供一些 3d 样式,我想添加一个多边形拉伸层,并根据您正在查看的楼层增加多边形的高度。但是,这使得更难看到不同房间的轮廓。我想要一个类似“线拉伸层”的东西,或者一个选项来突出显示拉伸多边形的边缘,甚至能够删除拉伸的顶部也会受到欢迎。 你们有什么想法我怎么能做到这一点吗?是否可以在挤压件的顶部放置线层?而不是在地图上?
我花了很多时间研究不同的选择,但没有找到任何接近我想要的东西。 我只想在挤压件的边缘有一条黑线
答:
不幸的是,没有线拉伸层。但是,有几种方法可以改善您的方案。
选项 1:每层楼的多边形拉伸
使用面拉伸图层的 base 和 height 属性创建每个楼层的切片。这应该在每个楼层之间创建一个接缝/线,并且还允许您使用事件来选择和突出显示各个楼层。为此,您可以为每个楼层创建一个面,并根据楼层编号为其分配一个底面/高度,也可以为每个楼层创建一个图层,并在数据源中重复使用相同的面。使用层方法将更具可扩展性,因为您的应用程序将使用更少的数据。如果您的楼层高度保持不变,事情可能会容易一些。如果我们假设您有一个指示建筑物所具有楼层数的值,则可以在每个图层上使用过滤器来确定是否应为该面创建楼层。这可能看起来像这样:
下面是一些示例源代码。您也可以在这里尝试直播:https://rbrundritt.azurewebsites.net/Demos/AzureMaps/BuildingFloors/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js"></script>
<script>
var map, datasource;
//The colors to use for each floor.
var colorScale = {
1: '#09e076',
2: '#0bbf67',
3: '#f7e305',
4: '#f7c707',
5: '#f78205',
6: '#f75e05',
7: '#f72505'
};
//The height of a single floor in meters.
var floorHeight = 4;
function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-122.134183, 47.643853],
zoom: 14,
maxPitch: 85,
style: 'satellite',
//Pitch the map so that the extrusion of the polygons is visible.
pitch: 45,
view: 'Auto',
//Add authentication details for connecting to Azure Maps.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '[YOUR_AZURE_MAPS_KEY]'
}
});
//Create a legend.
createLegend();
//Wait until the map resources are ready.
map.events.add('ready', function () {
//Create a data source to add your data to.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Load a dataset of polygons that have metadata we can style against.
datasource.importDataFromUrl('MSFT_Campus_Buildings.geojson');
//Create a polygon extrusion layer per floor.
for(var i = 1; i <= 7; i++) {
map.layers.add(new atlas.layer.PolygonExtrusionLayer(datasource, null, {
base: floorHeight * (i - 1),
height: floorHeight * i,
fillColor: colorScale[i],
filter: ['>=', ['get', 'floors'], i]
}), 'labels');
}
});
}
function createLegend() {
var html = [];
Object.keys(colorScale).forEach(function (key) {
html.push('<i style="background:', colorScale[key], '"></i> ', key, '<br/>');
});
document.getElementById('legend').innerHTML += html.join('');
}
</script>
<style>
html, body, #myMap {
margin: 0;
padding:0;
height: 100%;
width:100%;
}
#myMap {
background: linear-gradient(to bottom, #1e528e 0%,#728a7c 15%,#e9ce5d 100%); /** Give the sky/background some color for when the maps is pitched a lot **/
}
#legend {
position: absolute;
top: 1px;
left: 5px;
font-family: Arial;
font-size: 12px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 5px;
padding: 5px;
line-height: 20px;
}
#legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
<div id="legend">Floor<br /></div>
</body>
</html>
我尝试将所有地板的颜色设置为相同的颜色,但接缝不是很明显。如果希望所有楼层的颜色相同,可以在每个楼层之间添加一个具有单独颜色的薄层,如下所示:
这是上述代码的修改版本,用于执行此操作。您也可以在这里现场尝试: https://rbrundritt.azurewebsites.net/Demos/AzureMaps/BuildingFloors/FloorSeperator.html
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js"></script>
<script>
var map, datasource;
//The height of a single floor in meters.
var floorHeight = 3.9;
var floorSeperatorHeight = 0.1;
function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-122.134183, 47.643853],
zoom: 14,
maxPitch: 85,
style: 'satellite',
//Pitch the map so that the extrusion of the polygons is visible.
pitch: 45,
view: 'Auto',
//Add authentication details for connecting to Azure Maps.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '[YOUR_AZURE_MAPS_KEY]'
}
});
//Wait until the map resources are ready.
map.events.add('ready', function () {
//Create a data source to add your data to.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Load a dataset of polygons that have metadata we can style against.
datasource.importDataFromUrl('MSFT_Campus_Buildings.geojson');
//Create a polygon extrusion layer per floor. And a thin layer above the top floor to act as a seperator.
var floorBase = 0;
for (var i = 1; i <= 7; i++) {
floorBase = (floorHeight + floorSeperatorHeight) * (i - 1);
map.layers.add(new atlas.layer.PolygonExtrusionLayer(datasource, null, {
base: floorBase,
height: floorBase + floorHeight,
filter: ['>=', ['get', 'floors'], i]
}), 'labels');
//Add a layer to render a thin line seperator between each floor. Can skip the top floor by making filter ">" rather than ">="
map.layers.add(new atlas.layer.PolygonExtrusionLayer(datasource, null, {
base: floorBase + floorHeight,
height: floorBase + floorHeight + floorSeperatorHeight,
fillColor: 'black',
filter: ['>', ['get', 'floors'], i]
}), 'labels');
}
});
}
</script>
<style>
html, body, #myMap {
margin: 0;
padding:0;
height: 100%;
width:100%;
}
#myMap {
background: linear-gradient(to bottom, #1e528e 0%,#728a7c 15%,#e9ce5d 100%); /** Give the sky/background some color for when the maps is pitched a lot **/
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
</body>
</html>
选项 2:集成 Deck.gl
Deck.gl 是另一个 WebGL 渲染层,它支持渲染多边形拉伸和线条,如下所示:https://deck.gl/examples/geojson-layer-polygons。Deck.gl 可以通过以下示例与 Azure Maps 一起使用: 可以通过以下示例所示: https://samples.azuremaps.com/?search=deck&sample=deck-gl-custom-webgl-layer 这将为你提供你要查找的线条,但会在 Azure Maps API 之外引入许多新内容,这将使保持一致变得更加困难。例如,事件的处理方式不同,因此您的地图可能会使用两种不同类型的事件,这可能会使将来更难维护。我也有一种感觉,这种方法的实现会复杂得多。WebGlLayer
评论