Commit 6ee4a7d4 authored by Moreau Nicolas's avatar Moreau Nicolas
Browse files

Merge branch 'master' into highcharts

parents 86733526 6199091b
...@@ -714,7 +714,7 @@ class DataBlock: ...@@ -714,7 +714,7 @@ class DataBlock:
aux = [0 for x in range(len(bins))] aux = [0 for x in range(len(bins))]
for i in range (1, len(aux)): for i in range (1, len(aux)):
aux[i] = aux[i-1]+population[i-1] aux[i] = aux[i-1]+population[i-1]
normfactor = reduce(lambda a,b : a*b, self.__data.shape); normfactor = np.count_nonzero(~np.isnan(data)) #reduce(lambda a,b : a*b, self.__data.shape);
self.__statistics[key]["cumuldist"] = list(map(lambda x: x/normfactor, aux)); self.__statistics[key]["cumuldist"] = list(map(lambda x: x/normfactor, aux));
self.__logger.debug(self.__statistics[key]); self.__logger.debug(self.__statistics[key]);
self.__logger.debug("__collectStatistics : exiting") self.__logger.debug("__collectStatistics : exiting")
...@@ -1197,6 +1197,43 @@ class DataBlock: ...@@ -1197,6 +1197,43 @@ class DataBlock:
self.__logger.debug("measureContour : exiting") self.__logger.debug("measureContour : exiting")
return result return result
def measureBox(self, iFREQ, iRA0=None, iRA1=None, iDEC0=None, iDEC1=None):
self.__logger.debug("measureBox: entering")
numDims = len(self.__data.shape)
iDEC0 = iDEC0 if iDEC0 else 0
iDEC1 = iDEC1 if iDEC1 else (self.__data.shape[1] if numDims > 2 else self.__data.shape[0])
iRA0 = iRA0 if iRA0 else 0
iRA1 = iRA1 if iRA1 else (self.__data.shape[2] if numDims > 2 else self.__data.shape[1])
box = self.__getSlice(iFREQ).compute()[iDEC0:iDEC1, iRA0:iRA1]
shape = self.__data.shape
result = {}
bunit = self.__header["BUNIT"]
if bunit == "Jy/beam" :
sumunit = "Jy"
bunit = "Jy/beam"
else:
sumunit = bunit
self.__logger.debug(iRA0);
self.__logger.debug(iRA1);
self.__logger.debug(iDEC0);
self.__logger.debug(iDEC1);
self.__logger.debug(shape)
self.__logger.debug(type(box))
result["sum"] = {"value": np.nansum(box).item() / self.__convert * self.__cdelt , "unit" : sumunit}
result["min"] = {"value": np.nanmin(box).item() , "unit": bunit}
result["max"] = {"value": np.nanmax(box).item() , "unit": bunit}
result["mean"] = {"value": np.nanmean(box).item() , "unit": bunit}
result["stdev"] = {"value": np.nanstd(box).item() , "unit": bunit}
result["numpix"] = {"value": np.count_nonzero(~np.isnan(box)), "unit" : "pixels (!=Nan)"}
result["percentage of total number of pixels"] = {"value": (box.shape[0]*box.shape[1]) / (self.__header["NAXIS1"]*self.__header["NAXIS2"]) * 100, "unit": "%"}
result = {"status":True, "message":"", "result":result}
self.__logger.debug("measureBox : exiting")
return result
# #
# End of DataBlock class definition. # End of DataBlock class definition.
# #
...@@ -219,11 +219,11 @@ class DataManagerImpl : ...@@ -219,11 +219,11 @@ class DataManagerImpl :
self.__logger.debug("getPixelValueAtiFreqiRAiDEC : exiting") self.__logger.debug("getPixelValueAtiFreqiRAiDEC : exiting")
return result return result
def getSumOverSliceRectArea(self, relFITSFilePath, iFREQ, RAPix0=None, RAPix1=None, DECPix0=None, DECPix1=None): def getSumOverSliceRectArea(self, relFITSFilePath, iFREQ, iRA0=None, iRA1=None, iDEC0=None, iDEC1=None):
self.__logger.debug("getSumOnSliceRectArea : entering") self.__logger.debug("getSumOnSliceRectArea : entering")
result = self.__checkPresence(relFITSFilePath) result = self.__checkPresence(relFITSFilePath)
if result["status"]: if result["status"]:
result=self.__dataBlocks[relFITSFilePath].getSumOverSliceRectArea(iFREQ, RAPix0, RAPix1, DECPix0, DECPix1) result=self.__dataBlocks[relFITSFilePath].getSumOverSliceRectArea(iFREQ, iRA0, iRA1, iDEC0, iDEC1)
self.__logger.debug("getSumOnSliceRectArea : exiting") self.__logger.debug("getSumOnSliceRectArea : exiting")
return result return result
...@@ -268,6 +268,14 @@ class DataManagerImpl : ...@@ -268,6 +268,14 @@ class DataManagerImpl :
self.__logger.debug("measureContour - dispatcher : exiting") self.__logger.debug("measureContour - dispatcher : exiting")
return result return result
def measureBox(self, relFITSFilePath, iFREQ, iRA0, iRA1, iDEC0, iDEC1):
self.__logger.debug("measureBox - dispatcher : entering")
result = self.__checkPresence(relFITSFilePath)
if result["status"] :
result = self.__dataBlocks[relFITSFilePath].measureBox(iFREQ, iRA0, iRA1, iDEC0, iDEC1)
self.__logger.debug("measureBox - dispatcher : exiting")
return result
# #
# create fits file containing a spectrum at iRA, iDEC # create fits file containing a spectrum at iRA, iDEC
......
...@@ -560,12 +560,12 @@ def getSumOverSliceRectArea(): ...@@ -560,12 +560,12 @@ def getSumOverSliceRectArea():
logger.debug("getSumOverSliceRectArea - wrapper : entering" ) logger.debug("getSumOverSliceRectArea - wrapper : entering" )
try: try:
relFITSFilePath = rebuildFilename(request.GET['relFITSFilePath']) relFITSFilePath = rebuildFilename(request.GET['relFITSFilePath'])
DECPix0 = getIntValue(request.GET['DECPix0']) iDEC0 = getIntValue(request.GET['iDEC0'])
DECPix1 = getIntValue(request.GET['DECPix1']) iDEC1 = getIntValue(request.GET['iDEC1'])
RAPix0 = getIntValue(request.GET['RAPix0']) iRA0 = getIntValue(request.GET['iRA0'])
RAPix1 = getIntValue(request.GET['RAPix1']) iRA1 = getIntValue(request.GET['iRA1'])
iFREQ = getIntValue(request.GET['iFREQ']) iFREQ = getIntValue(request.GET['iFREQ'])
result = json.dumps(dm.getSumOverSliceRectArea(relFITSFilePath, iFREQ, RAPix0, RAPix1, DECPix0, DECPix1)) result = json.dumps(dm.getSumOverSliceRectArea(relFITSFilePath, iFREQ, iRA0, iRA1, iDEC0, iDEC1))
except Exception as e: except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
message = "%s ! %s" % (type(e), "".join(traceback.format_list(traceback.extract_tb(exc_traceback)))) message = "%s ! %s" % (type(e), "".join(traceback.format_list(traceback.extract_tb(exc_traceback))))
...@@ -881,6 +881,29 @@ def measureContour(): ...@@ -881,6 +881,29 @@ def measureContour():
logger.debug("measureContour - wrapper : exiting") logger.debug("measureContour - wrapper : exiting")
return json.dumps(result) return json.dumps(result)
@route( baseUrl+'/measureBox', name='measureBox', method='POST')
@enable_cors
def measureBox():
logger.debug("measureContour - wrapper : entering")
try:
body = byteify(json.loads(request.body.read()))
relFITSFilePath = rebuildFilename(body['relFITSFilePath'])
iFREQ = getIntValue(body['iFREQ'])
iRA0 = getIntValue(body['iRA0']) if 'iRA0' in body else None
iRA1 = getIntValue(body['iRA1']) if 'iRA1' in body else None
iDEC0 = getIntValue(body['iDEC0']) if 'iDEC0' in body else None
iDEC1 = getIntValue(body['iDEC1']) if 'iDEC1' in body else None
result = dm.measureBox(relFITSFilePath, iFREQ, iDEC0, iDEC1, iRA0, iRA1)
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
message = "%s ! %s" % (type(e), "".join(traceback.format_list(traceback.extract_tb(exc_traceback))))
logger.debug(message)
result = {"status": False, "message": message}
response.content_type = "application/json; charset=utf-8"
logger.debug("measureContour - wrapper : exiting")
return json.dumps(result)
""" """
Given the values of a spectrum 'ydata' passed with the corresponding frequency values 'xdata' Given the values of a spectrum 'ydata' passed with the corresponding frequency values 'xdata'
......
...@@ -99,14 +99,14 @@ var clienthttp = { ...@@ -99,14 +99,14 @@ var clienthttp = {
}); });
}, },
getSumOverSliceRectArea : function(relFITSFilePath, sessionID, iFREQ, RAPix0, RAPix1, DECPix0, DECPix1, callback) { getSumOverSliceRectArea : function(relFITSFilePath, sessionID, iFREQ, iRA0, iRA1, iDEC0, iDEC1, callback) {
request(this.server+"/getSumOverSliceRectArea?relFITSFilePath="+relFITSFilePath+ request(this.server+"/getSumOverSliceRectArea?relFITSFilePath="+relFITSFilePath+
"&sessionID="+sessionID+ "&sessionID="+sessionID+
"&iFREQ="+iFREQ+ "&iFREQ="+iFREQ+
"&RAPix0="+RAPix0+ "&iRA0="+iRA0+
"&RAPix1="+RAPix1+ "&iRA1="+iRA1+
"&DECPix0="+DECPix0+ "&iDEC0="+iDEC0+
"&DECPix1="+DECPix1, "&iDEC1="+iDEC1,
{json: true}, {json: true},
function(error, response, body){ function(error, response, body){
callback(error, response, body) callback(error, response, body)
...@@ -184,6 +184,16 @@ var clienthttp = { ...@@ -184,6 +184,16 @@ var clienthttp = {
}); });
}, },
measureBox: function(relFITSFilePath, iFREQ, iRA0, iRA1, iDEC0, iDEC1, callback) {
let input = {"relFITSFilePath": relFITSFilePath,
"iFREQ": iFREQ,
"iRA0" : iRA0, "iRA1" : iRA1,
"iDEC0" : iDEC0, "iDEC1" : iDEC1};
request.post(this.server+"/measureBox", {json:true, body:input}, function(error, response, body){
callback(error, response, body);
});
},
renderingCapabilities: function(callback) { renderingCapabilities: function(callback) {
request(this.server+"/renderingCapabilities", {json: true}, function (error, response, body){ request(this.server+"/renderingCapabilities", {json: true}, function (error, response, body){
callback(error, response, body); callback(error, response, body);
...@@ -542,10 +552,10 @@ router.post('/', function(req, res, next) { ...@@ -542,10 +552,10 @@ router.post('/', function(req, res, next) {
req.body.relFITSFilePath, req.body.relFITSFilePath,
req.body.sessionID ? req.body.sessionID : 0, req.body.sessionID ? req.body.sessionID : 0,
req.body.iFREQ ? parseInt(req.body.iFREQ) : 0, req.body.iFREQ ? parseInt(req.body.iFREQ) : 0,
req.body.RAPix0 ? parseInt(req.body.RAPix0) : 0, req.body.iRA0 ? parseInt(req.body.iRA0) : 0,
req.body.RAPix1 ? parseInt(req.body.RAPix1) : null, req.body.iRA1 ? parseInt(req.body.iRA1) : null,
req.body.DECPix0 ? parseInt(req.body.DECPix0) : 0, req.body.iDEC0 ? parseInt(req.body.iDEC0) : 0,
req.body.DECPix1 ? parseInt(req.body.DECPix1) : null, req.body.iDEC1 ? parseInt(req.body.iDEC1) : null,
(error, response, body) => { (error, response, body) => {
console.log("getSumOverSliceRectArea callback : entering"); console.log("getSumOverSliceRectArea callback : entering");
if (error) { if (error) {
...@@ -761,6 +771,22 @@ router.post('/measureContour', function(req, res, next){ ...@@ -761,6 +771,22 @@ router.post('/measureContour', function(req, res, next){
console.log("router.post('/measureContour', function(req, res, next){: exiting"); console.log("router.post('/measureContour', function(req, res, next){: exiting");
}); });
router.post('/measureBox', function(req, res, next){
console.log("router.post('/measureBox', function(req, res, next){: entering");
clienthttp.measureBox(req.body.relFITSFilePath, req.body.iFREQ, req.body.iRA0, req.body.iRA1, req.body.iDEC0, req.body.iDEC1, (error, response, body) => {
console.log("measureBox callback entering");
if (error) {
console.log(error);
}
else {
console.log(body);
res.send(body);
}
console.log("measureBox callback exiting");
});
console.log("router.post('/measureBox', function(req, res, next){: exiting");
});
router.get("/getYtObj", function(req, res, next) { router.get("/getYtObj", function(req, res, next) {
console.log('router.get("/", function(req, res, next) { : entering '); console.log('router.get("/", function(req, res, next) { : entering ');
clienthttp.getYtObj(req.query.relFITSFilePath,req.query.iRA0, req.query.iRA1, req.query.iDEC0, clienthttp.getYtObj(req.query.relFITSFilePath,req.query.iRA0, req.query.iRA1, req.query.iDEC0,
......
...@@ -182,6 +182,7 @@ th, td { ...@@ -182,6 +182,7 @@ th, td {
<% include olqv_customcontrols %> <% include olqv_customcontrols %>
<% include olqv_reset %> <% include olqv_reset %>
<% include olqv_samp_publisher %> <% include olqv_samp_publisher %>
<% include olqv_boxes %>
<div id="fullscreen" class="fullscreen"> <div id="fullscreen" class="fullscreen">
<div class="sidepanel"> <div class="sidepanel">
<nav class="navbar navbar-dark bg-dark"> <nav class="navbar navbar-dark bg-dark">
...@@ -255,8 +256,27 @@ var yaFITSContoursGUI; ...@@ -255,8 +256,27 @@ var yaFITSContoursGUI;
var reset; var reset;
var settings; var settings;
var boxTool;
function SliceViewer ( relFITSFilePath, width, height, RADECRangeInDegrees, FITSHeader, divSlice) { var format = function(floatValue) {
let result = floatValue;
if (typeof result === "number" && !Number.isInteger(result)){
result = result.toExponential(4);
}
return result;
};
var infos_line = document.getElementById('infos-line');
var infos_block = document.getElementById('ModalInfosBlockBody');
var populateInfosBlock = function(title, collection) {
infos_block.innerHTML = "<b>"+title+" <br><br>";
for (var k in collection) {
infos_block.innerHTML += k + ":" + format(collection[k]["value"]) + " " + collection[k]["unit"] + "<br>";
}
}
function SliceViewer (relFITSFilePath, width, height, RADECRangeInDegrees, FITSHeader, divSlice) {
console.log("SliceViewer : entering"); console.log("SliceViewer : entering");
let _relFITSFilePath = null; let _relFITSFilePath = null;
...@@ -345,6 +365,14 @@ function SliceViewer ( relFITSFilePath, width, height, RADECRangeInDegrees, FITS ...@@ -345,6 +365,14 @@ function SliceViewer ( relFITSFilePath, width, height, RADECRangeInDegrees, FITS
return result; return result;
}; };
this.getSliceIndex = function () {
return _sliceIndex;
}
this.getRelFITSFilePath = function() {
return _relFITSFilePath;
}
this.reset = function() { this.reset = function() {
_map_1.getView().setCenter(ol.extent.getCenter(_extent)); _map_1.getView().setCenter(ol.extent.getCenter(_extent));
_map_1.getView().setResolution(1); _map_1.getView().setResolution(1);
...@@ -566,44 +594,22 @@ var _marker_styles_f = function(feature) { ...@@ -566,44 +594,22 @@ var _marker_styles_f = function(feature) {
_selected_features_1 = event.target.getFeatures(); _selected_features_1 = event.target.getFeatures();
_deselected_features_1 = event.deselected; _deselected_features_1 = event.deselected;
let infos_line = document.getElementById('infos-line');
let infos_block = document.getElementById('ModalInfosBlockBody');
// Update the displayed integrated flux accordingly with the selected box. // Update the displayed integrated flux accordingly with the selected box.
if (_selected_features_1.getLength() == 1) { if (_selected_features_1.getLength() == 1) {
let selectedFeature = _selected_features_1.item(0); let selectedFeature = _selected_features_1.item(0);
let featureType = selectedFeature.getGeometry().getType(); let featureType = selectedFeature.getGeometry().getType();
let format = function(floatValue) {
let result = floatValue;
if (typeof result === "number" && !Number.isInteger(result)){
result = result.toExponential(4);
}
return result;
};
let populateInfosBlock = function(title, collection) {
infos_block.innerHTML = "<b>"+title+" <br><br>";
for (var k in collection) {
infos_block.innerHTML += k + ":" + format(collection[k]["value"]) + " " + collection[k]["unit"] + "<br>";
}
}
switch (featureType) { switch (featureType) {
case 'Polygon': case 'Polygon':
infos_line.innerHTML = 'Integrated flux : ' + _box_infos_1[_selected_features_1.item(0).getId()]["flux"].toExponential(3) + ' Jy'; boxFactory.selected(selectedFeature);
break; break;
case 'LineString': case 'LineString':
var coordinates = selectedFeature.getGeometry().getCoordinates(); var coordinates = selectedFeature.getGeometry().getCoordinates();
let properties = selectedFeature.get("properties"); let properties = selectedFeature.get("properties");
let level = properties["level"]["value"].toExponential(3); let level = properties["level"]["value"].toExponential(3);
let levelUnit = properties["level"]["unit"];
let title = 'Contour level at ' + level + ' ' + levelUnit;
infos_line.innerHTML = title;
if ("measurements" in properties) { if ("measurements" in properties) {
populateInfosBlock(title, properties["measurements"]); yAFITSContoursViewer.selected(selectedFeature);
infos_line.innerHTML += ' <button type="button" class="btn btn-outline-link btn-sm" data-toggle="modal" data-target="#ModalInfosBlock">etc.</button>';
yAFITSContoursViewer.highlight(selectedFeature);
} }
else { else {
document.getElementById('loading').style.display="block"; document.getElementById('loading').style.display="block";
...@@ -618,9 +624,7 @@ var _marker_styles_f = function(feature) { ...@@ -618,9 +624,7 @@ var _marker_styles_f = function(feature) {
console.log(resp["result"]); console.log(resp["result"]);
properties["measurements"]=resp["result"]; properties["measurements"]=resp["result"];
selectedFeature.set("properties",properties); selectedFeature.set("properties",properties);
populateInfosBlock(title, properties["measurements"]); yAFITSContoursViewer.selected(selectedFeature);
infos_line.innerHTML += ' <button type="button" class="btn btn-outline-link btn-sm" data-toggle="modal" data-target="#ModalInfosBlock">etc.</button>';
yAFITSContoursViewer.highlight(selectedFeature);
} }
console.log('measureContour callback : exiting'); console.log('measureContour callback : exiting');
}); });
...@@ -681,21 +685,21 @@ var _marker_styles_f = function(feature) { ...@@ -681,21 +685,21 @@ var _marker_styles_f = function(feature) {
/* /*
** This is our dragbox interaction ** This is our dragbox interaction
*/ */
_dragBox_1 = new ol.interaction.DragBox(); //_dragBox_1 = new ol.interaction.DragBox();
/* /*
** And its behaviour. ** And its behaviour.
*/ */
_dragBox_1.on('boxend', function() { // _dragBox_1.on('boxend', function() {
console.log(" _dragBox_1.on('boxend', function() { : entering"); // console.log(" _dragBox_1.on('boxend', function() { : entering");
var extent = _dragBox_1.getGeometry().getExtent(); // var extent = _dragBox_1.getGeometry().getExtent();
//
// The real work when a drag box interaction reach its end is done below // // The real work when a drag box interaction reach its end is done below
_getSumOverSliceRectAreaWithPOST(_relFITSFilePath, 0, 0, extent); // _getSumOverSliceRectAreaWithPOST(_relFITSFilePath, 0, 0, extent);
//
console.log(JSON.stringify(extent)); // console.log(JSON.stringify(extent));
console.log(" _dragBox_1.on('boxend', function() { : exiting"); // console.log(" _dragBox_1.on('boxend', function() { : exiting");
}); // });
let _updateSliceWithPOST = function () { let _updateSliceWithPOST = function () {
...@@ -863,22 +867,22 @@ var _marker_styles_f = function(feature) { ...@@ -863,22 +867,22 @@ var _marker_styles_f = function(feature) {
break; break;
// B // B
case 66 : // case 66 :
if (_interaction_mode == "") { // Has to see with boxes // if (_interaction_mode == "") { // Has to see with boxes
_interaction_mode = "box"; // _interaction_mode = "box";
_map_1.removeInteraction(_select_1); // Enter box mode // _map_1.removeInteraction(_select_1); // Enter box mode
_map_1.addInteraction(_dragBox_1); // _map_1.addInteraction(_dragBox_1);
//
jTarget.css('cursor','nwse-resize'); // jTarget.css('cursor','nwse-resize');
} // }
else if (_interaction_mode == "box") { // Leave box mode // else if (_interaction_mode == "box") { // Leave box mode
_interaction_mode = ""; // _interaction_mode = "";
_map_1.removeInteraction(_dragBox_1); // _map_1.removeInteraction(_dragBox_1);
_map_1.addInteraction(_select_1); // _map_1.addInteraction(_select_1);
//
jTarget.css('cursor','pointer'); // jTarget.css('cursor','pointer');
} // }
break; // break;
// X // X
case 88: case 88:
...@@ -1123,20 +1127,22 @@ $( document ).ready(function() { ...@@ -1123,20 +1127,22 @@ $( document ).ready(function() {
settings = new Settings(sliceViewer); settings = new Settings(sliceViewer);
customControls.addButton(settings.getButton()); customControls.addButton(settings.getButton());
markerFactory = new MarkerFactory(sliceViewer);
customControls.addButton(markerFactory.getButton());
yAFITSContoursViewer = new ContoursViewer(relFITSFilePath, sliceViewer);
customControls.addButton(yAFITSContoursViewer.getButton());
<%if(useSAMP){%> <%if(useSAMP){%>
publishSAMP = new PublishSAMP(sAMPPublisher); publishSAMP = new PublishSAMP(sAMPPublisher);
customControls.addButton(publishSAMP.getButton()); customControls.addButton(publishSAMP.getButton());
<%}%> <%}%>
markerFactory = new MarkerFactory(sliceViewer);
customControls.addButton(markerFactory.getButton());
yAFITSContoursViewer = new ContoursViewer(sliceViewer, infosBlock);
customControls.addButton(yAFITSContoursViewer.getButton());
yAFITSContoursGUI = new ContoursGUI(); yAFITSContoursGUI = new ContoursGUI();
yAFITSContoursGUI.connect(yAFITSContoursViewer, sliceViewer); yAFITSContoursGUI.connect(yAFITSContoursViewer, sliceViewer);
boxFactory = new BoxFactory(sliceViewer, infosBlock);
customControls.addButton(boxFactory.getButton());
$('a#rccap').click(function () {sliceViewer.refresh()}); $('a#rccap').click(function () {sliceViewer.refresh()});
console.log('$.post("", {"method": "RADECRangeInDegrees", "fileName": relFITSFilePath}).done(function (resp) { : exiting'); console.log('$.post("", {"method": "RADECRangeInDegrees", "fileName": relFITSFilePath}).done(function (resp) { : exiting');
......
<script>
class BoxFactory {
constructor (sliceViewer, infosBlock) {
console.log("BoxFactory ctor: entering");
this.source;
this.layer;
this.dragBox;
this.relFITSFilePath = sliceViewer.getRelFITSFilePath();
this.sliceIndex = sliceViewer.getSliceIndex();
this.map = sliceViewer.getMap();
let target = this.map.getTarget();
this.jTarget = typeof target === "string" ? $("#" + target) : $(target);
this.lastSelectedBox = null;
this.highlightStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 3
})
});
this.style = {
'LineString': new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'lightblue',
//lineDash: [2],
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.6)'
})
}),
'Polygon': new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'lightblue',
//lineDash: [2],
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
};
this.style_f = (feature) => {
return this.style[feature.getGeometry().getType()];
};
this.source = new ol.source.Vector();
this.layer = new ol.layer.Vector({source: this.source, style: this.style_f});
this.map.addLayer(this.layer);
this.layer.setZIndex(12);
this.visible = true;
this.overlay = null;
this.container = document.getElementById('popup');
this.content = document.getElementById('popup-content');
this.closer = document.getElementById('popup-closer');
this.lastSelectedContour = null;
this.button = document.createElement("button");
this.button.setAttribute("type","button");
this.button.setAttribute("class", "btn btn-primary btn-sm");
this.button.setAttribute("data-tooltip", "tooltip");
this.button.setAttribute("title", "Work with boxes");
this.button.append("B");
let f = function(event) {event.stopPropagation(); if (this.isOpened) this.close(); else this.open();};
this.button.onclick = f.bind(this);
<