【问题标题】:Azure Maps - How to user drawing manager to draw shapes for an extrusion layer?Azure Maps - 如何使用绘图管理器为拉伸层绘制形状?
【发布时间】:2021-11-11 03:09:04
【问题描述】:

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

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

代码示例未按预期工作:

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.
    ]
});

【问题讨论】:

    标签: azure-maps


    【解决方案1】:

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

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

    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>
    

    这是这个工作的截图。

    请注意,多边形挤压层不支持 opacity 属性上的表达式。

    【讨论】:

    • 非常感谢您的详细回复和示例。我得出了一个类似的结论,即绘图管理器无法直接渲染挤压形状,而您提供的是最接近该问题的实用解决方法。我相信其他人会发现这非常有用,再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多