1
0
mirror of https://github.com/gsi-upm/soil synced 2024-11-14 15:32:29 +00:00

Map added

This commit is contained in:
Tasio Mendez 2018-04-11 19:40:59 +02:00
parent da1ce1ea30
commit 819c371292
10 changed files with 127 additions and 39 deletions

View File

@ -1,6 +1,6 @@
name: TerroristNetworkModel_sim
load_module: TerroristNetworkModel
max_time: 100
max_time: 150
num_trials: 1
network_params:
generator: random_geometric_graph
@ -30,7 +30,7 @@ environment_params:
# TerroristSpreadModel
information_spread_intensity: 0.7
terrorist_additional_influence: 0.035
max_vulnerability: 0.5
max_vulnerability: 0.6
prob_interaction: 0.5
# TrainingAreaModel and HavenModel
@ -38,7 +38,7 @@ environment_params:
haven_influence: 0.20
# TerroristNetworkModel
vision_range: 0.50
vision_range: 0.30
sphere_influence: 2
weight_social_distance: 0.035
weight_link_distance: 0.035
@ -49,10 +49,12 @@ visualization_params:
shapes:
TrainingAreaModel: target
HavenModel: home
TerroristNetworkModel: person
colors:
- attr_id: 0
color: green
color: '#40de40'
- attr_id: 1
color: red
- attr_id: 2
color: '#c16a6a'
background_image: 'map.png'

2
run.py
View File

@ -14,7 +14,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Visualization of a Graph Model')
parser.add_argument('--name', '-n', nargs=1, default='SOIL Model', help='name of the simulation')
parser.add_argument('--name', '-n', nargs=1, default='SOIL', help='name of the simulation')
parser.add_argument('--dump', '-d', help='dumping results in folder output', action='store_true')
parser.add_argument('--verbose', '-v', help='verbose mode', action='store_true')
args = parser.parse_args()

View File

