mapview_interactions_draw.mjs
/**
## Mapview.interactions.draw()
@module /mapview/interactions/draw
@param {Object} params
The params object argument.
*/
export default function(params){
const mapview = this;
// Finish the current interaction.
mapview.interaction?.finish()
// Assign params onto the defaults as mapview.interaction.
mapview.interaction = {
type: 'draw',
finish,
getFeature,
format: new ol.format.GeoJSON(),
source: new ol.source.Vector(),
// The Layer is required for generated features such as isolines.
Layer: new ol.layer.Vector({
zIndex: params.layer?.zIndex || 99
}),
// Bind context menu from mapp ui elements.
drawend: mapp.ui?.elements.contextMenu.draw.bind(this),
vertices: [],
// Whether the draw interaction event should be handled.
condition: e => {
if (mapview.interaction.wait) return false;
// Right click
if (e.originalEvent.buttons === 2) {
// Remove last vertex.
mapview.interaction.interaction.removeLastPoint()
mapview.interaction.vertices.pop()
const moveEvent = new ol.MapBrowserEvent('pointermove', mapview.Map, e.originalEvent)
mapview.interaction.interaction.handleEvent(moveEvent)
mapview.interaction.conditions?.forEach(fn => typeof fn === 'function' && fn(e))
return false;
}
// Left click.
if (e.originalEvent.buttons === 1) {
mapview.interaction.vertices.push(e.coordinate);
mapview.popup(null);
mapview.interaction.conditions?.forEach(fn => typeof fn === 'function' && fn(e))
return true;
}
},
// OL Style for sketch feature.
style: [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: '#eee',
}),
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
geometry: mapp.utils.verticeGeoms
})
],
// Spread params argument.
...params
}
// Change cursor style over mapview element.
mapview.Map.getTargetElement().style.cursor = 'crosshair'
// Set mapview.interaction.Layer source.
mapview.interaction.Layer.setSource(mapview.interaction.source)
// Add mapview.interaction.Layer to mapview.
mapview.Map.addLayer(mapview.interaction.Layer)
document.addEventListener('keyup', escape)
function escape(e){
e.key === 'Escape' && mapview.interaction.finish()
}
// Create OL draw interaction.
mapview.interaction.interaction = new ol.interaction.Draw(mapview.interaction)
// Set drawstart event method.
mapview.interaction.interaction.on('drawstart', e => {
// Get the draw feature geometry.
const geometry = e.feature.getGeometry()
async function onChange() {
mapview.popup({
content: mapp.utils.html.node`
<div style="padding: 5px">
${await mapp.utils.convert(
// Get the geometry metric figure.
mapview.metrics[mapview.interaction.tooltip.metric](geometry),
// Options argument for conversion.
mapview.interaction.tooltip)}`
})
}
// Assign an onchange method to the geometry for the tooltip.
mapview.interaction.tooltip && geometry.on('change', mapview.interaction.tooltip.onChange || onChange)
// Clear the source
mapview.interaction.source.clear()
// Remove the popup.
mapview.popup(null)
})
if (typeof mapview.interaction.drawend === 'function') {
mapview.interaction.interaction.on('drawend', mapview.interaction.drawend)
}
// Add OL interaction to mapview.Map
mapview.Map.addInteraction(mapview.interaction.interaction)
// Assign snap interaction.
mapview.interactions.snap(mapview)
// Get first feature from mapview.interaction.source as GeoJSON.
function getFeature() {
// Return feature as geojson.
return JSON.parse(
mapview.interaction.format.writeFeature(
// Get first OL feature from source.
mapview.interaction.source.getFeatures()[0],
{
// Use mapview.interaction.srid as dataProjection if defined in params.
dataProjection: 'EPSG:' + mapview.interaction.layer?.srid || mapview.interaction.srid || mapview.srid,
featureProjection: 'EPSG:' + mapview.srid
})
)
}
function finish(feature) {
document.removeEventListener('keyup', escape)
// Remove snap interaction.
mapview.interaction.snap?.remove?.()
// Reset the cursor style.
mapview.Map.getTargetElement().style.cursor = 'default'
// Remove popup from mapview.
mapview.popup(null)
// Remove interaction from mapview.Map.
mapview.Map.removeInteraction(mapview.interaction.interaction)
// Remove draw Layer from mapview.Map.
mapview.Map.removeLayer(mapview.interaction.Layer)
mapview.interaction.callback?.(feature)
}
}