24.09., 9:00 - 11:00: Due to updates GitLab will be unavailable for some minutes between 09:00 and 11:00.

Commit 7d67883e authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck

add overlap checks. Add new gui button to generate ids for ScenarioElements

parent 560d835f
Pipeline #69553 failed with stages
in 47 seconds
......@@ -299,6 +299,7 @@ TopographyCreator.btnSimplePolygon.label=Simple Polygon
TopographyCreator.btnCircle.label=Circle
TopographyCreator.btnRectangle.label=Rectangle
TopographyCreator.btnChecker.tooltip=Show Topography Checker Messages
TopographyCreator.btnMakro.tooltip=Generate not set IDs.
select_shape_tooltip=Select Shape
......@@ -309,16 +310,23 @@ TopographyChecker.source.targetIdNotFound=The following target ids where not fou
TopographyChecker.source.noTargetIdSet=No Target Ids set for Source.
TopographyChecker.source.noTargetIdAndNoSpawn=No Target Ids set for Source with SpawnNumber 0. This might be an error.
TopographyChecker.source.idNotUnique=Multiple Sources have the same ID.
TopographyChecker.source.overlapWithObstacle=Source overlaps with Obstacle. This leads to pedestrians spawn in obstacle.
TopographyChecker.stairs.wrongTreadDim=Stair treadDepth outside of allowed dimension.
TopographyChecker.target.unused=The target is not used in any source. Remove target to increase performance.
TopographyChecker.pedestrian.speedsetup=speedDistributionMean must be within min/max range.
TopographyChecker.pedestrian.speedNotLogical=Min or Max speed of pedestrian is bigger than world record.
TopographyChecker.pedestrian.speedIsNegative=Min or Max speed is negative.
#TopographyChecker.obstacles.overlap=
#TopographyChecker.source.overlap=
#TopographyChecker.target.overlap=
#TopographyChecker.stairs.overlap=
TopographyChecker.overlap.stair.stair=Stairs cannot overlap.
TopographyChecker.overlap.target.stair=A target and a stairs element overlap in scenario.
TopographyChecker.overlap.source.stair=A source and a stairs element overlap in scenario.
TopographyChecker.overlap.source.target=A source and a target element overlap in scenario.
TopographyChecker.overlap.source.source=Two source overlap. This can cause overlapping when useFreeSpaceOnly is not set.
TopographyChecker.overlap.obstacle.stairs.err=Stairs is completely contained in an obstacle.
TopographyChecker.overlap.obstacle.stairs.warn=Stairs contains an obstacle. This setup works put is not tested. Split in two stairs.
TopographyChecker.overlap.obstacle.target.err=Target is completely contained in an obstacle.
TopographyChecker.overlap.obstacle.target.warn=Target contains an obstacle. This setup works but reduces the actual size of the target.
TopographyChecker.overlap.obstacle.source=Obstacle overlaps with a source. This setup will spawn pedestrians within the obstacle.
TopographyChecker.overlap.obstacle.obstacle=Two obstacles overlap / is enclosed completely. Delete one for better performance.
# tab titles Topography creator / postvis
......
......@@ -298,6 +298,7 @@ TopographyCreator.btnSimplePolygon.label=Einfaches Polygon
TopographyCreator.btnCircle.label=Kreis
TopographyCreator.btnRectangle.label=Rechteck
TopographyCreator.btnChecker.tooltip=Topography Linter Nachrichten
TopographyCreator.btnMakro.tooltip=Erzeuge nicht gesetzte IDs.
# TopographyChecker
TopographyChecker.type.error=Fehler
......@@ -306,16 +307,23 @@ TopographyChecker.source.targetIdNotFound=Die folgenden Ziel-IDs wurden nicht im
TopographyChecker.source.noTargetIdSet=In der Quelle wurden keine Ziel Ids vergeben.
TopographyChecker.source.noTargetIdAndNoSpawn=In der Quelle wurden keine Ziel Ids vergeben, aber die Spawn Anzahl ist bei 0.
TopographyChecker.source.idNotUnique=Quellen haben keine eindeutige ID.
TopographyChecker.source.overlapWithObstacle=Quelle und Hinderniss \u00fcberlappen sich. Dies kann f\u00fcrt zuf\u00fchren, dass Personen im Hinderniss erzeugt werden.
TopographyChecker.stairs.wrongTreadDim=Stufentiefe ist au\u00dferhalb des Definitionsbereichs.
TopographyChecker.target.unused=Das Ziel wird von keiner Quelle verwendet. Entferne das Ziel um die Performance zu erh\u00f6hen
TopographyChecker.pedestrian.speedsetup=speedDistributionMean muss im Bereich min/max liegen.
TopographyChecker.pedestrian.speedNotLogical=Min or Max Geschwindigkeit ist gr\u00f6\u00dfer als Weltrekord.
TopographyChecker.pedestrian.speedIsNegative=Min or Max Geschwindigkeit ist negativ.
#TopographyChecker.obstacles.overlap=
#TopographyChecker.source.overlap=
#TopographyChecker.target.overlap=
#TopographyChecker.stairs.overlap=
TopographyChecker.overlap.stair.stair=Treppen d\u00fcrfen nicht \u00fcberlappen.
TopographyChecker.overlap.target.stair=Ein Ziel und eine Treppen \u00fcberlappen im Scenario.
TopographyChecker.overlap.source.stair=Eine Quelle und eine Treppe \u00fcberlappen im Scenario.
TopographyChecker.overlap.source.target=Eine Quelle und eine Ziel \u00fcberappen im Scenario.
TopographyChecker.overlap.source.source=Zwei Quellen \u00fcberlappen. Wenn useFreeSpaceOnly nicht gesetzt ist kann dies zu \u00fcberlappungen von Pedestrians f\u00fchren.
TopographyChecker.overlap.obstacle.stairs.err=Treppe ist komplett in einem Hinderniss eingeschossen.
TopographyChecker.overlap.obstacle.stairs.warn=Treppe hat ein Hinderiss in sich. Dies ist m\u00f6glich aber nicht getestet. Wenn m\u00f6glich in zwei treppen aufteilen.
TopographyChecker.overlap.obstacle.target.err=Ziel ist komplett in einem Hinderniss eingeschlossen
TopographyChecker.overlap.obstacle.target.warn=Ziel hat ein Hinderniss in sich. Dies ist m\u00f6glich reduziert aber die tats\u00c4chliche Fl\u00c4che des Ziels.
TopographyChecker.overlap.obstacle.source=Hinderniss \u00fcberdeckt Quelle. Die f\u00fchrt dazu, dass Pedestrians im Hinderniss erzeugt werden.
TopographyChecker.overlap.obstacle.obstacle=Zwei identische bzw. eingeschlossene Obstacles gefunden. L\u00f6sche eins f\u00fcr bessere Performance
# tab titles Topography creator / postvis
Tab.Simulation.title=Simulation
......
package org.vadere.gui.topographycreator.control;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionTopographyMakroMenu extends TopographyAction {
public ActionTopographyMakroMenu(String name, ImageIcon icon, IDrawPanelModel<?> panelModel) {
super(name, icon, panelModel);
}
@Override
public void actionPerformed(ActionEvent e) {
getScenarioPanelModel().getTopography().generateUniqueIdIfNotSet();
getScenarioPanelModel().notifyObservers();
}
}
......@@ -30,6 +30,7 @@ import org.vadere.gui.topographycreator.control.ActionSelectSelectShape;
import org.vadere.gui.topographycreator.control.ActionSwitchCategory;
import org.vadere.gui.topographycreator.control.ActionSwitchSelectionMode;
import org.vadere.gui.topographycreator.control.ActionTopographyCheckerMenu;
import org.vadere.gui.topographycreator.control.ActionTopographyMakroMenu;
import org.vadere.gui.topographycreator.control.ActionUndo;
import org.vadere.gui.topographycreator.control.ActionZoomIn;
import org.vadere.gui.topographycreator.control.ActionZoomOut;
......@@ -309,6 +310,12 @@ public class TopographyWindow extends JPanel {
new ImageIcon(Resources.class.getResource("/icons/topography_icon.png")),
panelModel, selectShape);
/* Makros */
ActionTopographyMakroMenu actionTopographyMakroMenu =
new ActionTopographyMakroMenu("TopographyMakros",
new ImageIcon(Resources.class.getResource("/icons/setting32x32.png")),
panelModel);
/* Topography checker*/
ActionTopographyCheckerMenu actionTopographyCheckerMenu =
new ActionTopographyCheckerMenu("TopographyChecker", panelModel, jsonValidIndicator);
......@@ -350,6 +357,7 @@ public class TopographyWindow extends JPanel {
addActionToToolbar(toolbar, undoAction, "TopographyCreator.btnUndo.tooltip");
addActionToToolbar(toolbar, redoAction, "TopographyCreator.btnRedo.tooltip");
toolbar.add(Box.createHorizontalGlue());
addActionToToolbar(toolbar, actionTopographyMakroMenu, "TopographyCreator.btnMakro.tooltip");
addActionToToolbar(toolbar, actionTopographyCheckerMenu, "TopographyCreator.btnChecker.tooltip");
toolbar.add(infoButton);
infoButton.setToolTipText("About");
......
......@@ -12,13 +12,23 @@ public enum TopographyCheckerReason {
SOURCE_NO_TARGET_ID_SET("TopographyChecker.source.noTargetIdSet"),
SOURCE_NO_TARGET_ID_NO_SPAWN("TopographyChecker.source.noTargetIdAndNoSpawn"),
SOURCE_ID_NOT_UNIQUE("TopographyChecker.source.idNotUnique"),
SOURCE_OVERLAP_WITH_OBSTACLE("TopographyChecker.source.overlapWithObstacle"),
STAIRS_TREAD_DIM_WRONG("TopographyChecker.stairs.wrongTreadDim"),
OVERLAP_STAIR_STAIR("TopographyChecker.overlap.stair.stair"),
OVERLAP_TARGET_STAIR("TopographyChecker.overlap.target.stair"),
OVERLAP_SOURCE_STAIR("TopographyChecker.overlap.source.stair"),
OVERLAP_SOURCE_TARGET("TopographyChecker.overlap.source.target"),
OVERLAP_SOURCE_SOURCE("TopographyChecker.overlap.source.source"),
OVERLAP_OBSTACLE_STAIRS_ERR("TopographyChecker.overlap.obstacle.stairs.err"),
OVERLAP_OBSTACLE_STAIRS_WARN("TopographyChecker.overlap.obstacle.stairs.warn"),
OVERLAP_OBSTACLE_TARGET_ERR("TopographyChecker.overlap.obstacle.target.err"),
OVERLAP_OBSTACLE_TARGET_WARN("TopographyChecker.overlap.obstacle.target.warn"),
OVERLAP_OBSTACLE_SOURCE("TopographyChecker.overlap.obstacle.source"),
OVERLAP_OBSTACLE_OBSTACLE("TopographyChecker.overlap.obstacle.obstacle"),
OVERLAP_OBSTACLE_OBSTACLE_ENCLOSE("TopographyChecker.overlap.obstacle.obstacle.enclose"),
TARGET_UNUSED("TopographyChecker.target.unused"),
OBSTACLES_OVERLAP("TopographyChecker.obstacles.overlap"),
SOURCE_OVERLAP("TopographyChecker.source.overlap"),
TARGET_OVERLAP("TopographyChecker.target.overlap"),
STAIRS_OVERLAP("TopographyChecker.stairs.overlap"),
PEDESTRIAN_SPEED_SETUP("TopographyChecker.pedestrian.speedsetup"),
PEDESTRIAN_SPEED_NOT_LOGICAL("TopographyChecker.pedestrian.speedNotLogical"),
PEDESTRIAN_SPEED_NEGATIVE("TopographyChecker.pedestrian.speedIsNegative");
......
......@@ -2,6 +2,7 @@ package org.vadere.simulator.util;
import org.apache.commons.math3.util.Pair;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.vadere.state.attributes.scenario.AttributesObstacle;
import org.vadere.state.attributes.scenario.builder.AttributesAgentBuilder;
......@@ -15,7 +16,9 @@ import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VCircle;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
......@@ -105,6 +108,20 @@ public class TopographyCheckerTest {
out.forEach(m -> assertEquals(TopographyCheckerReason.SOURCE_ID_NOT_UNIQUE, m.getReason()));
}
@Test
@Ignore
public void TestOverlap(){
VShape a = new VRectangle(0, 0, 10, 10);
VShape b = new VRectangle(1, 1, 1, 1);
Area aa = new Area(a);
Area bb = new Area(b);
System.out.println(a.containsShape(b));
System.out.println(a.containsShape(a));
System.out.println(b.containsShape(a));
System.out.println(b.containsShape(b));
}
/**
* There should be only unique ids
*/
......@@ -245,7 +262,7 @@ public class TopographyCheckerTest {
Topography topography = builder.build();
TopographyChecker checker = new TopographyChecker(topography);
List<TopographyCheckerMessage> out = checker.checkSourceObstacleOverlap();
List<TopographyCheckerMessage> out = checker.checkOverlap((type, type2) -> true);
hasNoElement(out);
}
......@@ -278,11 +295,11 @@ public class TopographyCheckerTest {
Topography topography = builder.build();
TopographyChecker checker = new TopographyChecker(topography);
List<TopographyCheckerMessage> out = checker.checkSourceObstacleOverlap();
List<TopographyCheckerMessage> out = checker.checkOverlap((type, type2) -> true);
TopographyCheckerMessage msg = hasOneElement(out);
isErrorMsg(msg);
assertEquals(TopographyCheckerReason.SOURCE_OVERLAP_WITH_OBSTACLE, msg.getReason());
assertEquals(TopographyCheckerReason.OVERLAP_OBSTACLE_SOURCE, msg.getReason());
assertEquals(testSource, msg.getMsgTarget().getTargets().get(0));
assertEquals(testObstacle, msg.getMsgTarget().getTargets().get(1));
......
......@@ -33,6 +33,11 @@ public class AttributesObstacle extends AttributesEmbedShape {
return id;
}
public void setId(int id) {
checkSealed();
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
......
......@@ -216,4 +216,9 @@ public class AttributesSource extends AttributesEmbedShape {
checkSealed();
this.dynamicElementType = dynamicElementType;
}
public void setId(int id) {
checkSealed();
this.id = id;
}
}
......@@ -65,4 +65,8 @@ public class AttributesStairs extends AttributesEmbedShape {
return upwardDirection;
}
public void setId(int id) {
checkSealed();
this.id = id;
}
}
......@@ -144,4 +144,8 @@ public class AttributesTarget extends AttributesEmbedShape {
this.deletionDistance = reachedDistance;
}
public void setId(int id) {
checkSealed();
this.id = id;
}
}
......@@ -30,6 +30,10 @@ public class Obstacle extends ScenarioElement {
return attributes.getId();
}
public void setId(int id){
((AttributesObstacle)getAttributes()).setId(id);
}
@Override
public int hashCode() {
final int prime = 31;
......
......@@ -7,7 +7,19 @@ import org.vadere.util.geometry.shapes.VShape;
public abstract class ScenarioElement {
public abstract VShape getShape();
public boolean overlapWith(ScenarioElement element){
return getShape().intersects(element.getShape());
}
public boolean totalOverlapWith(ScenarioElement element){
return getShape().sameArea(element.getShape());
}
public boolean enclosesScenarioElement(ScenarioElement element){
return getShape().containsShape(element.getShape());
}
public abstract void setShape(VShape newShape);
public abstract int getId();
......
......@@ -3,6 +3,7 @@ package org.vadere.state.scenario;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
......@@ -465,4 +466,49 @@ public class Topography {
allOtherAttributes.forEach(a -> a.seal());
}
public void generateUniqueIdIfNotSet(){
Set<Integer> usedIds = sources.stream().map(Source::getId).collect(Collectors.toSet());
usedIds.addAll(targets.stream().map(Target::getId).collect(Collectors.toSet()));
usedIds.addAll(obstacles.stream().map(Obstacle::getId).collect(Collectors.toSet()));
usedIds.addAll(stairs.stream().map(Stairs::getId).collect(Collectors.toSet()));
sources.stream()
.filter(s -> s.getId() == Attributes.ID_NOT_SET)
.forEach(s -> s.getAttributes().setId(nextIdNotInSet(usedIds)));
targets.stream()
.filter(s -> s.getId() == Attributes.ID_NOT_SET)
.forEach(s -> s.getAttributes().setId(nextIdNotInSet(usedIds)));
obstacles.stream()
.filter(s -> s.getId() == Attributes.ID_NOT_SET)
.forEach(s -> s.setId(nextIdNotInSet(usedIds)));
stairs.stream()
.filter(s -> s.getId() == Attributes.ID_NOT_SET)
.forEach(s -> s.getAttributes().setId(nextIdNotInSet(usedIds)));
}
private int nextIdNotInSet(Set<Integer> usedIDs){
int newId = 1;
while (usedIDs.contains(newId)){
newId++;
}
usedIDs.add(newId);
return newId;
}
public ArrayList<ScenarioElement> getAllScenarioElements(){
ArrayList<ScenarioElement> all = new ArrayList<>((obstacles.size() + stairs.size() + targets.size() + sources.size() + boundaryObstacles.size()));
all.addAll(obstacles);
all.addAll(stairs);
all.addAll(targets);
all.addAll(sources);
all.addAll(boundaryObstacles);
return all;
}
}
......@@ -35,4 +35,19 @@ public interface VShape extends Shape, Cloneable {
thisShape.subtract(otherShape);
return !thisShape.equals(thisShapeCpy);
}
default boolean sameArea(VShape shape){
Area thisShape = new Area(this);
Area otherShape = new Area(shape);
thisShape.subtract(otherShape);
return thisShape.isEmpty();
}
default boolean containsShape(VShape otherShape){
Area thisArea = new Area(this);
Area otherArea = new Area(otherShape);
thisArea.intersect(otherArea);
return thisArea.equals(otherArea);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment