Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
rrs
viewer
log-segmentation
Commits
342fea6f
Unverified
Commit
342fea6f
authored
Nov 19, 2022
by
Juon Kawakami
🥗
Browse files
init
parent
54f6cedf
Changes
935
Expand all
Show whitespace changes
Inline
Side-by-side
modules/clear/src/clear/ClearSimulator.java
0 → 100644
View file @
342fea6f
package
clear
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
rescuecore2.log.Logger
;
import
rescuecore2.messages.Command
;
import
rescuecore2.messages.control.KSCommands
;
import
rescuecore2.misc.geometry.GeometryTools2D
;
import
rescuecore2.misc.geometry.Line2D
;
import
rescuecore2.misc.geometry.Point2D
;
import
rescuecore2.standard.components.StandardSimulator
;
import
rescuecore2.standard.entities.Area
;
import
rescuecore2.standard.entities.Blockade
;
import
rescuecore2.standard.entities.PoliceForce
;
import
rescuecore2.standard.entities.Road
;
import
rescuecore2.standard.entities.StandardEntity
;
import
rescuecore2.standard.messages.AKClear
;
import
rescuecore2.standard.messages.AKClearArea
;
import
rescuecore2.worldmodel.ChangeSet
;
import
rescuecore2.worldmodel.EntityID
;
/**
* The area model clear simulator. This simulator processes AKClear messages.
*/
public
class
ClearSimulator
extends
StandardSimulator
{
private
static
final
String
SIMULATOR_NAME
=
"Area Model Clear Simulator"
;
private
static
final
String
REPAIR_RATE_KEY
=
"clear.repair.rate"
;
private
static
final
String
REPAIR_RAD_KEY
=
"clear.repair.rad"
;
private
static
final
String
REPAIR_DISTANCE_KEY
=
"clear.repair.distance"
;
// Converts square mm to square m.
private
static
final
double
REPAIR_COST_FACTOR
=
0.000001
;
private
int
repairRate
;
private
int
repairRadius
;
private
int
repairDistance
;
@Override
public
String
getName
()
{
return
SIMULATOR_NAME
;
}
@Override
protected
void
postConnect
()
{
this
.
repairRate
=
config
.
getIntValue
(
REPAIR_RATE_KEY
);
this
.
repairRadius
=
config
.
getIntValue
(
REPAIR_RAD_KEY
);
this
.
repairDistance
=
config
.
getIntValue
(
REPAIR_DISTANCE_KEY
);
}
@Override
protected
void
processCommands
(
KSCommands
c
,
ChangeSet
changes
)
{
long
start
=
System
.
currentTimeMillis
();
int
time
=
c
.
getTime
();
Logger
.
info
(
"Timestep "
+
time
);
Map
<
Blockade
,
Integer
>
partiallyCleared
=
new
HashMap
<>();
Set
<
EntityID
>
cleared
=
new
HashSet
<>();
for
(
Command
command
:
c
.
getCommands
())
{
if
((
command
instanceof
AKClear
clear
)
&&
isValid
(
clear
,
cleared
))
{
Logger
.
debug
(
"Processing "
+
clear
);
EntityID
blockadeID
=
clear
.
getTarget
();
Blockade
blockade
=
(
Blockade
)
model
.
getEntity
(
blockadeID
);
Area
area
=
(
Area
)
model
.
getEntity
(
blockade
.
getPosition
());
int
cost
=
blockade
.
getRepairCost
();
Logger
.
debug
(
"Blockade repair cost: "
+
cost
);
Logger
.
debug
(
"Blockade repair rate: "
+
this
.
repairRate
);
if
(
this
.
repairRate
>=
cost
)
{
// Remove the blockade entirely
List
<
EntityID
>
ids
=
new
ArrayList
<>(
area
.
getBlockades
());
ids
.
remove
(
blockadeID
);
area
.
setBlockades
(
ids
);
model
.
removeEntity
(
blockadeID
);
changes
.
addChange
(
area
,
area
.
getBlockadesProperty
());
changes
.
entityDeleted
(
blockadeID
);
partiallyCleared
.
remove
(
blockade
);
cleared
.
add
(
blockadeID
);
Logger
.
debug
(
"Cleared "
+
blockade
);
}
else
{
// Update the repair cost
if
(!
partiallyCleared
.
containsKey
(
blockade
))
{
partiallyCleared
.
put
(
blockade
,
cost
);
}
cost
-=
this
.
repairRate
;
blockade
.
setRepairCost
(
cost
);
changes
.
addChange
(
blockade
,
blockade
.
getRepairCostProperty
());
}
}
else
if
((
command
instanceof
AKClearArea
clearArea
)
&&
(
isValid
(
clearArea
)))
{
processClearArea
(
clearArea
,
changes
);
Logger
.
debug
(
"Processing "
+
clearArea
);
}
}
// Shrink partially cleared blockades
for
(
Map
.
Entry
<
Blockade
,
Integer
>
next
:
partiallyCleared
.
entrySet
())
{
Blockade
b
=
next
.
getKey
();
double
original
=
next
.
getValue
();
double
current
=
b
.
getRepairCost
();
// d is the new size relative to the old size
double
d
=
current
/
original
;
Logger
.
debug
(
"Partially cleared "
+
b
);
Logger
.
debug
(
"Original repair cost: "
+
original
);
Logger
.
debug
(
"New repair cost: "
+
current
);
Logger
.
debug
(
"Proportion left: "
+
d
);
int
[]
apexes
=
b
.
getApexes
();
double
cx
=
b
.
getX
();
double
cy
=
b
.
getY
();
// Move each apex towards the centre
for
(
int
i
=
0
;
i
<
apexes
.
length
;
i
+=
2
)
{
double
x
=
apexes
[
i
];
double
y
=
apexes
[
i
+
1
];
double
dx
=
x
-
cx
;
double
dy
=
y
-
cy
;
// Shift both x and y so they are now d * dx from the centre
double
newX
=
cx
+
(
dx
*
d
);
double
newY
=
cy
+
(
dy
*
d
);
apexes
[
i
]
=
(
int
)
newX
;
apexes
[
i
+
1
]
=
(
int
)
newY
;
}
b
.
setApexes
(
apexes
);
changes
.
addChange
(
b
,
b
.
getApexesProperty
());
}
long
end
=
System
.
currentTimeMillis
();
Logger
.
info
(
"Timestep "
+
time
+
" took "
+
(
end
-
start
)
+
" ms"
);
}
private
void
processClearArea
(
AKClearArea
clear
,
ChangeSet
changes
)
{
PoliceForce
agent
=
(
PoliceForce
)
model
.
getEntity
(
clear
.
getAgentID
());
int
targetX
=
clear
.
getDestinationX
();
int
targetY
=
clear
.
getDestinationY
();
int
length
=
this
.
repairDistance
;
Map
<
Blockade
,
java
.
awt
.
geom
.
Area
>
blockades
=
new
HashMap
<>();
for
(
StandardEntity
entity
:
model
.
getObjectsInRange
(
agent
.
getX
(),
agent
.
getY
(),
length
))
{
if
((
entity
instanceof
Area
area
)
&&
(
area
.
isBlockadesDefined
()))
{
for
(
EntityID
blockadeID
:
area
.
getBlockades
())
{
Blockade
blockade
=
(
Blockade
)
model
.
getEntity
(
blockadeID
);
if
(
blockade
!=
null
)
{
if
(
blockade
.
getShape
()
==
null
)
{
Logger
.
debug
(
"Blockade Shape is null"
);
}
blockades
.
put
(
blockade
,
new
java
.
awt
.
geom
.
Area
(
blockade
.
getShape
()));
}
}
}
}
int
counter
=
0
;
int
min
=
0
;
int
max
=
2
*
length
;
while
(
true
)
{
counter
++;
length
=
(
min
+
max
)
/
2
;
java
.
awt
.
geom
.
Area
area
=
Geometry
.
getClearArea
(
agent
,
targetX
,
targetY
,
length
,
this
.
repairRadius
);
double
firstSurface
=
Geometry
.
surface
(
area
);
for
(
java
.
awt
.
geom
.
Area
blockade
:
blockades
.
values
())
area
.
subtract
(
blockade
);
double
surface
=
Geometry
.
surface
(
area
);
double
clearedSurface
=
firstSurface
-
surface
;
if
((
clearedSurface
*
REPAIR_COST_FACTOR
)
>
this
.
repairRate
)
{
max
=
length
;
}
else
if
((
counter
!=
1
)
&&
(
counter
<
15
)
&&
((
max
-
min
)
>
5
))
{
min
=
length
;
}
else
{
break
;
}
}
java
.
awt
.
geom
.
Area
area
=
Geometry
.
getClearArea
(
agent
,
targetX
,
targetY
,
length
,
this
.
repairRadius
);
for
(
Map
.
Entry
<
Blockade
,
java
.
awt
.
geom
.
Area
>
entry
:
blockades
.
entrySet
())
{
Blockade
blockade
=
entry
.
getKey
();
java
.
awt
.
geom
.
Area
blockadeArea
=
entry
.
getValue
();
Road
road
=
(
Road
)
model
.
getEntity
(
blockade
.
getPosition
());
double
firstSurface
=
Geometry
.
surface
(
blockadeArea
);
blockadeArea
.
subtract
(
area
);
double
surface
=
Geometry
.
surface
(
blockadeArea
);
if
(
surface
<
firstSurface
)
{
changes
.
addChange
(
blockade
,
blockade
.
getApexesProperty
());
List
<
int
[]>
areas
=
Geometry
.
getAreas
(
blockadeArea
);
if
(
areas
.
size
()
==
1
)
{
Blockade
backupBlockade
=
blockade
;
blockade
=
updateBlockadeApexes
(
blockade
,
areas
.
get
(
0
));
if
(
blockade
==
null
)
{
blockade
=
backupBlockade
;
areas
.
clear
();
}
else
{
changes
.
addChange
(
blockade
,
blockade
.
getApexesProperty
());
changes
.
addChange
(
blockade
,
blockade
.
getXProperty
());
changes
.
addChange
(
blockade
,
blockade
.
getYProperty
());
changes
.
addChange
(
blockade
,
blockade
.
getRepairCostProperty
());
}
}
if
(
areas
.
size
()
!=
1
)
{
try
{
List
<
EntityID
>
newIDs
=
requestNewEntityIDs
(
areas
.
size
());
Iterator
<
EntityID
>
it
=
newIDs
.
iterator
();
List
<
Blockade
>
newBlockades
=
new
ArrayList
<>();
if
(!
areas
.
isEmpty
())
Logger
.
debug
(
"Creating new blockade objects for "
+
blockade
.
getID
().
getValue
()
+
" "
+
areas
.
size
());
for
(
int
[]
apexes
:
areas
)
{
EntityID
id
=
it
.
next
();
Blockade
b
=
makeBlockade
(
id
,
apexes
,
road
.
getID
());
if
(
b
!=
null
)
newBlockades
.
add
(
b
);
}
List
<
EntityID
>
existing
=
road
.
getBlockades
();
List
<
EntityID
>
ids
=
new
ArrayList
<>();
if
(
existing
!=
null
)
ids
.
addAll
(
existing
);
for
(
Blockade
b
:
newBlockades
)
{
ids
.
add
(
b
.
getID
());
}
ids
.
remove
(
blockade
.
getID
());
road
.
setBlockades
(
ids
);
changes
.
addAll
(
newBlockades
);
model
.
removeEntity
(
blockade
.
getID
());
changes
.
addChange
(
road
,
road
.
getBlockadesProperty
());
changes
.
entityDeleted
(
blockade
.
getID
());
}
catch
(
InterruptedException
e
)
{
Logger
.
error
(
"Interrupted while requesting IDs"
);
}
}
}
}
}
private
Blockade
updateBlockadeApexes
(
Blockade
blockade
,
int
[]
apexes
)
{
List
<
Point2D
>
points
=
GeometryTools2D
.
vertexArrayToPoints
(
apexes
);
if
(
points
.
size
()
>=
2
)
{
Point2D
centroid
=
GeometryTools2D
.
computeCentroid
(
points
);
blockade
.
setApexes
(
apexes
);
blockade
.
setX
((
int
)
centroid
.
getX
());
blockade
.
setY
((
int
)
centroid
.
getY
());
int
cost
=
(
int
)
(
GeometryTools2D
.
computeArea
(
points
)
*
REPAIR_COST_FACTOR
);
if
(
cost
!=
0
)
{
blockade
.
setRepairCost
(
cost
);
return
blockade
;
}
}
return
null
;
}
private
Blockade
makeBlockade
(
EntityID
id
,
int
[]
apexes
,
EntityID
roadID
)
{
Blockade
blockade
=
new
Blockade
(
id
);
blockade
.
setPosition
(
roadID
);
return
updateBlockadeApexes
(
blockade
,
apexes
);
}
private
boolean
isValid
(
AKClear
clear
,
Set
<
EntityID
>
cleared
)
{
// Check Target
StandardEntity
target
=
model
.
getEntity
(
clear
.
getTarget
());
if
(
target
==
null
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": target does not exist"
);
return
false
;
}
else
if
(
cleared
.
contains
(
clear
.
getTarget
()))
{
Logger
.
info
(
"Ignoring clear command "
+
clear
+
": target already cleared in this timestep"
);
return
false
;
}
else
if
(!(
target
instanceof
Blockade
))
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": target is not a blockade"
);
return
false
;
}
// Check Agent
StandardEntity
agent
=
model
.
getEntity
(
clear
.
getAgentID
());
if
(
agent
==
null
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent does not exist"
);
return
false
;
}
else
if
(!(
agent
instanceof
PoliceForce
))
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent is not a PoliceForce"
);
return
false
;
}
// Check PoliceForce
PoliceForce
police
=
(
PoliceForce
)
agent
;
StandardEntity
agentPosition
=
police
.
getPosition
(
model
);
if
(
agentPosition
==
null
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": could not locate the agent"
);
return
false
;
}
else
if
(!
police
.
isHPDefined
()
||
police
.
getHP
()
<=
0
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent is dead"
);
return
false
;
}
else
if
(
police
.
isBuriednessDefined
()
&&
police
.
getBuriedness
()
>
0
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent is buried"
);
return
false
;
}
// Check Blockade
Blockade
targetBlockade
=
(
Blockade
)
target
;
if
(!
targetBlockade
.
isPositionDefined
())
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": blockade position undefined"
);
return
false
;
}
else
if
(!
targetBlockade
.
isRepairCostDefined
())
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": blockade has no repair cost"
);
return
false
;
}
// Check Any Blockade to Clear
Point2D
agentLocation
=
new
Point2D
(
police
.
getX
(),
police
.
getY
());
double
bestDistance
=
Double
.
MAX_VALUE
;
for
(
Line2D
line
:
GeometryTools2D
.
pointsToLines
(
GeometryTools2D
.
vertexArrayToPoints
(
targetBlockade
.
getApexes
()),
true
))
{
Point2D
closest
=
GeometryTools2D
.
getClosestPointOnSegment
(
line
,
agentLocation
);
double
distance
=
GeometryTools2D
.
getDistance
(
agentLocation
,
closest
);
if
(
distance
<
this
.
repairDistance
)
{
return
true
;
}
else
if
(
bestDistance
>
distance
)
{
bestDistance
=
distance
;
}
}
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent is not adjacent to a target: closest blockade is "
+
bestDistance
);
return
false
;
}
private
boolean
isValid
(
AKClearArea
clear
)
{
StandardEntity
agent
=
model
.
getEntity
(
clear
.
getAgentID
());
if
(
agent
==
null
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent does not exist"
);
return
false
;
}
else
if
(!(
agent
instanceof
PoliceForce
))
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
": agent is not a police officer"
);
return
false
;
}
// Check PoliceForce
PoliceForce
police
=
(
PoliceForce
)
agent
;
StandardEntity
agentPosition
=
police
.
getPosition
(
model
);
if
(!(
agentPosition
instanceof
Area
))
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
" : could not locate agent"
);
return
false
;
}
else
if
(!
police
.
isHPDefined
()
||
police
.
getHP
()
<=
0
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
" : agent is dead"
);
return
false
;
}
else
if
(
police
.
isBuriednessDefined
()
&&
police
.
getBuriedness
()
>
0
)
{
Logger
.
info
(
"Rejecting clear command "
+
clear
+
" : agent is buried"
);
return
false
;
}
return
true
;
}
}
\ No newline at end of file
modules/clear/src/clear/Geometry.java
0 → 100644
View file @
342fea6f
package
clear
;
import
java.awt.Polygon
;
import
java.awt.geom.Area
;
import
java.awt.geom.PathIterator
;
import
java.util.ArrayList
;
import
java.util.List
;
import
rescuecore2.misc.geometry.Line2D
;
import
rescuecore2.misc.geometry.Vector2D
;
import
rescuecore2.standard.entities.Human
;
public
class
Geometry
{
public
static
Area
getClearArea
(
Human
agent
,
int
targetX
,
int
targetY
,
int
clearLength
,
int
clearRad
)
{
Vector2D
agentToTarget
=
new
Vector2D
(
targetX
-
agent
.
getX
(),
targetY
-
agent
.
getY
());
if
(
agentToTarget
.
getLength
()
>
clearLength
)
agentToTarget
=
agentToTarget
.
normalised
().
scale
(
clearLength
);
agentToTarget
=
agentToTarget
.
normalised
()
.
scale
(
agentToTarget
.
getLength
()
+
510
);
Vector2D
backAgent
=
(
new
Vector2D
(
agent
.
getX
(),
agent
.
getY
()))
.
add
(
agentToTarget
.
normalised
().
scale
(-
510
));
Line2D
line
=
new
Line2D
(
backAgent
.
getX
(),
backAgent
.
getY
(),
agentToTarget
.
getX
(),
agentToTarget
.
getY
());
Vector2D
dir
=
agentToTarget
.
normalised
().
scale
(
clearRad
);
Vector2D
perpend1
=
new
Vector2D
(-
dir
.
getY
(),
dir
.
getX
());
Vector2D
perpend2
=
new
Vector2D
(
dir
.
getY
(),
-
dir
.
getX
());
rescuecore2
.
misc
.
geometry
.
Point2D
points
[]
=
new
rescuecore2
.
misc
.
geometry
.
Point2D
[]
{
line
.
getOrigin
().
plus
(
perpend1
),
line
.
getEndPoint
().
plus
(
perpend1
),
line
.
getEndPoint
().
plus
(
perpend2
),
line
.
getOrigin
().
plus
(
perpend2
)};
int
[]
xPoints
=
new
int
[
points
.
length
];
int
[]
yPoints
=
new
int
[
points
.
length
];
for
(
int
i
=
0
;
i
<
points
.
length
;
i
++)
{
xPoints
[
i
]
=
(
int
)
points
[
i
].
getX
();
yPoints
[
i
]
=
(
int
)
points
[
i
].
getY
();
}
return
new
Area
(
new
Polygon
(
xPoints
,
yPoints
,
points
.
length
));
}
public
static
double
surface
(
Area
area
)
{
PathIterator
iter
=
area
.
getPathIterator
(
null
);
double
sum_all
=
0
;
while
(!
iter
.
isDone
())
{
List
<
double
[]>
points
=
new
ArrayList
<
double
[]>();
while
(!
iter
.
isDone
())
{
double
point
[]
=
new
double
[
2
];
int
type
=
iter
.
currentSegment
(
point
);
iter
.
next
();
if
(
type
==
PathIterator
.
SEG_CLOSE
)
{
if
(
points
.
size
()
>
0
)
points
.
add
(
points
.
get
(
0
));
break
;
}
points
.
add
(
point
);
}
double
sum
=
0
;
for
(
int
i
=
0
;
i
<
points
.
size
()
-
1
;
i
++)
sum
+=
points
.
get
(
i
)[
0
]
*
points
.
get
(
i
+
1
)[
1
]
-
points
.
get
(
i
)[
1
]
*
points
.
get
(
i
+
1
)[
0
];
sum_all
+=
Math
.
abs
(
sum
)
/
2
;
}
return
sum_all
;
}
public
static
List
<
int
[]>
getAreas
(
Area
area
)
{
PathIterator
iter
=
area
.
getPathIterator
(
null
);
List
<
int
[]>
areas
=
new
ArrayList
<
int
[]>();
ArrayList
<
Integer
>
list
=
new
ArrayList
<
Integer
>();
while
(!
iter
.
isDone
())
{
double
point
[]
=
new
double
[
2
];
// x, y
int
type
=
iter
.
currentSegment
(
point
);
if
(
type
==
PathIterator
.
SEG_CLOSE
)
{
if
(
list
.
size
()
>
0
)
{
int
[]
newArea
=
new
int
[
list
.
size
()];
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
newArea
[
i
]
=
list
.
get
(
i
);
areas
.
add
(
newArea
);
list
=
new
ArrayList
<
Integer
>();
}
}
else
{
list
.
add
((
int
)
point
[
0
]);
list
.
add
((
int
)
point
[
1
]);
}
iter
.
next
();
}
return
areas
;
}
}
\ No newline at end of file
modules/collapse/src/collapse/CSBuilding.java
0 → 100644
View file @
342fea6f
package
collapse
;
import
rescuecore2.standard.entities.Building
;
/**
* Collapse Simulator Building (CSBuilding) is a wrapper for the Standard
* Building class that contains extra variables created, updated and used by the
* Collapse Simulator only. This class is created in order to prevented
* unnecessary changes to the Standard Building class.
*
* @author Salim
*
*/
public
class
CSBuilding
{
/**
* The reference to the real building class
*/
private
final
Building
real
;
/**
* Collapse Ratio shows the percent that the building has been collapsed so
* far.
*/
private
float
collapsedRatio
=
0
;
/**
* This shows whether the building has fire damage in the last cycle or not
*/
private
boolean
hasFireDamage
=
false
;
public
CSBuilding
(
Building
building
)
{
real
=
building
;
}
/**
* Returns the building's collapse ratio
*
* @return
*/
public
float
getCollapsedRatio
()
{
return
collapsedRatio
;
}
/**
* Changes the collapse ratio of the building to the input ratio
*
* @param collapsedRatio
* is a float
*/
public
void
setCollapsedRatio
(
float
collapsedRatio
)
{
this
.
collapsedRatio
=
collapsedRatio
;
}
/**
* Adds the input ratio to the building's collapse ratio
*
* @param ratio
* is a float that represents the increased value of the collapse
* ratio
*/
public
void
increaseCollapseRatio
(
float
ratio
)
{
setCollapsedRatio
(
getCollapsedRatio
()
+
ratio
);
}
public
Building
getReal
()
{
return
real
;
}
/**
* Returns the extent that is still possible to collapse.
*
* @return a float representing the extent
*/
public
double
getRemainingToCollapse
(
double
floorHeight
)
{
return
floorHeight
*
real
.
getFloors
()
*
(
1
-
getCollapsedRatio
());
}
public
boolean
hasFireDamage
()
{
return
false
;
}
public
void
setHasFireDamage
(
boolean
hasFireDamage
)
{
this
.
hasFireDamage
=
hasFireDamage
;
}
public
double
getTotalCollapse
(
double
floorHeight
){
return
floorHeight
*
real
.
getFloors
();
}
}
modules/collapse/src/collapse/CollapseSimulator.java
0 → 100755
View file @
342fea6f
This diff is collapsed.
Click to expand it.
modules/collapse/src/collapse/CollapseSimulatorGUI.java
0 → 100755
View file @
342fea6f
package
collapse
;
import
javax.swing.JPanel
;
import
javax.swing.JProgressBar
;
import
javax.swing.JLabel
;
import
javax.swing.SwingUtilities
;
import
java.awt.GridLayout
;
/**
GUI for the collapse simulator.
*/
public
class
CollapseSimulatorGUI
extends
JPanel
{
private
JLabel
timeLabel
;
private
JLabel
statusLabel
;
private
JProgressBar
collapseProgress
;
private
JProgressBar
fireProgress
;
private
JProgressBar
blockadeProgress
;
private
int
collapse
;
private
int
fire
;
private
int
block
;
/**
Construct a collapse simulator GUI.
*/
public
CollapseSimulatorGUI
()
{
super
(
new
GridLayout
(
0
,
2
));
timeLabel
=
new
JLabel
(
"Not started"
);
statusLabel
=
new
JLabel
(
"Not started"
);
collapseProgress
=
new
JProgressBar
(
0
,
1
);
fireProgress
=
new
JProgressBar
(
0
,
1
);
blockadeProgress
=
new
JProgressBar
(
0
,
1
);
collapseProgress
.
setStringPainted
(
true
);
fireProgress
.
setStringPainted
(
true
);
blockadeProgress
.
setStringPainted
(
true
);
add
(
new
JLabel
(
"Timestep"
));
add
(
timeLabel
);
add
(
new
JLabel
(
"Status"
));
add
(
statusLabel
);
add
(
new
JLabel
(
"Collapsing buildings"
));
add
(
collapseProgress
);
add
(
new
JLabel
(
"Fire damage"
));
add
(
fireProgress
);
add
(
new
JLabel
(
"Creating blockades"
));
add
(
blockadeProgress
);
}
/**
Notify the gui that a new timestep has started.
@param time The timestep.
*/
void
timestep
(
final
int
time
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
timeLabel
.
setText
(
String
.
valueOf
(
time
));
collapseProgress
.
setValue
(
0
);
fireProgress
.
setValue
(
0
);
blockadeProgress
.
setValue
(
0
);
collapse
=
0
;
fire
=
0
;
block
=
0
;
}
});
}
/**
Notify the gui that collapse computation has begun.
@param buildingCount The number of buildings to process.
*/
void
startCollapse
(
final
int
buildingCount
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
statusLabel
.
setText
(
"Collapsing buildings"
);
collapseProgress
.
setMaximum
(
buildingCount
);
collapseProgress
.
setValue
(
0
);
collapse
=
0
;
}
});
}
/**
Notify the gui that a building collapse has been processed.
*/
void
bumpCollapse
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
collapseProgress
.
setValue
(++
collapse
);
}
});
}
/**
Notify the gui that building collapse computation is complete.
*/
void
endCollapse
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
collapseProgress
.
setValue
(
collapseProgress
.
getMaximum
());
}
});
}
/**
Notify the gui that fire collapse computation has begun.
@param buildingCount The number of buildings to process.
*/
void
startFire
(
final
int
buildingCount
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
statusLabel
.
setText
(
"Fire damage"
);
fireProgress
.
setMaximum
(
buildingCount
);
fireProgress
.
setValue
(
0
);
fire
=
0
;
}
});
}
/**
Notify the gui that a fire collapse has been processed.
*/
void
bumpFire
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
fireProgress
.
setValue
(++
fire
);
}
});
}
/**
Notify the gui that fire collapse computation is complete.
*/
void
endFire
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
fireProgress
.
setValue
(
fireProgress
.
getMaximum
());
}
});
}
/**
Notify the gui that blockade generation has begun.
@param buildingCount The number of buildings to process.
*/
void
startBlock
(
final
int
buildingCount
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
statusLabel
.
setText
(
"Computing blockades"
);
if
(
buildingCount
==
0
)
{
blockadeProgress
.
setMaximum
(
1
);
blockadeProgress
.
setValue
(
1
);
}
else
{
blockadeProgress
.
setMaximum
(
buildingCount
);
blockadeProgress
.
setValue
(
0
);
block
=
0
;
}
}
});
}
/**
Notify the gui that blockade generation for a building has been processed.
*/
void
bumpBlock
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
blockadeProgress
.
setValue
(++
block
);
}
});
}
/**
Notify the gui that blockade generation is complete.
*/
void
endBlock
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
blockadeProgress
.
setValue
(
blockadeProgress
.
getMaximum
());
statusLabel
.
setText
(
"Done"
);
}
});
}
}
\ No newline at end of file
modules/collapse/src/collapse/CollapseWorldModel.java
0 → 100644
View file @
342fea6f
package
collapse
;
import
java.util.HashMap
;
import
rescuecore2.messages.control.KSAfterShocksInfo
;
import
rescuecore2.standard.entities.Building
;
import
rescuecore2.standard.entities.StandardEntity
;
import
rescuecore2.standard.entities.StandardEntityURN
;
import
rescuecore2.standard.entities.StandardWorldModel
;
import
rescuecore2.worldmodel.ChangeSet
;
import
rescuecore2.worldmodel.EntityID
;
/**
*
* Collapse simulator's world model contains aftershocks' information that other
* simulators don't need.
*
* @author Salim
*
*/
public
class
CollapseWorldModel
extends
StandardWorldModel
{
private
HashMap
<
Integer
,
Float
>
aftershocks
;
private
HashMap
<
Building
,
CSBuilding
>
collapseBuildings
;
public
CollapseWorldModel
()
{
this
.
aftershocks
=
new
HashMap
<
Integer
,
Float
>();
collapseBuildings
=
new
HashMap
<
Building
,
CSBuilding
>();
}
@Override
public
void
merge
(
ChangeSet
changes
)
{
super
.
merge
(
changes
);
}
/**
* Changes the list in the world model with the new input aftershock list
*
* @param msg
* instance of KSAfterShocksInfo
*/
public
void
updateAftershocks
(
KSAfterShocksInfo
msg
)
{
aftershocks
=
msg
.
getAftershocks
();
}
public
boolean
aftershockHappens
(
int
time
)
{
return
aftershocks
.
get
(
time
)
!=
null
;
}
public
float
aftershockIntensity
(
int
time
)
{
return
aftershocks
.
get
(
time
);
}
public
HashMap
<
Building
,
CSBuilding
>
getCollapseBuildings
()
{
if
(
collapseBuildings
.
size
()
==
0
)
createCollapseBuildings
();
return
collapseBuildings
;
}
/**
* Creates Collapse Simulator Buildings using the Standard Buildings
*/
private
void
createCollapseBuildings
()
{
for
(
StandardEntity
entity
:
this
)
{
if
(
entity
instanceof
Building
)
collapseBuildings
.
put
((
Building
)
entity
,
new
CSBuilding
((
Building
)
entity
));
}
}
/**
* Returns a specific CSBuilding by its EntityID
*
* @param id
* is an EntityID
* @return the corresponding CSBuilding to id
*/
public
CSBuilding
getCSBuiding
(
EntityID
id
)
{
return
getCollapseBuildings
().
get
((
Building
)
getEntity
(
id
));
}
/**
* Returns a specific CSBuilding by its Building
*
* @param building
* is an Building
* @return the corresponding CSBuilding to building
*/
public
CSBuilding
getCSBuiding
(
Building
building
)
{
return
getCollapseBuildings
().
get
(
building
);
}
}
modules/gis2/src/gis2/GISServer.java
0 → 100644
View file @
342fea6f
package
gis2
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.net.Socket
;
import
org.apache.log4j.Logger
;
import
rescuecore2.Constants
;
import
rescuecore2.config.Config
;
import
rescuecore2.connection.Connection
;
import
rescuecore2.connection.ConnectionException
;
import
rescuecore2.connection.ConnectionListener
;
import
rescuecore2.connection.TCPConnection
;
import
rescuecore2.messages.Message
;
import
rescuecore2.messages.control.GKConnectOK
;
import
rescuecore2.messages.control.KGConnect
;
import
rescuecore2.messages.control.Shutdown
;
import
rescuecore2.misc.CommandLineOptions
;
import
rescuecore2.misc.java.LoadableTypeProcessor
;
import
rescuecore2.registry.Registry
;
import
rescuecore2.worldmodel.Entity
;
import
rescuecore2.worldmodel.WorldModel
;
/**
* This class is used for starting a remote GIS server.
*/
public
final
class
GISServer
{
private
static
final
long
WAIT_TIME
=
1000
;
private
ServerSocket
server
;
private
WorldModel
<?
extends
Entity
>
world
;
private
volatile
boolean
running
;
private
static
final
Logger
LOG
=
Logger
.
getLogger
(
GISServer
.
class
);
private
GISServer
(
int
port
,
WorldModel
<?
extends
Entity
>
world
)
throws
IOException
{
server
=
new
ServerSocket
(
port
);
this
.
world
=
world
;
running
=
true
;
}
/**
* Start the GIS server.
*
* @param args Command line arguments: <-c config file>
*/
public
static
void
main
(
String
[]
args
)
{
Config
config
=
new
Config
();
try
{
CommandLineOptions
.
processArgs
(
args
,
config
);
int
port
=
config
.
getIntValue
(
Constants
.
GIS_PORT_NUMBER_KEY
,
Constants
.
DEFAULT_GIS_PORT_NUMBER
);
processJarFiles
(
config
);
GMLWorldModelCreator
creator
=
new
GMLWorldModelCreator
();
new
GISServer
(
port
,
creator
.
buildWorldModel
(
config
)).
run
();
LOG
.
info
(
"GIS server listening on port "
+
port
);
}
catch
(
Exception
e
)
{
LOG
.
fatal
(
"Error starting GIS server"
,
e
);
}
}
private
static
void
processJarFiles
(
Config
config
)
throws
IOException
{
LoadableTypeProcessor
processor
=
new
LoadableTypeProcessor
(
config
);
processor
.
addFactoryRegisterCallbacks
(
Registry
.
SYSTEM_REGISTRY
);
processor
.
process
();
}
/**
* Run the GIS server.
*/
public
void
run
()
{
while
(
running
)
{
try
{
Socket
socket
=
server
.
accept
();
new
ServerThread
(
socket
).
start
();
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Error accepting connection"
,
e
);
running
=
false
;
}
}
}
private
class
ServerThread
extends
Thread
implements
ConnectionListener
{
private
Socket
socket
;
private
boolean
dead
;
public
ServerThread
(
Socket
socket
)
{
this
.
socket
=
socket
;
dead
=
false
;
}
@Override
public
void
run
()
{
TCPConnection
c
=
null
;
try
{
c
=
new
TCPConnection
(
socket
);
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Error starting TCPConnection"
,
e
);
return
;
}
c
.
startup
();
c
.
addConnectionListener
(
this
);
synchronized
(
this
)
{
while
(!
dead
)
{
try
{
this
.
wait
(
WAIT_TIME
);
}
catch
(
InterruptedException
e
)
{
dead
=
true
;
}
}
}
c
.
shutdown
();
}
@Override
public
void
messageReceived
(
Connection
c
,
Message
msg
)
{
if
(
msg
instanceof
KGConnect
)
{
// Send a GKConnectOK
try
{
c
.
sendMessage
(
new
GKConnectOK
(
world
.
getAllEntities
()));
}
catch
(
ConnectionException
e
)
{
LOG
.
fatal
(
"Error sending message"
,
e
);
die
();
}
}
if
(
msg
instanceof
Shutdown
)
{
die
();
}
}
private
void
die
()
{
synchronized
(
this
)
{
dead
=
true
;
notifyAll
();
}
running
=
false
;
}
}
}
\ No newline at end of file
modules/gis2/src/gis2/GMLWorldModelCreator.java
0 → 100755
View file @
342fea6f
package
gis2
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
kernel.KernelException
;
import
kernel.WorldModelCreator
;
import
maps.CoordinateConversion
;
import
maps.MapException
;
import
maps.MapReader
;
import
maps.ScaleConversion
;
import
maps.gml.GMLBuilding
;
import
maps.gml.GMLCoordinates
;
import
maps.gml.GMLDirectedEdge
;
import
maps.gml.GMLMap
;
import
maps.gml.GMLRoad
;
import
maps.gml.GMLShape
;
import
org.apache.log4j.Logger
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentException
;
import
org.dom4j.io.SAXReader
;
import
rescuecore2.config.Config
;
import
rescuecore2.misc.geometry.GeometryTools2D
;
import
rescuecore2.misc.geometry.Point2D
;
import
rescuecore2.scenario.exceptions.ScenarioException
;
import
rescuecore2.standard.entities.Building
;
import
rescuecore2.standard.entities.Edge
;
import
rescuecore2.standard.entities.Road
;
import
rescuecore2.standard.entities.StandardWorldModel
;
import
rescuecore2.worldmodel.Entity
;
import
rescuecore2.worldmodel.EntityID
;
import
rescuecore2.worldmodel.WorldModel
;
/**
* A WorldModelCreator that reads a GML file and scenario descriptor.
*/
public
class
GMLWorldModelCreator
implements
WorldModelCreator
{
private
static
final
String
MAP_DIRECTORY_KEY
=
"gis.map.dir"
;
private
static
final
String
MAP_FILE_KEY
=
"gis.map.file"
;
private
static
final
String
DEFAULT_MAP_FILE
=
"map.gml"
;
private
static
final
String
SCENARIO_FILE_KEY
=
"gis.map.scenario"
;
private
static
final
String
DEFAULT_SCENARIO_FILE
=
"scenario.xml"
;
private
static
final
String
MAX_FLOOR
=
"gis.map.max-floor"
;
private
static
final
String
FLOOR_PLACEMENT_TYPE
=
"gis.map.floor-placement.random"
;
private
static
final
String
RANDOM_FLOOR_RATE
=
"gis.map.floor-placement.random.floor-rate."
;
private
static
final
String
BUILDING_CODE_PLACEMENT_TYPE
=
"gis.map.building-code-placement.random"
;
private
static
final
String
RANDOM_BUILDING_CODE_RATE
=
"gis.map.building-code-placement.random.code-rate."
;
private
static
final
String
MAX_BUILDING_CODE
=
"gis.map.max-building-code"
;
private
static
final
double
SQ_MM_TO_SQ_M
=
0.000001
;
private
GisScenario
scenario
;
private
static
final
Logger
LOG
=
Logger
.
getLogger
(
GMLWorldModelCreator
.
class
);
// private ShapeDebugFrame debug;
private
int
nextID
;
@Override
public
String
toString
()
{
return
"GML world model creator"
;
}
@Override
public
WorldModel
<?
extends
Entity
>
buildWorldModel
(
Config
config
)
throws
KernelException
{
try
{
StandardWorldModel
result
=
new
StandardWorldModel
();
File
dir
=
new
File
(
config
.
getValue
(
MAP_DIRECTORY_KEY
));
File
mapFile
=
new
File
(
dir
,
config
.
getValue
(
MAP_FILE_KEY
,
DEFAULT_MAP_FILE
));
File
scenarioFile
=
new
File
(
dir
,
config
.
getValue
(
SCENARIO_FILE_KEY
,
DEFAULT_SCENARIO_FILE
));
readMapData
(
mapFile
,
result
,
config
);
readScenarioAndApply
(
scenarioFile
,
result
,
config
);
for
(
Entity
e
:
result
)
{
nextID
=
Math
.
max
(
nextID
,
e
.
getID
().
getValue
());
}
++
nextID
;
result
.
index
();
return
result
;
}
catch
(
MapException
e
)
{
throw
new
KernelException
(
"Couldn't read GML file"
,
e
);
}
catch
(
DocumentException
e
)
{
throw
new
KernelException
(
"Couldn't read scenario file"
,
e
);
}
catch
(
ScenarioException
e
)
{
throw
new
KernelException
(
"Invalid scenario file"
,
e
);
}
}
@Override
public
EntityID
generateID
()
{
return
new
EntityID
(
nextID
++);
}
private
void
readMapData
(
File
mapFile
,
StandardWorldModel
result
,
Config
config
)
throws
MapException
{
int
maxFloor
=
config
.
getIntValue
(
MAX_FLOOR
,
3
);
boolean
randomfloorPlacement
=
config
.
getBooleanValue
(
FLOOR_PLACEMENT_TYPE
,
false
);
int
[]
floorRates
=
null
;
int
[]
floorRatesCumulative
=
null
;
if
(
randomfloorPlacement
)
{
floorRates
=
new
int
[
maxFloor
+
1
];
floorRatesCumulative
=
new
int
[
maxFloor
+
1
];
for
(
int
i
=
1
;
i
<=
maxFloor
;
i
++)
{
floorRates
[
i
]
=
config
.
getIntValue
(
RANDOM_FLOOR_RATE
+
i
);
floorRatesCumulative
[
i
]
=
floorRatesCumulative
[
i
-
1
]
+
floorRates
[
i
];
}
}
int
maxBuildingCode
=
config
.
getIntValue
(
MAX_BUILDING_CODE
,
2
);
boolean
randomBuildingCodePlacement
=
config
.
getBooleanValue
(
BUILDING_CODE_PLACEMENT_TYPE
,
false
);
int
[]
buildingCodeRates
=
null
;
int
[]
buildingCodesCumulative
=
null
;
if
(
randomBuildingCodePlacement
)
{
buildingCodeRates
=
new
int
[
maxBuildingCode
+
1
];
buildingCodesCumulative
=
new
int
[
maxBuildingCode
+
1
];
for
(
int
i
=
0
;
i
<=
maxBuildingCode
;
i
++)
{
buildingCodeRates
[
i
]
=
config
.
getIntValue
(
RANDOM_BUILDING_CODE_RATE
+
i
);
buildingCodesCumulative
[
i
]
=
(
i
>
0
?
buildingCodesCumulative
[
i
-
1
]
:
0
)
+
buildingCodeRates
[
i
];
}
}
GMLMap
map
=
(
GMLMap
)
MapReader
.
readMap
(
mapFile
);
CoordinateConversion
conversion
=
getCoordinateConversion
(
map
);
LOG
.
debug
(
"Creating entities"
);
LOG
.
debug
(
map
.
getBuildings
().
size
()
+
" buildings"
);
LOG
.
debug
(
map
.
getRoads
().
size
()
+
" roads"
);
for
(
GMLBuilding
next
:
map
.
getBuildings
())
{
// Create a new Building entity
EntityID
id
=
new
EntityID
(
next
.
getID
());
Building
b
=
new
Building
(
id
);
List
<
Point2D
>
vertices
=
convertShapeToPoints
(
next
,
conversion
);
double
area
=
GeometryTools2D
.
computeArea
(
vertices
)
*
SQ_MM_TO_SQ_M
;
Point2D
centroid
=
GeometryTools2D
.
computeCentroid
(
vertices
);
// Building properties
int
floors
=
Math
.
min
(
maxFloor
,
next
.
getFloors
());
if
(
randomfloorPlacement
)
{
int
rnd
=
config
.
getRandom
().
nextInt
(
floorRatesCumulative
[
maxFloor
])
+
1
;
for
(
int
i
=
1
;
i
<=
maxFloor
;
i
++)
{
if
(
rnd
<=
floorRatesCumulative
[
i
])
{
floors
=
i
;
break
;
}
}
}
int
code
=
Math
.
min
(
maxBuildingCode
,
next
.
getCode
());
if
(
randomBuildingCodePlacement
)
{
int
rnd
=
config
.
getRandom
()
.
nextInt
(
buildingCodesCumulative
[
maxBuildingCode
])
+
1
;
for
(
int
i
=
0
;
i
<=
maxBuildingCode
;
i
++)
{
if
(
rnd
<=
buildingCodesCumulative
[
i
])
{
code
=
i
;
break
;
}
}
}
b
.
setFloors
(
floors
);
b
.
setFieryness
(
0
);
b
.
setBrokenness
(
0
);
b
.
setBuildingCode
(
code
);
b
.
setBuildingAttributes
(
0
);
b
.
setGroundArea
((
int
)
Math
.
abs
(
area
));
b
.
setTotalArea
(((
int
)
Math
.
abs
(
area
))
*
b
.
getFloors
());
b
.
setImportance
(
next
.
getImportance
());
b
.
setCapacity
(
0
);
// Area properties
b
.
setEdges
(
createEdges
(
next
,
conversion
));
b
.
setX
((
int
)
centroid
.
getX
());
b
.
setY
((
int
)
centroid
.
getY
());
result
.
addEntity
(
b
);
}
for
(
GMLRoad
next
:
map
.
getRoads
())
{
// Create a new Road entity
EntityID
id
=
new
EntityID
(
next
.
getID
());
Road
r
=
new
Road
(
id
);
List
<
Point2D
>
vertices
=
convertShapeToPoints
(
next
,
conversion
);
Point2D
centroid
=
GeometryTools2D
.
computeCentroid
(
vertices
);
// Road properties: None
// Area properties
r
.
setX
((
int
)
centroid
.
getX
());
r
.
setY
((
int
)
centroid
.
getY
());
r
.
setEdges
(
createEdges
(
next
,
conversion
));
result
.
addEntity
(
r
);
}
}
private
void
readScenarioAndApply
(
File
scenarioFile
,
StandardWorldModel
result
,
Config
config
)
throws
DocumentException
,
ScenarioException
{
if
(
scenarioFile
.
exists
())
{
readScenario
(
scenarioFile
,
config
);
LOG
.
debug
(
"Applying scenario"
);
scenario
.
apply
(
result
,
config
);
}
}
private
void
readScenario
(
File
scenarioFile
,
Config
config
)
throws
DocumentException
,
ScenarioException
{
if
(
scenarioFile
.
exists
())
{
SAXReader
reader
=
new
SAXReader
();
LOG
.
debug
(
"Reading scenario"
);
Document
doc
=
reader
.
read
(
scenarioFile
);
scenario
=
new
GisScenario
(
doc
,
config
);
}
}
private
List
<
Edge
>
createEdges
(
GMLShape
s
,
CoordinateConversion
conversion
)
{
List
<
Edge
>
result
=
new
ArrayList
<
Edge
>();
for
(
GMLDirectedEdge
edge
:
s
.
getEdges
())
{
GMLCoordinates
start
=
edge
.
getStartCoordinates
();
GMLCoordinates
end
=
edge
.
getEndCoordinates
();
Integer
neighbourID
=
s
.
getNeighbour
(
edge
);
EntityID
id
=
neighbourID
==
null
?
null
:
new
EntityID
(
neighbourID
);
double
sx
=
conversion
.
convertX
(
start
.
getX
());
double
sy
=
conversion
.
convertY
(
start
.
getY
());
double
ex
=
conversion
.
convertX
(
end
.
getX
());
double
ey
=
conversion
.
convertY
(
end
.
getY
());
result
.
add
(
new
Edge
((
int
)
sx
,
(
int
)
sy
,
(
int
)
ex
,
(
int
)
ey
,
id
));
}
return
result
;
}
private
List
<
Point2D
>
convertShapeToPoints
(
GMLShape
shape
,
CoordinateConversion
conversion
)
{
List
<
Point2D
>
points
=
new
ArrayList
<
Point2D
>();
for
(
GMLCoordinates
next
:
shape
.
getCoordinates
())
{
points
.
add
(
new
Point2D
(
conversion
.
convertX
(
next
.
getX
()),
conversion
.
convertY
(
next
.
getY
())));
}
return
points
;
}
private
CoordinateConversion
getCoordinateConversion
(
GMLMap
map
)
{
return
new
ScaleConversion
(
map
.
getMinX
(),
map
.
getMinY
(),
1000
,
1000
);
}
public
GisScenario
getScenario
(
Config
config
)
throws
DocumentException
{
if
(
scenario
==
null
)
{
File
dir
=
new
File
(
config
.
getValue
(
MAP_DIRECTORY_KEY
));
File
scenarioFile
=
new
File
(
dir
,
config
.
getValue
(
SCENARIO_FILE_KEY
,
DEFAULT_SCENARIO_FILE
));
try
{
readScenario
(
scenarioFile
,
config
);
}
catch
(
ScenarioException
e
)
{
e
.
printStackTrace
();
}
}
return
scenario
;
}
}
\ No newline at end of file
modules/gis2/src/gis2/GisScenario.java
0 → 100755
View file @
342fea6f
This diff is collapsed.
Click to expand it.
modules/gis2/src/gis2/ScenarioException.java
0 → 100644
View file @
342fea6f
package
gis2
;
/**
* Exception class for problems with scenarios.
*/
public
class
ScenarioException
extends
Exception
{
/**
* Construct a scenario exception with no information.
*/
public
ScenarioException
()
{
super
();
}
/**
* Construct a scenario exception with an error message.
*
* @param msg The error message.
*/
public
ScenarioException
(
String
msg
)
{
super
(
msg
);
}
/**
* Construct a scenario exception that was caused by another exception.
*
* @param cause The cause of this exception.
*/
public
ScenarioException
(
Throwable
cause
)
{
super
(
cause
);
}
/**
* Construct a scenario exception with an error message and an underlying cause.
*
* @param msg The error message.
* @param cause The cause of this exception.
*/
public
ScenarioException
(
String
msg
,
Throwable
cause
)
{
super
(
msg
,
cause
);
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/AbstractFunction.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
/**
* Abstract base class for scenario editing functions.
*/
public
abstract
class
AbstractFunction
implements
Function
{
/** The editor instance. */
protected
ScenarioEditor
editor
;
/**
* Construct an AbstractFunction.
*
* @param editor The editor instance.
*/
protected
AbstractFunction
(
ScenarioEditor
editor
)
{
this
.
editor
=
editor
;
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/AbstractTool.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
/**
* Abstract base class for scenario editing tools.
*/
public
abstract
class
AbstractTool
implements
Tool
{
/** The scenario editor instance. */
protected
ScenarioEditor
editor
;
/**
* Construct an AbstractTool.
*
* @param editor The scenario editor instance.
*/
protected
AbstractTool
(
ScenarioEditor
editor
)
{
this
.
editor
=
editor
;
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/AgentOverlay.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
java.awt.Color
;
import
java.awt.Font
;
import
java.awt.Graphics2D
;
import
java.awt.Shape
;
import
java.awt.geom.Ellipse2D
;
import
java.util.Map
;
import
maps.gml.GMLShape
;
import
maps.gml.view.Overlay
;
import
rescuecore2.misc.collections.LazyMap
;
import
rescuecore2.misc.gui.ScreenTransform
;
/**
* Overlay for viewing agents in a scenario.
*/
public
class
AgentOverlay
implements
Overlay
{
private
static
final
int
SIZE
=
11
;
private
static
final
Color
CIVILIAN_COLOUR
=
Color
.
GREEN
;
private
static
final
Color
FIRE_BRIGADE_COLOUR
=
Color
.
RED
;
private
static
final
Color
POLICE_FORCE_COLOUR
=
Color
.
BLUE
;
private
static
final
Color
AMBULANCE_TEAM_COLOUR
=
Color
.
WHITE
;
private
static
final
int
OFFSET
=
7
;
private
ScenarioEditor
editor
;
/**
* Construct an AgentOverlay.
*
* @param editor The scenario editor.
*/
public
AgentOverlay
(
ScenarioEditor
editor
)
{
this
.
editor
=
editor
;
}
@Override
public
void
render
(
Graphics2D
g
,
ScreenTransform
transform
)
{
// Count agents in each location
g
.
setFont
(
new
Font
(
g
.
getFont
().
getName
(),
Font
.
BOLD
,
g
.
getFont
().
getSize
()));
Map
<
Integer
,
Integer
>
civs
=
new
LazyMap
<
Integer
,
Integer
>()
{
@Override
public
Integer
createValue
()
{
return
0
;
}
};
Map
<
Integer
,
Integer
>
fbs
=
new
LazyMap
<
Integer
,
Integer
>()
{
@Override
public
Integer
createValue
()
{
return
0
;
}
};
Map
<
Integer
,
Integer
>
pfs
=
new
LazyMap
<
Integer
,
Integer
>()
{
@Override
public
Integer
createValue
()
{
return
0
;
}
};
Map
<
Integer
,
Integer
>
ats
=
new
LazyMap
<
Integer
,
Integer
>()
{
@Override
public
Integer
createValue
()
{
return
0
;
}
};
for
(
int
next
:
editor
.
getScenario
().
getCivilians
())
{
civs
.
put
(
next
,
civs
.
get
(
next
)
+
1
);
}
for
(
int
next
:
editor
.
getScenario
().
getFireBrigades
())
{
fbs
.
put
(
next
,
fbs
.
get
(
next
)
+
1
);
}
for
(
int
next
:
editor
.
getScenario
().
getPoliceForces
())
{
pfs
.
put
(
next
,
pfs
.
get
(
next
)
+
1
);
}
for
(
int
next
:
editor
.
getScenario
().
getAmbulanceTeams
())
{
ats
.
put
(
next
,
ats
.
get
(
next
)
+
1
);
}
// Now draw them
for
(
Map
.
Entry
<
Integer
,
Integer
>
next
:
civs
.
entrySet
())
{
GMLShape
shape
=
editor
.
getMap
().
getShape
(
next
.
getKey
());
int
count
=
next
.
getValue
();
// int x = transform.xToScreen(shape.getCentreX());
// int y = transform.yToScreen(shape.getCentreY()) + CIV_OFFSET;
int
x
=
transform
.
xToScreen
(
shape
.
getCentreX
())
+
OFFSET
;
int
y
=
transform
.
yToScreen
(
shape
.
getCentreY
());
// g.drawString(count + " civs", x, y);
paint
(
g
,
x
,
y
,
CIVILIAN_COLOUR
);
g
.
drawString
(
count
+
""
,
x
,
y
);
}
for
(
Map
.
Entry
<
Integer
,
Integer
>
next
:
fbs
.
entrySet
())
{
GMLShape
shape
=
editor
.
getMap
().
getShape
(
next
.
getKey
());
int
count
=
next
.
getValue
();
// int x = transform.xToScreen(shape.getCentreX());
// int y = transform.yToScreen(shape.getCentreY()) + FB_OFFSET;
int
x
=
transform
.
xToScreen
(
shape
.
getCentreX
());
int
y
=
transform
.
yToScreen
(
shape
.
getCentreY
())
-
OFFSET
;
// g.drawString(count + " fbs", x, y);
paint
(
g
,
x
,
y
,
FIRE_BRIGADE_COLOUR
);
g
.
drawString
(
count
+
""
,
x
,
y
);
}
for
(
Map
.
Entry
<
Integer
,
Integer
>
next
:
pfs
.
entrySet
())
{
GMLShape
shape
=
editor
.
getMap
().
getShape
(
next
.
getKey
());
int
count
=
next
.
getValue
();
// int x = transform.xToScreen(shape.getCentreX());
// int y = transform.yToScreen(shape.getCentreY()) + PF_OFFSET;
int
x
=
transform
.
xToScreen
(
shape
.
getCentreX
());
int
y
=
transform
.
yToScreen
(
shape
.
getCentreY
())
+
OFFSET
;
// g.drawString(count + " pfs", x, y);
paint
(
g
,
x
,
y
,
POLICE_FORCE_COLOUR
);
g
.
drawString
(
count
+
""
,
x
,
y
);
}
for
(
Map
.
Entry
<
Integer
,
Integer
>
next
:
ats
.
entrySet
())
{
GMLShape
shape
=
editor
.
getMap
().
getShape
(
next
.
getKey
());
int
count
=
next
.
getValue
();
// int x = transform.xToScreen(shape.getCentreX());
// int y = transform.yToScreen(shape.getCentreY()) + AT_OFFSET;
int
x
=
transform
.
xToScreen
(
shape
.
getCentreX
())
-
OFFSET
;
int
y
=
transform
.
yToScreen
(
shape
.
getCentreY
());
// g.drawString(count + " ats", x, y);
paint
(
g
,
x
,
y
,
AMBULANCE_TEAM_COLOUR
);
g
.
drawString
(
count
+
""
,
x
,
y
);
}
}
public
void
paint
(
Graphics2D
g
,
int
x
,
int
y
,
Color
color
)
{
Shape
shape
=
new
Ellipse2D
.
Double
(
x
-
SIZE
/
4
,
y
-
SIZE
,
SIZE
,
SIZE
);
g
.
setColor
(
color
);
g
.
fill
(
shape
);
g
.
draw
(
shape
);
g
.
setColor
(
Color
.
black
);
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/CancelledByUserException.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
/**
* Exception for indicating the the user has cancelled an operation.
*/
public
class
CancelledByUserException
extends
Exception
{
/**
* Constructor.
*/
public
CancelledByUserException
()
{
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/ClearAgentsFunction.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
gis2.GisScenario
;
import
java.util.HashSet
;
/**
* Function for removing all agents.
*/
public
class
ClearAgentsFunction
extends
AbstractFunction
{
/**
* Construct a clear agents function.
*
* @param editor The editor instance.
*/
public
ClearAgentsFunction
(
ScenarioEditor
editor
)
{
super
(
editor
);
}
@Override
public
String
getName
()
{
return
"Remove agents"
;
}
@Override
public
void
execute
()
{
GisScenario
s
=
editor
.
getScenario
();
s
.
setFireBrigades
(
new
HashSet
<
Integer
>());
s
.
setFireStations
(
new
HashSet
<
Integer
>());
s
.
setPoliceForces
(
new
HashSet
<
Integer
>());
s
.
setPoliceOffices
(
new
HashSet
<
Integer
>());
s
.
setAmbulanceTeams
(
new
HashSet
<
Integer
>());
s
.
setAmbulanceCentres
(
new
HashSet
<
Integer
>());
editor
.
setChanged
();
editor
.
updateOverlays
();
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/ClearAllFunction.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
gis2.GisScenario
;
import
java.util.HashSet
;
/**
* Function for removing all agents, fires, civilians and refuges.
*/
public
class
ClearAllFunction
extends
AbstractFunction
{
/**
* Construct a clear all function.
*
* @param editor The editor instance.
*/
public
ClearAllFunction
(
ScenarioEditor
editor
)
{
super
(
editor
);
}
@Override
public
String
getName
()
{
return
"Remove all"
;
}
@Override
public
void
execute
()
{
GisScenario
s
=
editor
.
getScenario
();
s
.
setFireBrigades
(
new
HashSet
<
Integer
>());
s
.
setFireStations
(
new
HashSet
<
Integer
>());
s
.
setPoliceForces
(
new
HashSet
<
Integer
>());
s
.
setPoliceOffices
(
new
HashSet
<
Integer
>());
s
.
setAmbulanceTeams
(
new
HashSet
<
Integer
>());
s
.
setAmbulanceCentres
(
new
HashSet
<
Integer
>());
s
.
setCivilians
(
new
HashSet
<
Integer
>());
s
.
setFires
(
new
HashSet
<
Integer
>());
s
.
setRefuges
(
new
HashSet
<
Integer
>());
s
.
setGasStations
(
new
HashSet
<
Integer
>());
s
.
setHydrants
(
new
HashSet
<
Integer
>());
editor
.
setChanged
();
editor
.
updateOverlays
();
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/ClearFiresFunction.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
gis2.GisScenario
;
import
java.util.HashSet
;
/**
* Function for removing all fires.
*/
public
class
ClearFiresFunction
extends
AbstractFunction
{
/**
* Construct a clear fires function.
*
* @param editor The editor instance.
*/
public
ClearFiresFunction
(
ScenarioEditor
editor
)
{
super
(
editor
);
}
@Override
public
String
getName
()
{
return
"Remove fires"
;
}
@Override
public
void
execute
()
{
GisScenario
s
=
editor
.
getScenario
();
s
.
setFires
(
new
HashSet
<
Integer
>());
editor
.
setChanged
();
editor
.
updateOverlays
();
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/Function.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
/**
* Interface for a scenario editing function.
*/
public
interface
Function
{
/**
* Get the name of this function.
*
* @return The name of the function.
*/
String
getName
();
/**
* Execute this function.
*/
void
execute
();
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/ModifiedFlowLayout.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
java.awt.Component
;
import
java.awt.Container
;
import
java.awt.Dimension
;
import
java.awt.FlowLayout
;
import
java.awt.Insets
;
/**
* A modified version of FlowLayout that allows containers using this Layout to
* behave in a reasonable manner when placed inside a JScrollPane
*
* @author Babu Kalakrishnan Modifications by greearb and jzd
*/
public
class
ModifiedFlowLayout
extends
FlowLayout
{
public
ModifiedFlowLayout
()
{
super
(
FlowLayout
.
LEFT
);
}
public
ModifiedFlowLayout
(
int
align
)
{
super
(
align
);
}
public
ModifiedFlowLayout
(
int
align
,
int
hgap
,
int
vgap
)
{
super
(
align
,
hgap
,
vgap
);
}
public
Dimension
minimumLayoutSize
(
Container
target
)
{
// Size of largest component, so we can resize it in
// either direction with something like a split-pane.
return
computeMinSize
(
target
);
}
public
Dimension
preferredLayoutSize
(
Container
target
)
{
return
computeSize
(
target
);
}
private
Dimension
computeSize
(
Container
target
)
{
synchronized
(
target
.
getTreeLock
())
{
int
hgap
=
getHgap
();
int
vgap
=
getVgap
();
int
w
=
target
.
getWidth
();
// Let this behave like a regular FlowLayout (single row)
// if the container hasn't been assigned any size yet
if
(
w
==
0
)
{
w
=
Integer
.
MAX_VALUE
;
}
Insets
insets
=
target
.
getInsets
();
if
(
insets
==
null
)
{
insets
=
new
Insets
(
0
,
0
,
0
,
0
);
}
int
reqdWidth
=
0
;
int
maxwidth
=
w
-
(
insets
.
left
+
insets
.
right
+
hgap
*
2
);
int
n
=
target
.
getComponentCount
();
int
x
=
0
;
int
y
=
insets
.
top
+
vgap
;
// FlowLayout starts by adding vgap, so
// do that here too.
int
rowHeight
=
0
;
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
Component
c
=
target
.
getComponent
(
i
);
if
(
c
.
isVisible
())
{
Dimension
d
=
c
.
getPreferredSize
();
if
((
x
==
0
)
||
((
x
+
d
.
width
)
<=
maxwidth
))
{
// fits in current row.
if
(
x
>
0
)
{
x
+=
hgap
;
}
x
+=
d
.
width
;
rowHeight
=
Math
.
max
(
rowHeight
,
d
.
height
);
}
else
{
// Start of new row
x
=
d
.
width
;
y
+=
vgap
+
rowHeight
;
rowHeight
=
d
.
height
;
}
reqdWidth
=
Math
.
max
(
reqdWidth
,
x
);
}
}
y
+=
rowHeight
;
y
+=
insets
.
bottom
;
return
new
Dimension
(
reqdWidth
+
insets
.
left
+
insets
.
right
,
y
);
}
}
private
Dimension
computeMinSize
(
Container
target
)
{
synchronized
(
target
.
getTreeLock
())
{
int
minx
=
Integer
.
MAX_VALUE
;
int
miny
=
Integer
.
MIN_VALUE
;
boolean
found_one
=
false
;
int
n
=
target
.
getComponentCount
();
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
Component
c
=
target
.
getComponent
(
i
);
if
(
c
.
isVisible
())
{
found_one
=
true
;
Dimension
d
=
c
.
getPreferredSize
();
minx
=
Math
.
min
(
minx
,
d
.
width
);
miny
=
Math
.
min
(
miny
,
d
.
height
);
}
}
if
(
found_one
)
{
return
new
Dimension
(
minx
,
miny
);
}
return
new
Dimension
(
0
,
0
);
}
}
}
\ No newline at end of file
modules/gis2/src/gis2/scenario/PlaceAgentsFunction.java
0 → 100644
View file @
342fea6f
package
gis2.scenario
;
import
gis2.GisScenario
;
import
java.awt.GridLayout
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Random
;
import
javax.swing.JCheckBox
;
import
javax.swing.JComboBox
;
import
javax.swing.JLabel
;
import
javax.swing.JOptionPane
;
import
javax.swing.JPanel
;
import
javax.swing.JTextField
;
import
maps.gml.GMLShape
;
/**
* Function for placing agents.
*/
public
class
PlaceAgentsFunction
extends
AbstractFunction
{
private
static
final
int
TYPE_FIRE
=
0
;
private
static
final
int
TYPE_POLICE
=
1
;
private
static
final
int
TYPE_AMBULANCE
=
2
;
private
static
final
int
TYPE_CIVILIAN
=
3
;
private
Random
random
;
/**
* Construct a place agents function.
*
* @param editor The editor instance.
*/
public
PlaceAgentsFunction
(
ScenarioEditor
editor
)
{
super
(
editor
);
random
=
new
Random
();
}
@Override
public
String
getName
()
{
return
"Place agents"
;
}
@Override
public
void
execute
()
{
JPanel
panel
=
new
JPanel
(
new
GridLayout
(
3
,
2
));
JTextField
numberField
=
new
JTextField
(
"1"
);
JComboBox
<
String
>
typeCombo
=
new
JComboBox
<
String
>(
new
String
[]
{
"Fire"
,
"Police"
,
"Ambulance"
,
"Civilian"
});
JCheckBox
buildingBox
=
new
JCheckBox
(
"In buildings?"
,
false
);
JCheckBox
roadBox
=
new
JCheckBox
(
"In Roads?"
,
true
);
JPanel
jp
=
new
JPanel
();
jp
.
add
(
buildingBox
);
jp
.
add
(
roadBox
);
panel
.
add
(
new
JLabel
(
"Type"
));
panel
.
add
(
typeCombo
);
panel
.
add
(
new
JLabel
(
"Number"
));
panel
.
add
(
numberField
);
panel
.
add
(
jp
);
List
<
Integer
>
ids
=
new
ArrayList
<
Integer
>();
int
type
=
-
1
;
List
<
GMLShape
>
all
=
new
ArrayList
<
GMLShape
>();
if
(
JOptionPane
.
showConfirmDialog
(
null
,
panel
,
"Add agents"
,
JOptionPane
.
OK_CANCEL_OPTION
)
==
JOptionPane
.
OK_OPTION
)
{
try
{
int
number
=
Integer
.
parseInt
(
numberField
.
getText
());
type
=
typeCombo
.
getSelectedIndex
();
if
(
roadBox
.
isSelected
())
all
.
addAll
(
editor
.
getMap
().
getRoads
());
if
(
buildingBox
.
isSelected
())
all
.
addAll
(
editor
.
getMap
().
getBuildings
());
if
(
all
.
size
()
==
0
)
{
JOptionPane
.
showMessageDialog
(
null
,
"No Area to Place... Please choose In Road or Building..."
,
"Error"
,
JOptionPane
.
ERROR_MESSAGE
);
return
;
}
for
(
int
i
=
0
;
i
<
number
;
++
i
)
{
ids
.
add
(
all
.
get
(
random
.
nextInt
(
all
.
size
())).
getID
());
}
}
catch
(
NumberFormatException
e
)
{
e
.
printStackTrace
();
}
}
GisScenario
s
=
editor
.
getScenario
();
switch
(
type
)
{
case
TYPE_FIRE:
for
(
int
id
:
ids
)
{
s
.
addFireBrigade
(
id
);
}
break
;
case
TYPE_POLICE:
for
(
int
id
:
ids
)
{
s
.
addPoliceForce
(
id
);
}
break
;
case
TYPE_AMBULANCE:
for
(
int
id
:
ids
)
{
s
.
addAmbulanceTeam
(
id
);
}
break
;
case
TYPE_CIVILIAN:
for
(
int
id
:
ids
)
{
s
.
addCivilian
(
id
);
}
break
;
default
:
throw
new
IllegalArgumentException
(
"Unexpected type: "
+
type
);
}
editor
.
setChanged
();
editor
.
updateOverlays
();
}
}
\ No newline at end of file
Prev
1
2
3
4
5
…
47
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment