Azure Maps - 如何使用绘图管理器为挤压层绘制形状?

Azure Maps - How to user drawing manager to draw shapes for an extrusion layer?

我可以通过将绘图管理器设置为 'draw-polygon' 等各种模式来绘制形状,但我希望绘制形状并将其分配给挤压层。用户可以通过设置高度来简单地决定是否要将形状变红为挤压样式的形状。

似乎没有办法做到这一点,因为绘图管理器似乎看不到挤压层 class 除非我手动创建形状并将它们作为预定义对象添加到地图中这不利于使用绘图管理器工具进行编辑。

代码示例未按预期工作:

var layers = drawingManager.getLayers();

layers.polygonExtrusionLayer.setOptions({
    filter: polygonLayerFilter,
    fillColor: [
        'case', // Use a conditional case expression.

        ['has', 'fillColor'],   // Check to see if feature has a "fillOpacity" property
        ['get', 'fillColor'],   // If it does, use it.

        '#000000'  //If it doesn't, default to black.
    ],
    fillOpacity: [
        'case', // Use a conditional case expression.

        ['has', 'fillOpacity'],   // Check to see if feature has a "fillOpacity" property
        ['get', 'fillOpacity'],   // If it does, use it.

        0.5  // If it doesn't, default to 0.5 opacity.
    ],
    base: [
        'case', // Use a conditional case expression.

        ['has', 'base'],   // Check to see if feature has a "base" property
        ['get', 'base'],   // If it does, use it.

        0  // If it doesn't, default to 0.
    ],
    height: [
        'case', // Use a conditional case expression.

        ['has', 'height'],   // Check to see if feature has a "height" property
        ['get', 'height'],   // If it does, use it.

        0  // If it doesn't, default to 0.
    ]
});

绘图工具将仅使用标准多边形图层渲染多边形。也就是说,有几个选择。请注意,绘图工具仅支持编辑二维形状。

  1. 您可以创建单独的多边形拉伸图层和数据源。监视绘图工具事件和模式,并将多边形数据从绘图管理器复制到使用多边形挤压层进行渲染的新数据源中。这将在绘图工具中呈现在多边形图层上方,如果使用纯色,则会隐藏。或者,您可以在 entering/exiting 绘图模式下切换图层的可见性。

  2. 与上面类似,您可以监视绘图管理器的绘图模式,并根据用户是否正在编辑将形状移入和移出绘图管理器数据源。这将作为切换可见性的替代方法。

这是演示第一种方法的快速粗略代码示例。

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>

    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="IE=Edge" />
    <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 rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css" />
    <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>

    <!-- Add references to the Azure Maps Map Drawing Tools JavaScript and CSS files. -->
    <link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.css" type="text/css" />
    <script src="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.js"></script>

    <script type='text/javascript'>
        var map, drawingManager;
        var polyDataSource;
        var exLayer;

        function GetMap() {
            //Initialize a map instance.
            map = new atlas.Map('myMap', {
                center: [-122.33, 47.6],
                zoom: 12,
                view: 'Auto',

                authOptions: {
                    authType: 'subscriptionKey',
                    subscriptionKey: '<Your Azure Maps Key>'
                }
            });

            //Wait until the map resources are ready.
            map.events.add('ready', function () {

                //Create an instance of the drawing manager and display the drawing toolbar.
                drawingManager = new atlas.drawing.DrawingManager(map, {
                    toolbar: new atlas.control.DrawingToolbar({
                        buttons: ['draw-polygon', 'draw-circle', 'draw-rectangle', 'edit-geometry', 'erase-geometry'],
                        position: 'top-right',
                        style: 'light'
                    })
                });

                //Create a data source for polygons.
                polyDataSource = new atlas.source.DataSource();
                map.sources.add(polyDataSource);

                //Monitor the mode of the drawing manager.
                map.events.add('drawingmodechanged', drawingManager, drawingModeChanged);

                //Add a layer to render polygons as extrusions if they have a height value.
                exLayer = new atlas.layer.PolygonExtrusionLayer(polyDataSource, null, {
                    fillOpacity: 0.8,
                    fillColor: [
                        'case', // Use a conditional case expression.

                        ['has', 'fillColor'],   // Check to see if feature has a "fillOpacity" property
                        ['get', 'fillColor'],   // If it does, use it.

                        '#000000'  //If it doesn't, default to black.
                    ],
                    base: [
                        'case', // Use a conditional case expression.

                        ['has', 'base'],   // Check to see if feature has a "base" property
                        ['get', 'base'],   // If it does, use it.

                        0  // If it doesn't, default to 0.
                    ],
                    height: [
                        'case', // Use a conditional case expression.

                        ['has', 'height'],   // Check to see if feature has a "height" property
                        ['get', 'height'],   // If it does, use it.

                        0  // If it doesn't, default to 0.
                    ]
                });

                map.layers.add(exLayer);
            });
        }

        function drawingModeChanged(mode) {
            //Get the layers from the drawing manager.
            var dmLayers = drawingManager.getLayers();

            //Check to see if mode is idle. This would mean drawing manager likely exited a different mode.
            if (mode === 'idle') {
                //Copy all data from drawing manager into polygon data source.
                var source = drawingManager.getSource();
                polyDataSource.setShapes(source.getShapes());

                //Hide drawing managers polygon layer and show extrusion layer.
                dmLayers.polygonLayer.setOptions({ visible: false });
                dmLayers.polygonOutlineLayer.setOptions({ visible: false });
                exLayer.setOptions({ visible: true });
            } else {
                //Show drawing managers polygon layer and hide extrusion layer.
                dmLayers.polygonLayer.setOptions({ visible: true });
                dmLayers.polygonOutlineLayer.setOptions({ visible: true });
                exLayer.setOptions({ visible: false });
            }
        }

        function addProperties() {
            //Rndomly add heights and fill color properties to shapes, if not set, for testing purposes.
            var source = drawingManager.getSource();
            var shapes = source.getShapes();

            shapes.forEach(s => {
                var p = s.getProperties();

                if (typeof p.height !== 'number') {
                    p.height = Math.random() * 500;                       
                }

                if (!p.fillColor) {
                    p.fillColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
                }

                s.setProperties(p);
            });

            //Add copy of data to polygon data source.
            polyDataSource.setShapes(source.getShapes());

            //Exit drawing mode if enabled.
            drawingManager.setOptions({ mode: 'idle' });
        }
    </script>
</head>
<body onload="GetMap()">
    <div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>

    <input type="button" value="Add properties" onclick="addProperties()"/>
</body>
</html>

这是这个工作的屏幕截图。

注意多边形挤出层不支持不透明度表达式属性。