I'm able to draw shapes by setting the drawing manager to the various modes such as 'draw-polygon' etc, but I want the shapes to be drawn and assigned to an extrusion layer. The user would the simply decide if they want the shape to redner as an extrusion styled shape or not by setting the height.
It seems there is no way to do this as the drawing manager does not seem to have visbility of the extrusion layers class unless i manually create the shapes and add them to the map as pre-defined objects which is no good for using the drawing manager tools for editing purposes.
Code sample not working as expected:
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.
]
});
The drawing tools will only render polygons using a standard polygon layer. That said, there are a couple of options. Note that the drawing tools only support editing of shapes in 2D.
You can create a separate polygon extrusion layer and data source. Monitor the drawing tool events and mode, and copy the polygon data from the drawing manager into the new data source that uses a polygon extrusion layer for rendering. This would render above the polygon layer in the drawing tools and would be hidden if using solid colors. Alternatively, you could toggle the visibility of the layers when entering/exiting drawing modes.
Similar to above, you could monitor the drawing mode of the drawing manager, and move shapes in and out of the drawing managers data source depending on if the user is editing's or not. This would be as an alternative to toggling the visibility.
Here is a quick rough code sample demonstrating the first method.
<!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>
Here is a screenshot of this working.
Note that the polygon extrusion layer does not support expressions on the opacity property.