@ -94,10 +94,11 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
settings = []
for key in self.config['environment_params']:
if type(self.config['environment_params'][key]) == float:
setting_type = 'number'
elif type(self.config['environment_params'][key]) == int:
if type(self.config['environment_params'][key]) == float or type(self.config['environment_params'][key]) == int:
if self.config['environment_params'][key] <= 1:
setting_type = 'number'
else:
setting_type = 'great_number'
elif type(self.config['environment_params'][key]) == bool:
setting_type = 'boolean'
else:
@ -122,7 +123,6 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
elif msg['type'] == 'run_simulation':
if self.application.verbose:
logger.info('Running new simulation for {name}'.format(name=self.config['name']))
print(msg['data'])
self.send_log('INFO.soil', 'Running new simulation for {name}'.format(name=self.config['name']))
self.config['environment_params'] = msg['data']
self.run_simulation()
@ -209,7 +209,7 @@ class ModularServer(tornado.web.Application):
settings = {'debug': True,
'template_path': os.path.dirname(__file__) + '/templates'}
def __init__(self, model, visualization_element, name='SOIL Model', verbose=True,
def __init__(self, model, visualization_element, name='SOIL', verbose=True,
*args, **kwargs):
self.verbose = verbose

View File

@ -33,6 +33,25 @@ html, body {
cursor: pointer;
}
.wrapper-heading {
display: flex;
flex-direction: row;
padding: 0 !important;
}
.soil_logo {
padding: 0 !important;
border-left: none !important;
border-right: none !important;
display: flex;
justify-content: flex-end;
background-color: rgb(88, 88, 88);
}
.soil_logo > img {
max-height: 100%;
}
.node {
stroke: #fff;
stroke-width: 1.5px;
@ -292,7 +311,7 @@ table#link-distance .max {
/* Console */
#update, .console {
#update, .console, .soil_logo {
padding: 10px 15px;
height: 135px;
border: 1px solid #585858;
@ -317,6 +336,7 @@ table#link-distance .max {
overflow: auto;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
width: 100%;
}
.console::-webkit-scrollbar {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
templates/img/logo_soil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -74,7 +74,7 @@
);
if ( file['type'] !== "application/x-yaml" ) {
console.log('File format not supported. Sorry for the inconvenience.');
console.error('File format not supported. Sorry for the inconvenience.');
_socket.error('File format not supported. Sorry for the inconvenience.');
return;
} else {
@ -142,14 +142,22 @@
<div class="container-fluid fixed">
<div class="col-sm-9 wrapper-heading">
<!-- CONSOLE -->
<div class="col-sm-9 console">
<div class="console">
Please, upload a YAML file that defines all the parameters of a simulation. <br/>
If you don't know how to write the file, please visit this page:<br/>
http://soilsim.readthedocs.io/en/latest/quickstart.html<br/>
</div>
<!-- //CONSOLE -->
<!-- SOIL Logo -->
<div class="soil_logo" >
<img src="img/logo_soil.png" />
</div>
<!-- //SOIL Logo -->
</div>
<div id="update" class="col-sm-3">
<!-- Load File -->
<form enctype="multipart/form-data">
@ -210,7 +218,7 @@
<div class="container-fluid">
<div id="graph_container">
<svg id="graph" class="col-sm-9"></svg>
<svg id="graph" class="col-sm-9" xmlns="http://www.w3.org/2000/svg"></svg>
</div>
<div id="configuration" class="col-sm-3">

View File

@ -26,12 +26,12 @@ ws.onmessage = function(message) {
self.GraphVisualization.import(convertJSON(msg['data']), function() {
reset_configuration();
set_configuration();
$('#home_menu').click(function() {
setTimeout(function() {
reset_timeline();
set_timeline(msg['data']);
}, 1000);
});
// $('#home_menu').click(function() {
// setTimeout(function() {
// reset_timeline();
// set_timeline(msg['data']);
// }, 1000);
// });
reset_timeline();
set_timeline(msg['data']);
$('#load').hide();
@ -52,7 +52,7 @@ ws.onmessage = function(message) {
break;
case 'error':
console.log(msg['error']);
console.error(msg['error']);
_socket.error(msg['error']);
$('#load').removeClass('loader');
break;
@ -65,10 +65,18 @@ ws.onmessage = function(message) {
case 'visualization_params':
console.log(msg['data']);
self.GraphVisualization.set_params(msg['data']['shape_property'], msg['data']['shapes'], msg['data']['colors']);
if ( msg['data']['background_image'] ) {
// $('svg#graph').css('background-image', 'linear-gradient(to bottom, rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%), url(img/background/' + msg['data']['background_image'])
// .css('background-size', '130%').css('background-position', '5% 30%').css('background-repeat', 'no-repeat');
$('<style>').text('svg line.link { stroke: white !important; stroke-width: 1.5px !important; }').appendTo($('html > head'));
$('<style>').text('svg circle.node { stroke-width: 2.5px !important; }').appendTo($('html > head'));
self.GraphVisualization.set_background('img/background/' + msg['data']['background_image']);
}
break;
default:
console.log('Unexpected message!')
console.warn('Unexpected message!')
}
}
@ -111,8 +119,8 @@ var reset_trials = function() {
var convertJSON = function(json) {
// For NetworkX Geometric Graphs get positions
json.nodes.forEach(function(node) {
var scx = d3.scale.linear().domain([0, 1]).range([0, height]);
var scy = d3.scale.linear().domain([0, 1]).range([height, 0]);
var scx = d3.scale.linear().domain([0, 1]).range([0, width]);
var scy = d3.scale.linear().domain([0, 1]).range([width, 0]);
if ( node.pos ) {
node.scx = scx(node.pos[0]);
node.scy = scy(node.pos[1]);
@ -227,7 +235,14 @@ var set_timeline = function(graph) {
// Draw graph for the first time
self.GraphVisualization.update_graph($('.config-item #properties').val(), maxUnix, function() {
update_statistics_table();
$('svg #root > image').attr('height', d3.select('#root').node().getBBox().height)
setTimeout(function() {
if ( $('svg #root > image').length !== 0 ) {
$('svg #root > image').attr('height', d3.select('#root').node().getBBox().height * 1.2);
var dx = d3.select('#graph-wrapper').node().getBBox().width - d3.select('svg #root > image').node().getBBox().width;
var dy = d3.select('#graph-wrapper').node().getBBox().height - d3.select('svg #root > image').node().getBBox().height;
$('svg #root > image').attr('transform', 'translate(' + (dx / 2) + ',' + (dy / 2) + ')');
}
self.GraphVisualization.fit();
}, 100);
});
@ -397,7 +412,11 @@ var run_simulation = function() {
case 'checkbox':
environment_variables[this.id] = ($(this).is(':checked')) ? true : false;
break;
case 'number':
environment_variables[this.id] = Number(this.value);
break;
default:
console.warn(this.id + ' not defined when running simulation!');
break;
}

View File

@ -64,6 +64,13 @@ var initGUI = function(model_params) {
});
};
var addNumberInput = function(name, value) {
var wrapper = $('<div>').attr('class', 'col-sm-6').height('110px');
var label = $('<div>').width('100%').text(name).css('text-align', 'center').css('font-weight', 'bolder').appendTo(wrapper);
var input = $('<input>').attr('id', name).attr('type', 'number').attr('class', 'form-control').attr('value', value).attr('min', 0).css('margin-top', '18px').appendTo(wrapper);
$('#wrapper-settings').append(wrapper);
}
var addTextBox = function(param, obj) {
var well = $('<div class="well">' + obj.value + '</div>')[0];
sidebar.append(well);
@ -81,8 +88,11 @@ var initGUI = function(model_params) {
case 'number':
addSliderInput(model_params[option]['label'], model_params[option]['value']);
break;
case 'great_number':
addNumberInput(model_params[option]['label'], model_params[option]['value']);
break;
default:
console.log(model_params[option]['label'] + ' not defined!');
console.warn(model_params[option]['label'] + ' not defined!');
break;
}
}

View File

@ -14,6 +14,7 @@
// Private constants
var focus_opacity = 0.1,
radius = 8,
shape_size = 16,
required_node = ['id', 'index', 'label', 'px', 'py', 'spells', 'weight', 'x', 'y', 'pos', 'scx', 'scy'];
// Private variables
@ -29,8 +30,10 @@
zoom, // Zoom
groot, // Append sections to svg to have nodes and edges separately
graph_wrapper,
glinks,
gnodes,
background_image,
data_node, // Actual node data for the graph
data_link, // Actual link data for the graph
@ -38,7 +41,8 @@
node, // Circles for the nodes
shape_property, // Property to whom the shape will be applied
shapes, // Dictionary of shapes for nodes
colors; // Dictionary of colors for nodes
colors, // Dictionary of colors for nodes
background; // Background of the graph
Number.prototype.between = function(min, max) {
var min = (min || min === 0) ? min : Math.max(),
@ -221,9 +225,18 @@
.size([width, height]);
// Append sections to svg to have nodes and edges separately
groot = svg.append('g') .attr('id', 'root');
groot = svg.append('g').attr('id', 'root');
// Set background
if ( background !== undefined ) {
background_image = groot.append('image').attr('href', background).style('opacity', '0.8');
graph_wrapper = groot.append('g') .attr('id', 'graph-wrapper');
glinks = graph_wrapper.append('g') .attr('id', 'links');
gnodes = graph_wrapper.append('g') .attr('id', 'nodes');
} else {
glinks = groot.append('g') .attr('id', 'links');
gnodes = groot.append('g') .attr('id', 'nodes');
}
// Add patterns for shapes
var defs = [];
@ -245,8 +258,8 @@
.attr('href', function(d) {
return window.location.protocol + '//' + window.location.host + '/img/svg/' + d + '.svg';
})
.attr('width', 16)
.attr('height', 16);
.attr('width', shape_size)
.attr('height', shape_size);
// Zoom
zoom = d3.behavior
@ -447,10 +460,25 @@
radius = r(distance);
node.attr('r', radius);
var s = d3.scale.linear().domain([30, 1000]).range([16, 48]);
if ( shapes instanceof Object && shape_property ) {
svg.selectAll('pattern image').attr('width', s(distance)).attr('height', s(distance));
}
if (callback) { callback(radius); }
}
}
/**
* Set background image.
* A function that set a background image.
*
* @param {object} image Path to image.
*/
function set_background(image) {
background = image;
}
/**
* Set property and instant of time.
* A function that draws the graph depends on the property and instant of time selected.
@ -623,6 +651,7 @@
update_graph: update_graph,
set_params: set_params,
set_link_distance: set_link_distance,
set_background: set_background,
fit: zoom_to_fit,
reset: reset,