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
419
Show whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 419+
files are displayed.
Plain diff
Email patch
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
package
collapse
;
import
rescuecore2.config.Config
;
import
rescuecore2.messages.Message
;
import
rescuecore2.messages.control.KSAfterShocksInfo
;
import
rescuecore2.messages.control.KSCommands
;
import
rescuecore2.worldmodel.ChangeSet
;
import
rescuecore2.worldmodel.EntityID
;
import
rescuecore2.worldmodel.WorldModelListener
;
import
rescuecore2.worldmodel.WorldModel
;
import
rescuecore2.misc.geometry.Point2D
;
import
rescuecore2.misc.geometry.Line2D
;
import
rescuecore2.misc.geometry.Vector2D
;
import
rescuecore2.misc.geometry.GeometryTools2D
;
import
rescuecore2.misc.collections.LazyMap
;
import
rescuecore2.log.Logger
;
import
rescuecore2.GUIComponent
;
import
rescuecore2.standard.components.StandardSimulator
;
import
rescuecore2.standard.entities.StandardEntity
;
import
rescuecore2.standard.entities.StandardEntityURN
;
import
rescuecore2.standard.entities.StandardEntityConstants
;
import
rescuecore2.standard.entities.Building
;
import
rescuecore2.standard.entities.Road
;
import
rescuecore2.standard.entities.Edge
;
import
rescuecore2.standard.entities.Blockade
;
import
rescuecore2.standard.entities.StandardWorldModel
;
import
org.uncommons.maths.random.GaussianGenerator
;
import
org.uncommons.maths.random.ContinuousUniformGenerator
;
import
org.uncommons.maths.number.NumberGenerator
;
import
org.uncommons.maths.Maths
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.EnumMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.awt.geom.Path2D
;
import
java.awt.geom.Ellipse2D
;
import
java.awt.geom.PathIterator
;
import
javax.swing.JComponent
;
/**
* A simple collapse simulator.
*/
public
class
CollapseSimulator
extends
StandardSimulator
implements
GUIComponent
{
private
static
final
String
CONFIG_PREFIX
=
"collapse."
;
private
static
final
String
DESTROYED_SUFFIX
=
".p-destroyed"
;
private
static
final
String
SEVERE_SUFFIX
=
".p-severe"
;
private
static
final
String
MODERATE_SUFFIX
=
".p-moderate"
;
private
static
final
String
SLIGHT_SUFFIX
=
".p-slight"
;
private
static
final
String
NONE_SUFFIX
=
".p-none"
;
private
static
final
String
DESTROYED_MEAN_SUFFIX
=
"destroyed.mean"
;
private
static
final
String
DESTROYED_SD_SUFFIX
=
"destroyed.sd"
;
private
static
final
String
SEVERE_MEAN_SUFFIX
=
"severe.mean"
;
private
static
final
String
SEVERE_SD_SUFFIX
=
"severe.sd"
;
private
static
final
String
MODERATE_MEAN_SUFFIX
=
"moderate.mean"
;
private
static
final
String
MODERATE_SD_SUFFIX
=
"moderate.sd"
;
private
static
final
String
SLIGHT_MEAN_SUFFIX
=
"slight.mean"
;
private
static
final
String
SLIGHT_SD_SUFFIX
=
"slight.sd"
;
private
static
final
String
BLOCK_KEY
=
"collapse.create-road-blockages"
;
private
static
final
String
FLOOR_HEIGHT_KEY
=
"collapse.floor-height"
;
private
static
final
String
WALL_COLLAPSE_EXTENT_MIN_KEY
=
"collapse.wall-extent.min"
;
private
static
final
String
WALL_COLLAPSE_EXTENT_MAX_KEY
=
"collapse.wall-extent.max"
;
/* Aftershock Requirment 2013 */
private
static
final
String
RANDOM_AFTERSHOCK
=
"collapse.aftershock.random"
;
/* Aftershock Requirment 2013 */
// enum IntensityType {
// ON_DAMAGE, ON_DISTANCE;
// public String toString() {
// if (this.equals(ON_DAMAGE))
// return "damage";
// else
// return "distance";
// };
//
// }
enum
CollapsePolicy
{
MERGE_BLOCKADES
,
DONT_MERGE_BLOCKADES
;
public
String
toString
()
{
if
(
this
.
equals
(
MERGE_BLOCKADES
))
return
"merge"
;
else
return
"dont_merge"
;
};
}
CollapsePolicy
policy
=
CollapsePolicy
.
DONT_MERGE_BLOCKADES
;
private
static
final
int
MAX_COLLAPSE
=
100
;
private
static
final
double
REPAIR_COST_FACTOR
=
0.000001
;
// Converts
// square mm to
// square m.
public
static
final
String
NAME
=
"Collapse Simulator v1.1"
;
private
static
final
List
<
EntityID
>
EMPTY_ID_LIST
=
new
ArrayList
<
EntityID
>(
0
);
private
NumberGenerator
<
Double
>
destroyed
;
private
NumberGenerator
<
Double
>
severe
;
private
NumberGenerator
<
Double
>
moderate
;
private
NumberGenerator
<
Double
>
slight
;
private
boolean
block
;
private
double
floorHeight
;
private
NumberGenerator
<
Double
>
extent
;
private
Map
<
StandardEntityConstants
.
BuildingCode
,
CollapseStats
>
stats
;
private
CollapseSimulatorGUI
gui
;
private
Collection
<
Building
>
buildingCache
;
private
Collection
<
Road
>
roadCache
;
public
CollapseSimulator
()
{
}
/**
* This method instantiate a CollapseWorldModel instance.
*/
@Override
protected
StandardWorldModel
createWorldModel
()
{
return
new
CollapseWorldModel
();
/* Aftershocks Requirement:2013 */
}
@Override
public
JComponent
getGUIComponent
()
{
if
(
gui
==
null
)
{
gui
=
new
CollapseSimulatorGUI
();
}
return
gui
;
}
@Override
public
String
getGUIComponentName
()
{
return
"Collapse simulator"
;
}
@Override
public
String
getName
()
{
return
NAME
;
}
@Override
protected
void
postConnect
()
{
super
.
postConnect
();
stats
=
new
EnumMap
<
StandardEntityConstants
.
BuildingCode
,
CollapseStats
>(
StandardEntityConstants
.
BuildingCode
.
class
);
for
(
StandardEntityConstants
.
BuildingCode
code
:
StandardEntityConstants
.
BuildingCode
.
values
())
{
stats
.
put
(
code
,
new
CollapseStats
(
code
,
config
));
}
slight
=
new
GaussianGenerator
(
config
.
getFloatValue
(
CONFIG_PREFIX
+
SLIGHT_MEAN_SUFFIX
),
config
.
getFloatValue
(
CONFIG_PREFIX
+
SLIGHT_SD_SUFFIX
),
config
.
getRandom
());
moderate
=
new
GaussianGenerator
(
config
.
getFloatValue
(
CONFIG_PREFIX
+
MODERATE_MEAN_SUFFIX
),
config
.
getFloatValue
(
CONFIG_PREFIX
+
MODERATE_SD_SUFFIX
),
config
.
getRandom
());
severe
=
new
GaussianGenerator
(
config
.
getFloatValue
(
CONFIG_PREFIX
+
SEVERE_MEAN_SUFFIX
),
config
.
getFloatValue
(
CONFIG_PREFIX
+
SEVERE_SD_SUFFIX
),
config
.
getRandom
());
destroyed
=
new
GaussianGenerator
(
config
.
getFloatValue
(
CONFIG_PREFIX
+
DESTROYED_MEAN_SUFFIX
),
config
.
getFloatValue
(
CONFIG_PREFIX
+
DESTROYED_SD_SUFFIX
),
config
.
getRandom
());
block
=
config
.
getBooleanValue
(
BLOCK_KEY
);
floorHeight
=
config
.
getFloatValue
(
FLOOR_HEIGHT_KEY
)
*
1000
;
extent
=
new
ContinuousUniformGenerator
(
config
.
getFloatValue
(
WALL_COLLAPSE_EXTENT_MIN_KEY
),
config
.
getFloatValue
(
WALL_COLLAPSE_EXTENT_MAX_KEY
),
config
.
getRandom
());
buildingCache
=
new
HashSet
<
Building
>();
roadCache
=
new
HashSet
<
Road
>();
for
(
StandardEntity
next
:
model
)
{
if
(
next
instanceof
Building
)
{
buildingCache
.
add
((
Building
)
next
);
}
if
(
next
instanceof
Road
)
{
roadCache
.
add
((
Road
)
next
);
}
}
model
.
addWorldModelListener
(
new
WorldModelListener
<
StandardEntity
>()
{
@Override
public
void
entityAdded
(
WorldModel
<?
extends
StandardEntity
>
model
,
StandardEntity
e
)
{
if
(
e
instanceof
Building
)
{
buildingCache
.
add
((
Building
)
e
);
}
if
(
e
instanceof
Road
)
{
roadCache
.
add
((
Road
)
e
);
}
}
@Override
public
void
entityRemoved
(
WorldModel
<?
extends
StandardEntity
>
model
,
StandardEntity
e
)
{
if
(
e
instanceof
Building
)
{
buildingCache
.
remove
((
Building
)
e
);
}
if
(
e
instanceof
Road
)
{
roadCache
.
remove
((
Road
)
e
);
}
}
});
}
@Override
protected
void
processCommands
(
KSCommands
c
,
ChangeSet
changes
)
{
long
start
=
System
.
currentTimeMillis
();
int
time
=
c
.
getTime
();
Logger
.
info
(
"Timestep "
+
time
);
if
(
gui
!=
null
)
{
gui
.
timestep
(
time
);
}
Collection
<
Building
>
collapsed
=
doCollapse
(
changes
,
time
);
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
newBlock
=
doBlock
(
collapsed
,
time
);
// Create blockade objects
Map
<
Road
,
Collection
<
Blockade
>>
blockades
=
createBlockadeObjects
(
newBlock
);
for
(
Map
.
Entry
<
Road
,
Collection
<
Blockade
>>
entry
:
blockades
.
entrySet
())
{
Road
r
=
entry
.
getKey
();
List
<
EntityID
>
existing
=
r
.
getBlockades
();
List
<
EntityID
>
ids
=
new
ArrayList
<
EntityID
>();
if
(
existing
!=
null
)
{
ids
.
addAll
(
existing
);
}
for
(
Blockade
b
:
entry
.
getValue
())
{
ids
.
add
(
b
.
getID
());
}
r
.
setBlockades
(
ids
);
changes
.
addAll
(
entry
.
getValue
());
changes
.
addChange
(
r
,
r
.
getBlockadesProperty
());
}
// If any roads have undefined blockades then set the blockades property
// to the empty list
for
(
Road
next
:
roadCache
)
{
if
(!
next
.
isBlockadesDefined
())
{
next
.
setBlockades
(
EMPTY_ID_LIST
);
changes
.
addChange
(
next
,
next
.
getBlockadesProperty
());
}
}
long
end
=
System
.
currentTimeMillis
();
Logger
.
info
(
"Timestep "
+
time
+
" took "
+
(
end
-
start
)
+
" ms"
);
}
private
Collection
<
Building
>
doCollapse
(
ChangeSet
changes
,
int
time
)
{
Collection
<
Building
>
result
=
new
HashSet
<
Building
>();
if
(
gui
!=
null
)
{
gui
.
startCollapse
(
buildingCache
.
size
());
}
if
(
time
==
1
)
{
result
.
addAll
(
doEarthquakeCollapse
(
changes
));
}
/* Aftershocks Requirement:2013 */
if
(
time
!=
1
&&
model
().
aftershockHappens
(
time
))
{
result
.
addAll
(
doEarthquakeCollapse
(
changes
));
}
if
(
gui
!=
null
)
{
gui
.
endCollapse
();
}
if
(
gui
!=
null
)
{
gui
.
startFire
(
buildingCache
.
size
());
}
// result.addAll(doFireCollapse(changes));
if
(
gui
!=
null
)
{
gui
.
endFire
();
}
return
result
;
}
static
long
t1
;
static
long
t2
;
static
long
t3
;
private
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
doBlock
(
Collection
<
Building
>
collapsed
,
int
time
)
{
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
result
=
new
LazyMap
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>()
{
@Override
public
Collection
<
java
.
awt
.
geom
.
Area
>
createValue
()
{
return
new
ArrayList
<
java
.
awt
.
geom
.
Area
>();
}
};
if
(!
block
)
{
return
result
;
}
if
(
gui
!=
null
)
{
gui
.
startBlock
(
collapsed
.
size
());
}
for
(
Building
b
:
collapsed
)
{
createBlockages
(
b
,
result
,
time
);
if
(
gui
!=
null
)
{
gui
.
bumpBlock
();
}
}
if
(
gui
!=
null
)
{
gui
.
endBlock
();
}
return
result
;
}
private
Collection
<
Building
>
doEarthquakeCollapse
(
ChangeSet
changes
)
{
Map
<
StandardEntityConstants
.
BuildingCode
,
Map
<
CollapseDegree
,
Integer
>>
count
=
new
EnumMap
<
StandardEntityConstants
.
BuildingCode
,
Map
<
CollapseDegree
,
Integer
>>(
StandardEntityConstants
.
BuildingCode
.
class
);
Map
<
StandardEntityConstants
.
BuildingCode
,
Integer
>
total
=
new
EnumMap
<
StandardEntityConstants
.
BuildingCode
,
Integer
>(
StandardEntityConstants
.
BuildingCode
.
class
);
for
(
StandardEntityConstants
.
BuildingCode
code
:
StandardEntityConstants
.
BuildingCode
.
values
())
{
Map
<
CollapseDegree
,
Integer
>
next
=
new
EnumMap
<
CollapseDegree
,
Integer
>(
CollapseDegree
.
class
);
for
(
CollapseDegree
cd
:
CollapseDegree
.
values
())
{
next
.
put
(
cd
,
0
);
}
count
.
put
(
code
,
next
);
total
.
put
(
code
,
0
);
}
Logger
.
debug
(
"Collapsing buildings"
);
Collection
<
Building
>
result
=
new
HashSet
<
Building
>();
for
(
Building
b
:
buildingCache
)
{
StandardEntityConstants
.
BuildingCode
code
=
b
.
getBuildingCodeEnum
();
int
damage
=
code
==
null
?
0
:
stats
.
get
(
code
).
damage
();
damage
=
Maths
.
restrictRange
(
damage
,
0
,
MAX_COLLAPSE
);
int
lastDamage
=
b
.
getBrokenness
();
/*
* Aftershock Requirement 2013: this ignores the new damage of it is
* less than the previous
*/
if
(
damage
<
lastDamage
)
{
damage
=
lastDamage
;
}
/* Aftershock Requirement 2013 */
b
.
setBrokenness
(
damage
);
changes
.
addChange
(
b
,
b
.
getBrokennessProperty
());
CollapseDegree
degree
=
CollapseDegree
.
get
(
damage
);
count
.
get
(
code
).
put
(
degree
,
count
.
get
(
code
).
get
(
degree
)
+
1
);
total
.
put
(
code
,
total
.
get
(
code
)
+
1
);
if
(
damage
>
0
)
{
result
.
add
(
b
);
}
if
(
gui
!=
null
)
{
gui
.
bumpCollapse
();
}
}
Logger
.
info
(
"Finished collapsing buildings: "
);
for
(
StandardEntityConstants
.
BuildingCode
code
:
StandardEntityConstants
.
BuildingCode
.
values
())
{
Logger
.
info
(
"Building code "
+
code
+
": "
+
total
.
get
(
code
)
+
" buildings"
);
Map
<
CollapseDegree
,
Integer
>
data
=
count
.
get
(
code
);
for
(
Map
.
Entry
<
CollapseDegree
,
Integer
>
entry
:
data
.
entrySet
())
{
Logger
.
info
(
" "
+
entry
.
getValue
()
+
" "
+
entry
.
getKey
().
toString
().
toLowerCase
());
}
}
return
result
;
}
private
Collection
<
Building
>
doFireCollapse
(
ChangeSet
changes
)
{
Logger
.
debug
(
"Checking fire damage"
);
Collection
<
Building
>
result
=
new
HashSet
<
Building
>();
for
(
Building
b
:
buildingCache
)
{
/*
* Aftershock Requirement @ 2103: it is used in doBlock to check
* whether apply the aftershock intensity or not
*/
model
().
getCSBuiding
(
b
).
setHasFireDamage
(
false
);
if
(!
b
.
isFierynessDefined
())
{
if
(
gui
!=
null
)
{
gui
.
bumpFire
();
}
continue
;
}
int
minDamage
=
0
;
switch
(
b
.
getFierynessEnum
())
{
case
HEATING:
minDamage
=
slight
.
nextValue
().
intValue
();
break
;
case
BURNING:
minDamage
=
moderate
.
nextValue
().
intValue
();
break
;
case
INFERNO:
minDamage
=
severe
.
nextValue
().
intValue
();
break
;
case
BURNT_OUT:
minDamage
=
destroyed
.
nextValue
().
intValue
();
break
;
default
:
break
;
}
/* Aftershock Requirement @ 2103 */
if
(
minDamage
!=
0
)
{
// indicates that the building has fire damage
model
().
getCSBuiding
(
b
).
setHasFireDamage
(
true
);
}
minDamage
=
Maths
.
restrictRange
(
minDamage
,
0
,
MAX_COLLAPSE
);
int
damage
=
b
.
isBrokennessDefined
()
?
b
.
getBrokenness
()
:
0
;
if
(
damage
<
minDamage
)
{
Logger
.
info
(
b
+
" damaged by fire. New brokenness: "
+
minDamage
);
b
.
setBrokenness
(
minDamage
);
changes
.
addChange
(
b
,
b
.
getBrokennessProperty
());
result
.
add
(
b
);
}
if
(
gui
!=
null
)
{
gui
.
bumpFire
();
}
}
Logger
.
debug
(
"Finished checking fire damage"
);
return
result
;
}
private
Map
<
Road
,
Collection
<
Blockade
>>
createBlockadeObjects
(
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
blocks
)
{
Map
<
Road
,
Collection
<
Blockade
>>
result
=
new
LazyMap
<
Road
,
Collection
<
Blockade
>>()
{
@Override
public
Collection
<
Blockade
>
createValue
()
{
return
new
ArrayList
<
Blockade
>();
}
};
int
count
=
0
;
for
(
Collection
<
java
.
awt
.
geom
.
Area
>
c
:
blocks
.
values
())
{
count
+=
c
.
size
();
}
try
{
if
(
count
!=
0
)
{
List
<
EntityID
>
newIDs
=
requestNewEntityIDs
(
count
);
Iterator
<
EntityID
>
it
=
newIDs
.
iterator
();
Logger
.
debug
(
"Creating new blockade objects"
);
for
(
Map
.
Entry
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
entry
:
blocks
.
entrySet
())
{
Road
r
=
entry
.
getKey
();
for
(
java
.
awt
.
geom
.
Area
area
:
entry
.
getValue
())
{
EntityID
id
=
it
.
next
();
Blockade
blockade
=
makeBlockade
(
id
,
area
,
r
.
getID
());
if
(
blockade
!=
null
)
{
result
.
get
(
r
).
add
(
blockade
);
}
}
}
}
}
catch
(
InterruptedException
e
)
{
Logger
.
error
(
"Interrupted while requesting IDs"
);
}
return
result
;
}
private
void
createBlockages
(
Building
b
,
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
roadBlockages
,
int
time
)
{
long
t
=
System
.
currentTimeMillis
();
Logger
.
debug
(
"Creating blockages for "
+
b
);
/*
* Aftershock's Requirement@2103: this checks the ratio of the
* building's floors that is possible to collapsed
*/
double
remainingfloors
=
model
().
getCSBuiding
(
b
)
.
getRemainingToCollapse
(
floorHeight
);
double
currentExtent
=
extent
.
nextValue
();
double
damage
=
b
.
getBrokenness
();
/*
* Aftershock Requirement 2013: applies the intensity of the aftershock.
* This only applies if there is an aftershock and time is >1 and the
* building doesn't have any fire damage. In case of any fire damage the
* building creates the max possible collapse.
*/
if
(
time
!=
1
&&
model
().
aftershockHappens
(
time
)
&&
!
model
().
getCSBuiding
(
b
).
hasFireDamage
())
{
float
intensity
=
model
().
aftershockIntensity
(
time
);
damage
=
(
int
)
((
float
)
damage
*
Math
.
min
(
1
,
intensity
));
}
/* Aftershock's Requirement: 2013 */
double
d
=
remainingfloors
*
(
damage
/
(
double
)
MAX_COLLAPSE
)
*
currentExtent
;
t1
+=
System
.
currentTimeMillis
()
-
t
;
t
=
System
.
currentTimeMillis
();
/* Aftershock's Requirement: 2013 */
model
().
getCSBuiding
(
b
).
increaseCollapseRatio
(
(
float
)
(
d
/
model
().
getCSBuiding
(
b
).
getTotalCollapse
(
floorHeight
)));
// Place some blockages on surrounding roads
List
<
java
.
awt
.
geom
.
Area
>
wallAreas
=
new
ArrayList
<
java
.
awt
.
geom
.
Area
>();
// Project each wall out and build a list of wall areas
for
(
Edge
edge
:
b
.
getEdges
())
{
projectWall
(
edge
,
wallAreas
,
d
);
}
java
.
awt
.
geom
.
Area
fullArea
=
new
java
.
awt
.
geom
.
Area
();
for
(
java
.
awt
.
geom
.
Area
wallArea
:
wallAreas
)
{
fullArea
.
add
(
wallArea
);
}
/*
* new ShapeDebugFrame().show("Collapsed building", new
* ShapeDebugFrame.AWTShapeInfo(b.getShape(), "Original building area",
* Color.RED, true), new ShapeDebugFrame.AWTShapeInfo(fullArea,
* "Expanded building area (d = " + d + ")", Color.BLACK, false) );
*/
// Find existing blockade areas
java
.
awt
.
geom
.
Area
existing
=
new
java
.
awt
.
geom
.
Area
();
if
(
policy
.
equals
(
CollapsePolicy
.
MERGE_BLOCKADES
))
{
for
(
StandardEntity
e
:
model
.
getEntitiesOfType
(
StandardEntityURN
.
BLOCKADE
))
{
Blockade
blockade
=
(
Blockade
)
e
;
existing
.
add
(
blockadeToArea
(
blockade
));
}
}
t2
+=
System
.
currentTimeMillis
()
-
t
;
// Intersect wall areas with roads
t
=
System
.
currentTimeMillis
();
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
blockadesForRoads
=
createRoadBlockades
(
fullArea
,
existing
);
t3
+=
System
.
currentTimeMillis
()
-
t
;
// Add to roadBlockages
for
(
Map
.
Entry
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
entry
:
blockadesForRoads
.
entrySet
())
{
Road
r
=
entry
.
getKey
();
Collection
<
java
.
awt
.
geom
.
Area
>
c
=
entry
.
getValue
();
roadBlockages
.
get
(
r
).
addAll
(
c
);
}
}
private
void
projectWall
(
Edge
edge
,
Collection
<
java
.
awt
.
geom
.
Area
>
areaList
,
double
d
)
{
Line2D
wallLine
=
new
Line2D
(
edge
.
getStartX
(),
edge
.
getStartY
(),
edge
.
getEndX
()
-
edge
.
getStartX
(),
edge
.
getEndY
()
-
edge
.
getStartY
());
Vector2D
wallDirection
=
wallLine
.
getDirection
();
Vector2D
offset
=
wallDirection
.
getNormal
().
normalised
().
scale
(-
d
);
Path2D
path
=
new
Path2D
.
Double
();
Point2D
right
=
wallLine
.
getOrigin
();
Point2D
left
=
wallLine
.
getEndPoint
();
Point2D
first
=
left
.
plus
(
offset
.
scale
(-
1
));
Point2D
second
=
right
.
plus
(
offset
.
scale
(-
1
));
Point2D
third
=
right
.
plus
(
offset
);
Point2D
fourth
=
left
.
plus
(
offset
);
path
.
moveTo
(
first
.
getX
(),
first
.
getY
());
path
.
lineTo
(
second
.
getX
(),
second
.
getY
());
path
.
lineTo
(
third
.
getX
(),
third
.
getY
());
path
.
lineTo
(
fourth
.
getX
(),
fourth
.
getY
());
path
.
closePath
();
java
.
awt
.
geom
.
Area
wallArea
=
new
java
.
awt
.
geom
.
Area
(
path
);
areaList
.
add
(
wallArea
);
// Also add circles at each corner
double
radius
=
offset
.
getLength
();
Ellipse2D
ellipse1
=
new
Ellipse2D
.
Double
(
right
.
getX
()
-
radius
,
right
.
getY
()
-
radius
,
radius
*
2
,
radius
*
2
);
Ellipse2D
ellipse2
=
new
Ellipse2D
.
Double
(
left
.
getX
()
-
radius
,
left
.
getY
()
-
radius
,
radius
*
2
,
radius
*
2
);
areaList
.
add
(
new
java
.
awt
.
geom
.
Area
(
ellipse1
));
areaList
.
add
(
new
java
.
awt
.
geom
.
Area
(
ellipse2
));
// Logger.info("Edge from " + wallLine + " expanded to " + first + ", "
// + second + ", " + third + ", " + fourth);
// debug.show("Collapsed building",
// new ShapeDebugFrame.AWTShapeInfo(buildingArea,
// "Original building area", Color.RED, true),
// new ShapeDebugFrame.Line2DShapeInfo(wallLine, "Wall edge",
// Color.WHITE, true, true),
// new ShapeDebugFrame.AWTShapeInfo(wallArea, "Wall area (d = " + d +
// ")", Color.GREEN, false),
// new ShapeDebugFrame.AWTShapeInfo(ellipse1, "Ellipse 1", Color.BLUE,
// false),
// new ShapeDebugFrame.AWTShapeInfo(ellipse2, "Ellipse 2", Color.ORANGE,
// false)
// );
}
private
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
createRoadBlockades
(
java
.
awt
.
geom
.
Area
buildingArea
,
java
.
awt
.
geom
.
Area
existing
)
{
Map
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>
result
=
new
HashMap
<
Road
,
Collection
<
java
.
awt
.
geom
.
Area
>>();
java
.
awt
.
Rectangle
rectangle
=
buildingArea
.
getBounds
();
Collection
<
StandardEntity
>
roads
=
model
.
getObjectsInRectangle
(
(
int
)
rectangle
.
getMinX
(),
(
int
)
rectangle
.
getMinY
(),
(
int
)
rectangle
.
getMaxX
(),
(
int
)
rectangle
.
getMaxY
());
for
(
StandardEntity
e
:
roads
)
{
if
(!(
e
instanceof
Road
))
{
continue
;
}
Road
r
=
(
Road
)
e
;
java
.
awt
.
geom
.
Area
roadArea
=
areaToGeomArea
(
r
);
java
.
awt
.
geom
.
Area
intersection
=
new
java
.
awt
.
geom
.
Area
(
roadArea
);
intersection
.
intersect
(
buildingArea
);
intersection
.
subtract
(
existing
);
if
(
intersection
.
isEmpty
())
{
continue
;
}
existing
.
add
(
intersection
);
List
<
java
.
awt
.
geom
.
Area
>
blockadeAreas
=
fix
(
intersection
);
result
.
put
(
r
,
blockadeAreas
);
// debug.show("Road blockage",
// new ShapeDebugFrame.AWTShapeInfo(buildingArea, "Building area",
// Color.BLACK, false),
// new ShapeDebugFrame.AWTShapeInfo(roadArea, "Road area",
// Color.BLUE, false),
// new ShapeDebugFrame.AWTShapeInfo(intersection, "Intersection",
// Color.GREEN, true)
// );
}
return
result
;
}
private
java
.
awt
.
geom
.
Area
areaToGeomArea
(
rescuecore2
.
standard
.
entities
.
Area
area
)
{
Path2D
result
=
new
Path2D
.
Double
();
Iterator
<
Edge
>
it
=
area
.
getEdges
().
iterator
();
Edge
e
=
it
.
next
();
result
.
moveTo
(
e
.
getStartX
(),
e
.
getStartY
());
result
.
lineTo
(
e
.
getEndX
(),
e
.
getEndY
());
while
(
it
.
hasNext
())
{
e
=
it
.
next
();
result
.
lineTo
(
e
.
getEndX
(),
e
.
getEndY
());
}
return
new
java
.
awt
.
geom
.
Area
(
result
);
}
private
List
<
java
.
awt
.
geom
.
Area
>
fix
(
java
.
awt
.
geom
.
Area
area
)
{
List
<
java
.
awt
.
geom
.
Area
>
result
=
new
ArrayList
<
java
.
awt
.
geom
.
Area
>();
if
(
area
.
isSingular
())
{
result
.
add
(
area
);
return
result
;
}
PathIterator
it
=
area
.
getPathIterator
(
null
);
Path2D
current
=
null
;
// CHECKSTYLE:OFF:MagicNumber
double
[]
d
=
new
double
[
6
];
while
(!
it
.
isDone
())
{
switch
(
it
.
currentSegment
(
d
))
{
case
PathIterator
.
SEG_MOVETO
:
if
(
current
!=
null
)
{
result
.
add
(
new
java
.
awt
.
geom
.
Area
(
current
));
}
current
=
new
Path2D
.
Double
();
current
.
moveTo
(
d
[
0
],
d
[
1
]);
break
;
case
PathIterator
.
SEG_LINETO
:
current
.
lineTo
(
d
[
0
],
d
[
1
]);
break
;
case
PathIterator
.
SEG_QUADTO
:
current
.
quadTo
(
d
[
0
],
d
[
1
],
d
[
2
],
d
[
3
]);
break
;
case
PathIterator
.
SEG_CUBICTO
:
current
.
curveTo
(
d
[
0
],
d
[
1
],
d
[
2
],
d
[
3
],
d
[
4
],
d
[
5
]);
break
;
case
PathIterator
.
SEG_CLOSE
:
current
.
closePath
();
break
;
default
:
throw
new
RuntimeException
(
"Unexpected result from PathIterator.currentSegment: "
+
it
.
currentSegment
(
d
));
}
it
.
next
();
}
// CHECKSTYLE:ON:MagicNumber
if
(
current
!=
null
)
{
result
.
add
(
new
java
.
awt
.
geom
.
Area
(
current
));
}
return
result
;
}
private
Blockade
makeBlockade
(
EntityID
id
,
java
.
awt
.
geom
.
Area
area
,
EntityID
roadID
)
{
if
(
area
.
isEmpty
())
{
return
null
;
}
Blockade
result
=
new
Blockade
(
id
);
int
[]
apexes
=
getApexes
(
area
);
List
<
Point2D
>
points
=
GeometryTools2D
.
vertexArrayToPoints
(
apexes
);
if
(
points
.
size
()
<
2
)
{
return
null
;
}
int
cost
=
(
int
)
(
GeometryTools2D
.
computeArea
(
points
)
*
REPAIR_COST_FACTOR
);
if
(
cost
==
0
)
{
return
null
;
}
Point2D
centroid
=
GeometryTools2D
.
computeCentroid
(
points
);
result
.
setApexes
(
apexes
);
result
.
setPosition
(
roadID
);
result
.
setX
((
int
)
centroid
.
getX
());
result
.
setY
((
int
)
centroid
.
getY
());
result
.
setRepairCost
((
int
)
cost
);
return
result
;
}
private
int
[]
getApexes
(
java
.
awt
.
geom
.
Area
area
)
{
// Logger.debug("getApexes");
List
<
Integer
>
apexes
=
new
ArrayList
<
Integer
>();
// CHECKSTYLE:OFF:MagicNumber
PathIterator
it
=
area
.
getPathIterator
(
null
,
100
);
double
[]
d
=
new
double
[
6
];
int
moveX
=
0
;
int
moveY
=
0
;
int
lastX
=
0
;
int
lastY
=
0
;
boolean
finished
=
false
;
while
(!
finished
&&
!
it
.
isDone
())
{
int
x
=
0
;
int
y
=
0
;
switch
(
it
.
currentSegment
(
d
))
{
case
PathIterator
.
SEG_MOVETO
:
x
=
(
int
)
d
[
0
];
y
=
(
int
)
d
[
1
];
moveX
=
x
;
moveY
=
y
;
// Logger.debug("Move to " + x + ", " + y);
break
;
case
PathIterator
.
SEG_LINETO
:
x
=
(
int
)
d
[
0
];
y
=
(
int
)
d
[
1
];
// Logger.debug("Line to " + x + ", " + y);
if
(
x
==
moveX
&&
y
==
moveY
)
{
finished
=
true
;
}
break
;
case
PathIterator
.
SEG_QUADTO
:
x
=
(
int
)
d
[
2
];
y
=
(
int
)
d
[
3
];
// Logger.debug("Quad to " + x + ", " + y);
if
(
x
==
moveX
&&
y
==
moveY
)
{
finished
=
true
;
}
break
;
case
PathIterator
.
SEG_CUBICTO
:
x
=
(
int
)
d
[
4
];
y
=
(
int
)
d
[
5
];
// Logger.debug("Cubic to " + x + ", " + y);
if
(
x
==
moveX
&&
y
==
moveY
)
{
finished
=
true
;
}
break
;
case
PathIterator
.
SEG_CLOSE
:
// Logger.debug("Close");
finished
=
true
;
break
;
default
:
throw
new
RuntimeException
(
"Unexpected result from PathIterator.currentSegment: "
+
it
.
currentSegment
(
d
));
}
// Logger.debug(x + ", " + y);
if
(!
finished
&&
(
x
!=
lastX
||
y
!=
lastY
))
{
apexes
.
add
(
x
);
apexes
.
add
(
y
);
}
lastX
=
x
;
lastY
=
y
;
it
.
next
();
}
// CHECKSTYLE:ON:MagicNumber
int
[]
result
=
new
int
[
apexes
.
size
()];
int
i
=
0
;
for
(
Integer
next
:
apexes
)
{
result
[
i
++]
=
next
;
}
return
result
;
}
private
java
.
awt
.
geom
.
Area
blockadeToArea
(
Blockade
b
)
{
Path2D
result
=
new
Path2D
.
Double
();
int
[]
apexes
=
b
.
getApexes
();
result
.
moveTo
(
apexes
[
0
],
apexes
[
1
]);
for
(
int
i
=
2
;
i
<
apexes
.
length
;
i
+=
2
)
{
result
.
lineTo
(
apexes
[
i
],
apexes
[
i
+
1
]);
}
result
.
closePath
();
return
new
java
.
awt
.
geom
.
Area
(
result
);
}
private
class
CollapseStats
{
private
double
pDestroyed
;
private
double
pSevere
;
private
double
pModerate
;
private
double
pSlight
;
CollapseStats
(
StandardEntityConstants
.
BuildingCode
code
,
Config
config
)
{
String
s
=
CONFIG_PREFIX
+
code
.
toString
().
toLowerCase
();
pDestroyed
=
config
.
getFloatValue
(
s
+
DESTROYED_SUFFIX
);
pSevere
=
pDestroyed
+
config
.
getFloatValue
(
s
+
SEVERE_SUFFIX
);
pModerate
=
pSevere
+
config
.
getFloatValue
(
s
+
MODERATE_SUFFIX
);
pSlight
=
pModerate
+
config
.
getFloatValue
(
s
+
SLIGHT_SUFFIX
);
}
int
damage
()
{
double
d
=
random
.
nextDouble
();
if
(
d
<
pDestroyed
)
{
return
destroyed
.
nextValue
().
intValue
();
}
if
(
d
<
pSevere
)
{
return
severe
.
nextValue
().
intValue
();
}
if
(
d
<
pModerate
)
{
return
moderate
.
nextValue
().
intValue
();
}
if
(
d
<
pSlight
)
{
return
slight
.
nextValue
().
intValue
();
}
return
0
;
}
}
private
enum
CollapseDegree
{
NONE
(
0
),
SLIGHT
(
25
),
MODERATE
(
50
),
SEVERE
(
75
),
DESTROYED
(
100
);
private
int
max
;
private
CollapseDegree
(
int
max
)
{
this
.
max
=
max
;
}
public
static
CollapseDegree
get
(
int
d
)
{
for
(
CollapseDegree
next
:
values
())
{
if
(
d
<=
next
.
max
)
{
return
next
;
}
}
throw
new
IllegalArgumentException
(
"Don't know what to do with a damage value of "
+
d
);
}
}
// /* Aftershocks Requirement:2013 */
// /**
// * Handles KAAftershocksInfo and calls the parent processMessage.
// */
// @Override
// protected void processMessage(Message msg) {
//
// }
/* Aftershocks Requirement:2013 */
public
CollapseWorldModel
model
()
{
return
(
CollapseWorldModel
)
model
;
}
@Override
protected
void
processMessage
(
Message
msg
)
{
if
(
msg
instanceof
KSAfterShocksInfo
)
{
model
().
updateAftershocks
((
KSAfterShocksInfo
)
msg
);
}
else
{
super
.
processMessage
(
msg
);
}
}
public
static
void
main
(
String
[]
args
)
{
}
}
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
package
gis2
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
maps.gml.GMLRefuge
;
import
org.apache.log4j.Logger
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentHelper
;
import
org.dom4j.Element
;
import
org.dom4j.Namespace
;
import
org.dom4j.QName
;
import
rescuecore2.config.Config
;
import
rescuecore2.scenario.compatibilities.CollapseSimCompatibaleScenarioV1_1
;
import
rescuecore2.scenario.exceptions.ScenarioException
;
import
rescuecore2.standard.entities.AmbulanceCentre
;
import
rescuecore2.standard.entities.AmbulanceTeam
;
import
rescuecore2.standard.entities.Area
;
import
rescuecore2.standard.entities.Building
;
import
rescuecore2.standard.entities.Civilian
;
import
rescuecore2.standard.entities.FireBrigade
;
import
rescuecore2.standard.entities.FireStation
;
import
rescuecore2.standard.entities.GasStation
;
import
rescuecore2.standard.entities.Human
;
import
rescuecore2.standard.entities.Hydrant
;
import
rescuecore2.standard.entities.PoliceForce
;
import
rescuecore2.standard.entities.PoliceOffice
;
import
rescuecore2.standard.entities.Refuge
;
import
rescuecore2.standard.entities.Road
;
import
rescuecore2.standard.entities.StandardEntity
;
import
rescuecore2.standard.entities.StandardWorldModel
;
import
rescuecore2.worldmodel.Entity
;
import
rescuecore2.worldmodel.EntityID
;
/**
* This class knows how to read scenario files and apply them to
* StandardWorldModels.
*/
public
class
GisScenario
implements
rescuecore2
.
scenario
.
Scenario
,
CollapseSimCompatibaleScenarioV1_1
{
private
static
final
String
SCENARIO_NAMESPACE_URI
=
"urn:roborescue:map:scenario"
;
private
static
final
Namespace
SCENARIO_NAMESPACE
=
DocumentHelper
.
createNamespace
(
"scenario"
,
SCENARIO_NAMESPACE_URI
);
private
static
final
int
DEFAULT_HP
=
10000
;
private
static
final
int
DEFAULT_STAMINA
=
10000
;
private
static
final
String
WATER_QUANTITY_KEY
=
"fire.tank.maximum"
;
private
static
final
QName
LOCATION_QNAME
=
DocumentHelper
.
createQName
(
"location"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
TIME_QNAME
=
DocumentHelper
.
createQName
(
"time"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
INTENSITY_QNAME
=
DocumentHelper
.
createQName
(
"intensity"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
SCENARIO_QNAME
=
DocumentHelper
.
createQName
(
"scenario"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
REFUGE_QNAME
=
DocumentHelper
.
createQName
(
"refuge"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
GAS_STATION_QNAME
=
DocumentHelper
.
createQName
(
"gasstation"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
HYDRANT_QNAME
=
DocumentHelper
.
createQName
(
"hydrant"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
CIV_QNAME
=
DocumentHelper
.
createQName
(
"civilian"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
FB_QNAME
=
DocumentHelper
.
createQName
(
"firebrigade"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
AT_QNAME
=
DocumentHelper
.
createQName
(
"ambulanceteam"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
PF_QNAME
=
DocumentHelper
.
createQName
(
"policeforce"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
FS_QNAME
=
DocumentHelper
.
createQName
(
"firestation"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
AC_QNAME
=
DocumentHelper
.
createQName
(
"ambulancecentre"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
PO_QNAME
=
DocumentHelper
.
createQName
(
"policeoffice"
,
SCENARIO_NAMESPACE
);
private
static
final
QName
FIRE_QNAME
=
DocumentHelper
.
createQName
(
"fire"
,
SCENARIO_NAMESPACE
);
/* Aftershock requirement:2013 */
private
static
final
QName
AFTERSHOCK_QNAME
=
DocumentHelper
.
createQName
(
"aftershock"
,
SCENARIO_NAMESPACE
);
/* Refuge bed capacity:2020 */
private
static
final
QName
BEDCAPACITY_QNAME
=
DocumentHelper
.
createQName
(
"bedCapacity"
,
SCENARIO_NAMESPACE
);
/* Refuge refill capacity:2020 */
private
static
final
QName
REFILLCAPACITY_QNAME
=
DocumentHelper
.
createQName
(
"refillCapacity"
,
SCENARIO_NAMESPACE
);
private
Set
<
Integer
>
refuges
;
private
Set
<
Integer
>
hydrants
;
private
Set
<
Integer
>
gasStations
;
private
Set
<
Integer
>
fires
;
/* Aftershock requirement:2013 */
private
HashMap
<
Integer
,
Float
>
aftershocks
;
private
Collection
<
Integer
>
civLocations
;
private
Collection
<
Integer
>
fbLocations
;
private
Collection
<
Integer
>
atLocations
;
private
Collection
<
Integer
>
pfLocations
;
private
Collection
<
Integer
>
fsLocations
;
private
Collection
<
Integer
>
acLocations
;
private
Collection
<
Integer
>
poLocations
;
/* Refuge Capacity requirements: 2020 */
private
HashMap
<
Integer
,
Integer
>
refugeBedCapacity
;
private
HashMap
<
Integer
,
Integer
>
refugeRefillCapacity
;
private
Map
<
Integer
,
GMLRefuge
>
gmlRefuges
;
private
static
final
Logger
LOG
=
Logger
.
getLogger
(
GisScenario
.
class
);
/**
* Create an empty scenario.
*/
public
GisScenario
()
{
refuges
=
new
HashSet
<
Integer
>();
hydrants
=
new
HashSet
<
Integer
>();
gasStations
=
new
HashSet
<
Integer
>();
fires
=
new
HashSet
<
Integer
>();
civLocations
=
new
ArrayList
<
Integer
>();
fbLocations
=
new
ArrayList
<
Integer
>();
pfLocations
=
new
ArrayList
<
Integer
>();
atLocations
=
new
ArrayList
<
Integer
>();
fsLocations
=
new
ArrayList
<
Integer
>();
poLocations
=
new
ArrayList
<
Integer
>();
acLocations
=
new
ArrayList
<
Integer
>();
/* Aftershock requirement:2013 */
aftershocks
=
new
HashMap
<
Integer
,
Float
>();
/* Refuge Capacity requirements: 2020 */
refugeBedCapacity
=
new
HashMap
<
Integer
,
Integer
>();
refugeRefillCapacity
=
new
HashMap
<
Integer
,
Integer
>();
gmlRefuges
=
new
HashMap
<
Integer
,
GMLRefuge
>();
}
/**
* Create a scenario from an XML document.
*
* @param doc The document to read.
* @throws ScenarioException If the scenario is invalid.
*/
public
GisScenario
(
Document
doc
,
Config
config
)
throws
ScenarioException
{
this
();
read
(
doc
,
config
);
}
/**
* Read scenario data from an XML document.
*
* @param doc The document to read.
* @throws ScenarioException If the scenario is invalid.
*/
public
void
read
(
Document
doc
,
Config
config
)
throws
ScenarioException
{
hydrants
.
clear
();
gasStations
.
clear
();
refuges
.
clear
();
fires
.
clear
();
civLocations
.
clear
();
fbLocations
.
clear
();
pfLocations
.
clear
();
atLocations
.
clear
();
fsLocations
.
clear
();
poLocations
.
clear
();
acLocations
.
clear
();
refugeBedCapacity
.
clear
();
refugeRefillCapacity
.
clear
();
Element
root
=
doc
.
getRootElement
();
if
(!
root
.
getQName
().
equals
(
SCENARIO_QNAME
))
{
throw
new
ScenarioException
(
"Scenario document has wrong root element: expecting "
+
SCENARIO_QNAME
+
"; not "
+
root
.
getQName
());
}
for
(
Object
next
:
root
.
elements
(
REFUGE_QNAME
))
{
Element
e
=
(
Element
)
next
;
refuges
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
/* capacity requirements:2020 */
int
default_bedCapacity
=
config
.
getIntValue
(
"gis.map.refuge.default-bedCapacity"
,
1000
);
int
default_refillCapacity
=
config
.
getIntValue
(
"gis.map.refuge.default-refillCapacity"
,
1000
);
int
bedCapacity
=
e
.
attributeValue
(
BEDCAPACITY_QNAME
)
!=
null
?
Integer
.
parseInt
(
e
.
attributeValue
(
BEDCAPACITY_QNAME
))
:
default_bedCapacity
;
int
refillCapacity
=
e
.
attributeValue
(
REFILLCAPACITY_QNAME
)
!=
null
?
Integer
.
parseInt
(
e
.
attributeValue
(
REFILLCAPACITY_QNAME
))
:
default_refillCapacity
;
refugeBedCapacity
.
put
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)),
bedCapacity
);
refugeRefillCapacity
.
put
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)),
refillCapacity
);
}
for
(
Object
next
:
root
.
elements
(
HYDRANT_QNAME
))
{
Element
e
=
(
Element
)
next
;
hydrants
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
GAS_STATION_QNAME
))
{
Element
e
=
(
Element
)
next
;
gasStations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
CIV_QNAME
))
{
Element
e
=
(
Element
)
next
;
civLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
FB_QNAME
))
{
Element
e
=
(
Element
)
next
;
fbLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
PF_QNAME
))
{
Element
e
=
(
Element
)
next
;
pfLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
AT_QNAME
))
{
Element
e
=
(
Element
)
next
;
atLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
FS_QNAME
))
{
Element
e
=
(
Element
)
next
;
fsLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
PO_QNAME
))
{
Element
e
=
(
Element
)
next
;
poLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
AC_QNAME
))
{
Element
e
=
(
Element
)
next
;
acLocations
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
for
(
Object
next
:
root
.
elements
(
FIRE_QNAME
))
{
Element
e
=
(
Element
)
next
;
fires
.
add
(
Integer
.
parseInt
(
e
.
attributeValue
(
LOCATION_QNAME
)));
}
/*
* Aftershock requirement:2013
*/
for
(
Object
next
:
root
.
elements
(
AFTERSHOCK_QNAME
))
{
Element
e
=
(
Element
)
next
;
aftershocks
.
put
(
Integer
.
parseInt
(
e
.
attributeValue
(
TIME_QNAME
)),
Float
.
parseFloat
(
e
.
attributeValue
(
INTENSITY_QNAME
)));
}
}
/**
* Write scenario data to an XML document.
*
* @param doc The document to write to.
*/
public
void
write
(
Document
doc
)
{
Element
root
=
DocumentHelper
.
createElement
(
SCENARIO_QNAME
);
doc
.
setRootElement
(
root
);
for
(
int
next
:
refuges
)
{
Element
el
=
root
.
addElement
(
REFUGE_QNAME
);
el
.
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
el
.
addAttribute
(
BEDCAPACITY_QNAME
,
String
.
valueOf
(
refugeBedCapacity
.
get
(
next
)));
// el.addAttribute(REFILLCAPACITY_QNAME,
// String.valueOf(refugeRefillCapacity.get(next)));
}
for
(
int
next
:
fires
)
{
root
.
addElement
(
FIRE_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
hydrants
)
{
root
.
addElement
(
HYDRANT_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
gasStations
)
{
root
.
addElement
(
GAS_STATION_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
civLocations
)
{
root
.
addElement
(
CIV_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
fbLocations
)
{
root
.
addElement
(
FB_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
fsLocations
)
{
root
.
addElement
(
FS_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
pfLocations
)
{
root
.
addElement
(
PF_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
poLocations
)
{
root
.
addElement
(
PO_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
atLocations
)
{
root
.
addElement
(
AT_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
for
(
int
next
:
acLocations
)
{
root
.
addElement
(
AC_QNAME
).
addAttribute
(
LOCATION_QNAME
,
String
.
valueOf
(
next
));
}
root
.
addNamespace
(
"scenario"
,
SCENARIO_NAMESPACE_URI
);
}
/**
* Apply this scenario to a world model.
*
* @param model The world model to alter.
* @param config The configuration.
* @throws ScenarioException if this scenario is invalid.
*/
public
void
apply
(
StandardWorldModel
model
,
Config
config
)
throws
ScenarioException
{
LOG
.
debug
(
"Creating "
+
refuges
.
size
()
+
" refuges"
);
for
(
int
next
:
refuges
)
{
LOG
.
debug
(
"Converting building "
+
next
+
" to a refuge"
);
Building
b
=
(
Building
)
model
.
getEntity
(
new
EntityID
(
next
));
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
Refuge
r
=
new
Refuge
(
b
);
if
(
refugeBedCapacity
.
containsKey
(
next
))
r
.
setBedCapacity
(
refugeBedCapacity
.
get
(
next
));
else
throw
new
ScenarioException
(
"RefugeBedCapacity dose not contains "
+
next
);
if
(
refugeRefillCapacity
.
containsKey
(
next
))
r
.
setRefillCapacity
(
refugeRefillCapacity
.
get
(
next
));
else
throw
new
ScenarioException
(
"refugeRefillCapacity dose not contain "
+
next
);
r
.
setOccupiedBeds
(
0
);
r
.
setCapacity
(
0
);
// todo
r
.
setWaitingListSize
(
0
);
model
.
removeEntity
(
b
);
model
.
addEntity
(
r
);
LOG
.
debug
(
"Converted "
+
b
+
" into "
+
r
);
}
for
(
int
next
:
gasStations
)
{
LOG
.
debug
(
"Converting building "
+
next
+
" to a gas station"
);
Building
b
=
(
Building
)
model
.
getEntity
(
new
EntityID
(
next
));
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
GasStation
r
=
new
GasStation
(
b
);
r
.
setImportance
(
5
);
model
.
removeEntity
(
b
);
model
.
addEntity
(
r
);
LOG
.
debug
(
"Converted "
+
b
+
" into "
+
r
);
}
for
(
int
next
:
hydrants
)
{
LOG
.
debug
(
"Converting Road "
+
next
+
" to a hydrant"
);
Area
area
=
(
Area
)
model
.
getEntity
(
new
EntityID
(
next
));
if
(
area
==
null
||
!(
area
instanceof
Road
))
{
throw
new
ScenarioException
(
"Road "
+
next
+
" does not exist"
);
}
Hydrant
h
=
new
Hydrant
((
Road
)
area
);
model
.
removeEntity
(
area
);
model
.
addEntity
(
h
);
LOG
.
debug
(
"Converted "
+
area
+
" into "
+
h
);
}
LOG
.
debug
(
"Igniting "
+
fires
.
size
()
+
" fires"
);
for
(
int
next
:
fires
)
{
LOG
.
debug
(
"Igniting "
+
next
);
Building
b
=
(
Building
)
model
.
getEntity
(
new
EntityID
(
next
));
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
b
.
setIgnition
(
true
);
}
int
lastID
=
0
;
for
(
StandardEntity
next
:
model
)
{
lastID
=
Math
.
max
(
lastID
,
next
.
getID
().
getValue
());
}
LOG
.
debug
(
"Creating "
+
fbLocations
.
size
()
+
" fire brigades"
);
for
(
int
next
:
fbLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
lastID
=
getNextId
(
model
,
config
,
lastID
);
FireBrigade
f
=
new
FireBrigade
(
new
EntityID
(
lastID
));
setupAgent
(
f
,
id
,
model
,
config
);
}
LOG
.
debug
(
"Creating "
+
pfLocations
.
size
()
+
" police forces"
);
for
(
int
next
:
pfLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
lastID
=
getNextId
(
model
,
config
,
lastID
);
PoliceForce
p
=
new
PoliceForce
(
new
EntityID
(
lastID
));
setupAgent
(
p
,
id
,
model
,
config
);
}
LOG
.
debug
(
"Creating "
+
atLocations
.
size
()
+
" ambulance teams"
);
for
(
int
next
:
atLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
lastID
=
getNextId
(
model
,
config
,
lastID
);
AmbulanceTeam
a
=
new
AmbulanceTeam
(
new
EntityID
(
lastID
));
setupAgent
(
a
,
id
,
model
,
config
);
}
LOG
.
debug
(
"Creating "
+
fsLocations
.
size
()
+
" fire stations"
);
for
(
int
next
:
fsLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
LOG
.
debug
(
"Coverting building "
+
next
+
" to a fire station"
);
Building
b
=
(
Building
)
model
.
getEntity
(
id
);
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
FireStation
f
=
new
FireStation
(
b
);
model
.
removeEntity
(
b
);
model
.
addEntity
(
f
);
LOG
.
debug
(
"Converted "
+
b
+
" into "
+
f
);
}
LOG
.
debug
(
"Creating "
+
poLocations
.
size
()
+
" police offices"
);
for
(
int
next
:
poLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
LOG
.
debug
(
"Coverting building "
+
next
+
" to a police office"
);
Building
b
=
(
Building
)
model
.
getEntity
(
id
);
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
PoliceOffice
p
=
new
PoliceOffice
(
b
);
model
.
removeEntity
(
b
);
model
.
addEntity
(
p
);
LOG
.
debug
(
"Converted "
+
b
+
" into "
+
p
);
}
LOG
.
debug
(
"Creating "
+
acLocations
.
size
()
+
" ambulance centres"
);
for
(
int
next
:
acLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
LOG
.
debug
(
"Coverting building "
+
next
+
" to an ambulance centre"
);
Building
b
=
(
Building
)
model
.
getEntity
(
id
);
if
(
b
==
null
)
{
throw
new
ScenarioException
(
"Building "
+
next
+
" does not exist"
);
}
AmbulanceCentre
a
=
new
AmbulanceCentre
(
b
);
model
.
removeEntity
(
b
);
model
.
addEntity
(
a
);
LOG
.
debug
(
"Converted "
+
b
+
" into "
+
a
);
}
LOG
.
debug
(
"Creating "
+
civLocations
.
size
()
+
" civilians"
);
for
(
int
next
:
civLocations
)
{
EntityID
id
=
new
EntityID
(
next
);
lastID
=
getNextId
(
model
,
config
,
lastID
);
Civilian
c
=
new
Civilian
(
new
EntityID
(
lastID
));
setupAgent
(
c
,
id
,
model
,
config
);
}
}
private
int
getNextId
(
StandardWorldModel
model
,
Config
config
,
int
lastId
)
{
boolean
humanRandomId
=
config
.
getBooleanValue
(
"senario.human.random-id"
,
true
);
if
(
humanRandomId
)
{
int
newId
;
do
{
newId
=
config
.
getRandom
().
nextInt
(
Integer
.
MAX_VALUE
);
}
while
(
model
.
getEntity
(
new
EntityID
(
newId
))
!=
null
);
return
newId
;
}
else
{
return
lastId
+
1
;
}
}
/**
* Get the set of fire locations.
*
* @return The set of fire locations.
*/
public
Set
<
Integer
>
getFires
()
{
return
Collections
.
unmodifiableSet
(
fires
);
}
/**
* Get the set of refuge locations.
*
* @return The set of refuge locations.
*/
public
Set
<
Integer
>
getRefuges
()
{
return
Collections
.
unmodifiableSet
(
refuges
);
}
/**
* Get a refuge by ID.
*
* @param id The ID to look up.
* @return The refuge with that ID or null if the ID is not found.
*/
public
GMLRefuge
getRefuge
(
int
id
)
{
return
gmlRefuges
.
get
(
id
);
}
/**
* Get the set of GMLRefuges.
*
* @return The set of GMLRefuges.
*/
public
Map
<
Integer
,
GMLRefuge
>
getGMLRefuges
()
{
return
gmlRefuges
;
}
/**
* Get the HashMap of refuge bed capacity.
*
* @return The HashMap of refuge bed capacity.
*/
public
HashMap
<
Integer
,
Integer
>
getRefugeBedCapacity
()
{
return
refugeBedCapacity
;
}
/**
* Get the HashMap of refuge refill capacity.
*
* @return The HashMap of refuge refill capacity.
*/
public
HashMap
<
Integer
,
Integer
>
getRefugeRefillCapacity
()
{
return
refugeRefillCapacity
;
}
/**
* Get the set of GasStations locations.
*
* @return The set of GasStations locations.
*/
public
Set
<
Integer
>
getGasStations
()
{
return
Collections
.
unmodifiableSet
(
gasStations
);
}
/**
* Get the set of hydrant locations.
*
* @return The set of hydrant locations.
*/
public
Set
<
Integer
>
getHydrants
()
{
return
Collections
.
unmodifiableSet
(
hydrants
);
}
/**
* Get the list of civilian locations.
*
* @return The list of civilian locations.
*/
public
Collection
<
Integer
>
getCivilians
()
{
return
Collections
.
unmodifiableCollection
(
civLocations
);
}
/**
* Get the list of fire brigade locations.
*
* @return The list of fire brigade locations.
*/
public
Collection
<
Integer
>
getFireBrigades
()
{
return
Collections
.
unmodifiableCollection
(
fbLocations
);
}
/**
* Get the list of fire station locations.
*
* @return The list of fire station locations.
*/
public
Collection
<
Integer
>
getFireStations
()
{
return
Collections
.
unmodifiableCollection
(
fsLocations
);
}
/**
* Get the list of police force locations.
*
* @return The list of police force locations.
*/
public
Collection
<
Integer
>
getPoliceForces
()
{
return
Collections
.
unmodifiableCollection
(
pfLocations
);
}
/**
* Get the list of police office locations.
*
* @return The list of police office locations.
*/
public
Collection
<
Integer
>
getPoliceOffices
()
{
return
Collections
.
unmodifiableCollection
(
poLocations
);
}
/**
* Get the list of ambulance team locations.
*
* @return The list of ambulance team locations.
*/
public
Collection
<
Integer
>
getAmbulanceTeams
()
{
return
Collections
.
unmodifiableCollection
(
atLocations
);
}
/**
* Get the list of ambulance centre locations.
*
* @return The list of ambulance centre locations.
*/
public
Collection
<
Integer
>
getAmbulanceCentres
()
{
return
Collections
.
unmodifiableCollection
(
acLocations
);
}
/**
* Set the set of fire locations.
*
* @param newLocations The new set of locations.
*/
public
void
setFires
(
Set
<
Integer
>
newLocations
)
{
fires
.
clear
();
fires
.
addAll
(
newLocations
);
}
/**
* Set the set of refuge locations.
*
* @param newLocations The new set of locations.
*/
public
void
setRefuges
(
Set
<
Integer
>
newLocations
)
{
refuges
.
clear
();
refuges
.
addAll
(
newLocations
);
}
/**
* Set the set of gas station locations.
*
* @param newLocations The new set of locations.
*/
public
void
setGasStations
(
Set
<
Integer
>
newLocations
)
{
gasStations
.
clear
();
gasStations
.
addAll
(
newLocations
);
}
/**
* Set the set of hydrant locations.
*
* @param newLocations The new set of locations.
*/
public
void
setHydrants
(
Set
<
Integer
>
newLocations
)
{
hydrants
.
clear
();
hydrants
.
addAll
(
newLocations
);
}
/**
* Set the list of civilian locations.
*
* @param newLocations The new list of locations.
*/
public
void
setCivilians
(
Collection
<
Integer
>
newLocations
)
{
civLocations
.
clear
();
civLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of fire brigade locations.
*
* @param newLocations The new list of locations.
*/
public
void
setFireBrigades
(
Collection
<
Integer
>
newLocations
)
{
fbLocations
.
clear
();
fbLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of fire station locations.
*
* @param newLocations The new list of locations.
*/
public
void
setFireStations
(
Collection
<
Integer
>
newLocations
)
{
fsLocations
.
clear
();
fsLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of police force locations.
*
* @param newLocations The new list of locations.
*/
public
void
setPoliceForces
(
Collection
<
Integer
>
newLocations
)
{
pfLocations
.
clear
();
pfLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of police office locations.
*
* @param newLocations The new list of locations.
*/
public
void
setPoliceOffices
(
Collection
<
Integer
>
newLocations
)
{
poLocations
.
clear
();
poLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of ambulance team locations.
*
* @param newLocations The new list of locations.
*/
public
void
setAmbulanceTeams
(
Collection
<
Integer
>
newLocations
)
{
atLocations
.
clear
();
atLocations
.
addAll
(
newLocations
);
}
/**
* Set the list of ambulance centre locations.
*
* @param newLocations The new list of locations.
*/
public
void
setAmbulanceCentres
(
Collection
<
Integer
>
newLocations
)
{
acLocations
.
clear
();
acLocations
.
addAll
(
newLocations
);
}
/**
* Add a fire.
*
* @param location The new fire location.
*/
public
void
addFire
(
int
location
)
{
fires
.
add
(
location
);
}
/**
* Remove a fire.
*
* @param location The fire location to remove.
*/
public
void
removeFire
(
int
location
)
{
fires
.
remove
(
location
);
}
/**
* Add a refuge.
*
* @param location The new refuge location.
*/
public
void
addRefuge
(
int
location
)
{
refuges
.
add
(
location
);
}
public
void
addRefuge
(
int
location
,
int
bedCapacity
,
int
refillCapacity
)
{
refuges
.
add
(
location
);
refugeBedCapacity
.
put
(
location
,
bedCapacity
);
refugeRefillCapacity
.
put
(
location
,
refillCapacity
);
}
public
void
addRefuge
(
int
location
,
int
bedCapacity
)
{
refuges
.
add
(
location
);
refugeBedCapacity
.
put
(
location
,
bedCapacity
);
}
public
void
addGMLRefuge
(
GMLRefuge
r
)
{
gmlRefuges
.
put
(
r
.
getID
(),
r
);
}
/**
* Remove a refuge.
*
* @param location The refuge location to remove.
*/
public
void
removeRefuge
(
int
location
)
{
refuges
.
remove
(
location
);
if
(
refugeRefillCapacity
.
containsKey
(
location
))
{
refugeRefillCapacity
.
remove
(
location
);
}
if
(
refugeBedCapacity
.
containsKey
(
location
))
{
refugeBedCapacity
.
remove
(
location
);
}
gmlRefuges
.
remove
(
location
);
}
/**
* Add a hydrant.
*
* @param location The new hydrant location.
*/
public
void
addHydrant
(
int
location
)
{
hydrants
.
add
(
location
);
}
/**
* Remove a hydrant.
*
* @param location The hydrant location to remove.
*/
public
void
removeHydrant
(
int
location
)
{
hydrants
.
remove
(
location
);
}
/**
* Remove a GasStation.
*
* @param location The GasStation location to remove.
*/
public
void
removeGasStation
(
int
location
)
{
gasStations
.
remove
(
location
);
}
/**
* Add a GasStation.
*
* @param location The new GasStation location.
*/
public
void
addGasStation
(
int
location
)
{
gasStations
.
add
(
location
);
}
/**
* Add a civilian.
*
* @param location The new civilian location.
*/
public
void
addCivilian
(
int
location
)
{
civLocations
.
add
(
location
);
}
/**
* Remove a civilian.
*
* @param location The civilian location to remove.
*/
public
void
removeCivilian
(
int
location
)
{
civLocations
.
remove
(
location
);
}
/**
* Add a fire brigade.
*
* @param location The new fire brigade location.
*/
public
void
addFireBrigade
(
int
location
)
{
fbLocations
.
add
(
location
);
}
/**
* Remove a fire brigade.
*
* @param location The fire brigade location to remove.
*/
public
void
removeFireBrigade
(
int
location
)
{
fbLocations
.
remove
(
location
);
}
/**
* Add a fire station.
*
* @param location The new fire station location.
*/
public
void
addFireStation
(
int
location
)
{
fsLocations
.
add
(
location
);
}
/**
* Remove a fire station.
*
* @param location The fire station location to remove.
*/
public
void
removeFireStation
(
int
location
)
{
fsLocations
.
remove
(
location
);
}
/**
* Add a police force.
*
* @param location The new police force location.
*/
public
void
addPoliceForce
(
int
location
)
{
pfLocations
.
add
(
location
);
}
/**
* Remove a police force.
*
* @param location The police force location to remove.
*/
public
void
removePoliceForce
(
int
location
)
{
pfLocations
.
remove
(
location
);
}
/**
* Add a police office.
*
* @param location The new police office location.
*/
public
void
addPoliceOffice
(
int
location
)
{
poLocations
.
add
(
location
);
}
/**
* Remove a police office.
*
* @param location The police office location to remove.
*/
public
void
removePoliceOffice
(
int
location
)
{
poLocations
.
remove
(
location
);
}
/**
* Add an ambulance team.
*
* @param location The new ambulance team location.
*/
public
void
addAmbulanceTeam
(
int
location
)
{
atLocations
.
add
(
location
);
}
/**
* Remove an ambulance team.
*
* @param location The ambulance team location to remove.
*/
public
void
removeAmbulanceTeam
(
int
location
)
{
atLocations
.
remove
(
location
);
}
/**
* Add an ambulance centre.
*
* @param location The new ambulance centre location.
*/
public
void
addAmbulanceCentre
(
int
location
)
{
acLocations
.
add
(
location
);
}
/**
* Remove an ambulance centre.
*
* @param location The ambulance centre location to remove.
*/
public
void
removeAmbulanceCentre
(
int
location
)
{
acLocations
.
remove
(
location
);
}
private
void
setupAgent
(
Human
h
,
EntityID
position
,
StandardWorldModel
model
,
Config
config
)
throws
ScenarioException
{
Entity
areaEntity
=
model
.
getEntity
(
position
);
if
(
areaEntity
==
null
)
{
throw
new
ScenarioException
(
"Area "
+
position
+
" does not exist"
);
}
if
(!(
areaEntity
instanceof
Area
))
{
throw
new
ScenarioException
(
"Entity "
+
position
+
" is not an area: "
+
areaEntity
);
}
Area
area
=
(
Area
)
areaEntity
;
h
.
setX
(
area
.
getX
());
h
.
setY
(
area
.
getY
());
h
.
setPosition
(
position
);
h
.
setStamina
(
DEFAULT_STAMINA
);
h
.
setHP
(
DEFAULT_HP
);
h
.
setDamage
(
0
);
h
.
setBuriedness
(
0
);
h
.
setDirection
(
0
);
h
.
setTravelDistance
(
0
);
h
.
setPositionHistory
(
new
int
[
0
]);
if
(
h
instanceof
FireBrigade
)
{
((
FireBrigade
)
h
).
setWater
(
config
.
getIntValue
(
WATER_QUANTITY_KEY
));
}
model
.
addEntity
(
h
);
LOG
.
debug
(
"Created "
+
h
);
}
@Override
public
HashMap
<
Integer
,
Float
>
getAftershocks
()
{
return
aftershocks
;
}
}
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
…
21
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