Commit 7bfc54e6 authored by hm-schuhba1's avatar hm-schuhba1

178 measurement area

parent fc320f3f
......@@ -314,11 +314,14 @@ TopographyCreator.btnInsertTarget.tooltip=Target
TopographyCreator.btnInsertAbsorbingArea.tooltip=Absorbing Area
TopographyCreator.btnInsertSource.tooltip=Source
TopographyCreator.btnInsertStairs.tooltip=Stairs
TopographyCreator.btnInsertMeasurementArea.tooltip=MeasurmentArea
TopographyCreator.btnErase.tooltip=Eraser
TopographyCreator.btnConvexHull.label=Convex Hull
TopographyCreator.btnSimplePolygon.label=Simple Polygon
TopographyCreator.btnCircle.label=Circle
TopographyCreator.btnLine.label=Line
TopographyCreator.btnRectangle.label=Rectangle
TopographyCreator.btnSubtractMeasurementArea.label=Subtract Obstacle from Area
TopographyCreator.btnChecker.tooltip=Show Topography Checker Messages
TopographyCreator.btnGenerateIds.tooltip=Generate missing Ids for sources, targets, ...
......
......@@ -309,12 +309,15 @@ TopographyCreator.btnTranslation.tooltip=Topographie verschieben
TopographyCreator.btnElementTranslation.tooltip=Elemente der Topography verschieben
TopographyCreator.btnInsertSource.tooltip=Quelle
TopographyCreator.btnInsertStairs.tooltip=Treppen
TopographyCreator.btnInsertMeasurementArea.tooltip=Messbereich
TopographyCreator.btnErase.tooltip=Radierer
select_shape_tooltip=Form ausw\u00e4hlen
TopographyCreator.btnConvexHull.label=Convexe H\u00fclle
TopographyCreator.btnSimplePolygon.label=Einfaches Polygon
TopographyCreator.btnCircle.label=Kreis
TopographyCreator.btnLine.label=Linie
TopographyCreator.btnRectangle.label=Rechteck
TopographyCreator.btnSubtractMeasurementArea.label=Subtrahiere Hinderniss von Messfl\u00e4che
TopographyCreator.btnChecker.tooltip=Topography Linter Nachrichten
TopographyCreator.btnGenerateIds.tooltip=Erzeuge fehlende Ids f\u00fcr Quellen, Ziele, ...
......
......@@ -10,6 +10,8 @@ public class DefaultConfig {
private Color densityColor = Color.RED;
private Color stairColor = new Color(0.5058823529411764f, 0.4470588235294118f, 0.6980392156862745f);
private Color pedestrianColor = new Color(0.2980392156862745f, 0.4470588235294118f, 0.7901960784313725f);
private Color measurementAreaColor = Color.RED;
private int measurementAreaAlpha = 140;
private boolean changed = false;
public DefaultConfig() {}
......@@ -20,6 +22,8 @@ public class DefaultConfig {
this.absorbingAreaColor = config.absorbingAreaColor;
this.densityColor = config.densityColor;
this.obstacleColor = config.obstacleColor;
this.measurementAreaColor = config.measurementAreaColor;
this.measurementAreaAlpha = config.measurementAreaAlpha;
this.stairColor = config.stairColor;
this.changed = config.changed;
}
......@@ -46,6 +50,22 @@ public class DefaultConfig {
setChanged();
}
public Color getMeasurementAreaColor() {
return measurementAreaColor;
}
public void setMeasurementAreaColor(Color measurementAreaColor) {
this.measurementAreaColor = measurementAreaColor;
}
public int getMeasurementAreaAlpha() {
return measurementAreaAlpha;
}
public void setMeasurementAreaAlpha(int measurementAreaAlpha) {
this.measurementAreaAlpha = measurementAreaAlpha;
}
public Color getSourceColor() {
return sourceColor;
}
......
......@@ -23,6 +23,7 @@ public class DefaultSimulationConfig extends DefaultConfig {
private boolean showAbsorbingAreas = true;
private boolean showSources = true;
private boolean showObstacles = true;
private boolean showMeasurementArea = true;
private boolean showStairs = true;
private boolean showPedestrians = true;
private boolean showWalkdirection = false;
......@@ -154,6 +155,15 @@ public class DefaultSimulationConfig extends DefaultConfig {
setChanged();
}
public boolean isShowMeasurementArea(){
return showMeasurementArea;
}
public void setShowMeasurementArea(boolean showMeasurementArea){
this.showMeasurementArea = showMeasurementArea;
setChanged();
}
public boolean isShowStairs() {
return showStairs;
}
......
......@@ -5,6 +5,7 @@ import org.vadere.gui.components.model.IDefaultModel;
import org.vadere.meshing.mesh.gen.MeshRenderer;
import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.state.scenario.Agent;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Stairs;
import org.vadere.util.data.cellgrid.IPotentialPoint;
......@@ -230,6 +231,30 @@ public abstract class DefaultRenderer {
graphics.setColor(tmpColor);
}
protected void renderMeasurementAreas(final Iterable<? extends ScenarioElement> elements, final Graphics2D g,
final Color color){
for (ScenarioElement e : elements){
renderMeasurementArea(e, g, color);
}
}
protected void renderMeasurementArea(ScenarioElement element, final Graphics2D graphics, Color color){
final Color tmpColor = graphics.getColor();
MeasurementArea area = (MeasurementArea) element;
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(),
defaultModel.getConfig().getMeasurementAreaAlpha()));
if (area.getShape() instanceof VPolygon){
VPolygon p = (VPolygon) area.getShape();
if (p.getPoints().size() == 2){
graphics.setStroke(new BasicStroke(3*getLineWidth()));
graphics.draw(p);
}
}
fill(element.getShape(), graphics);
graphics.setColor(tmpColor);
}
protected void renderSelectionShape(final Graphics2D graphics) {
graphics.setColor(defaultModel.getMouseSelectionMode().getSelectionColor());
graphics.setStroke(new BasicStroke(getSelectionBorderLineWidth()));
......
......@@ -79,6 +79,10 @@ public abstract class SimulationRenderer extends DefaultRenderer {
renderScenarioElement(model.getTopography().getObstacles(), graphics, model.config.getObstacleColor());
}
if (model.config.isShowMeasurementArea()){
renderMeasurementAreas(model.getTopography().getMeasurementAreas(), graphics, model.config.getMeasurementAreaColor());
}
if (model.config.isShowStairs()) {
renderStairs(model.getTopography().getStairs(), graphics, model.config.getStairColor());
}
......
......@@ -18,23 +18,35 @@ public class ActionOpenDrawOptionMenu extends TopographyAction {
private static final long serialVersionUID = 2337382087222665146L;
private final TopographyAction action;
private final Component parent;
private final List<Action> actions;
private final List<Action> drawActions;
private final List<Action> miscActions;
private JPopupMenu menu;
public ActionOpenDrawOptionMenu(final String name, final ImageIcon icon, final IDrawPanelModel panelModel,
final TopographyAction action, final Component parent, final List<Action> actions) {
final TopographyAction action, final Component parent, final List<Action> drawActions, final List<Action> miscActions) {
super(name, icon, panelModel);
this.action = action;
this.parent = parent;
this.actions = actions;
this.drawActions = drawActions;
this.miscActions = miscActions;
}
public ActionOpenDrawOptionMenu(final String name, final ImageIcon icon, final IDrawPanelModel panelModel,
final TopographyAction action, final Component parent, final List<Action> drawActions) {
this(name, icon, panelModel, action, parent, drawActions, null);
}
public ActionOpenDrawOptionMenu(final String name, final IDrawPanelModel panelModel, final TopographyAction action,
final Component parent, final List<Action> actions) {
final Component parent, final List<Action> actions, final List<Action> miscActions) {
super(name, panelModel);
this.action = action;
this.parent = parent;
this.actions = actions;
this.drawActions = actions;
this.miscActions = null;
}
public ActionOpenDrawOptionMenu(final String name, final IDrawPanelModel panelModel, final TopographyAction action,
final Component parent, final List<Action> actions) {
this(name, panelModel, action, parent, actions, null);
}
@Override
......@@ -46,9 +58,13 @@ public class ActionOpenDrawOptionMenu extends TopographyAction {
public void run() {
if (menu == null) {
menu = new JPopupMenu();
for (Action action : actions) {
for (Action action : drawActions) {
menu.add(action);
}
if (miscActions != null){
menu.addSeparator();
miscActions.forEach(a -> menu.add(a));
}
}
menu.show(parent, 0, parent.getHeight());
}
......
package org.vadere.gui.topographycreator.control;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.Obstacle;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VShape;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.undo.UndoableEdit;
import javax.swing.undo.UndoableEditSupport;
/**
*
*/
public class ActionSubtractMeasurementArea extends TopographyAction {
private final UndoableEditSupport undoSupport;
public ActionSubtractMeasurementArea(String name, ImageIcon icon, IDrawPanelModel panelModel,
UndoableEditSupport undoSupport) {
super(name, icon, panelModel);
this.undoSupport = undoSupport;
}
@Override
public void actionPerformed(ActionEvent e) {
List<Obstacle> obstacles = new ArrayList<>(getScenarioPanelModel().getObstacles());
List<MeasurementArea> before = new ArrayList<>(getScenarioPanelModel().getMeasurementAreas());
for (MeasurementArea measurementAreaOld : before) {
List<VShape> intersectedObstecales = obstacles.stream()
.map(Obstacle::getShape)
.filter(s -> s.intersects(measurementAreaOld.getShape()))
.collect(Collectors.toList());
if (intersectedObstecales.size() > 0 ){
// remove overlapping MeasurementArea
getScenarioPanelModel().removeElement(measurementAreaOld);
VShape shape = measurementAreaOld.getShape();
List<VPoint> points = shape.getPath();
Area thisArea = new Area(shape);
// subtract portions of the measurement area covered by an obstacle.
for (VShape intersectedObstecale : intersectedObstecales) {
Area otherArea = new Area(intersectedObstecale);
thisArea.subtract(otherArea);
}
// add new MeasurementArea
MeasurementArea measurementAreaNew = new MeasurementArea();
measurementAreaNew.setId(measurementAreaOld.getId());
measurementAreaNew.setShape(getPolygonPoints(thisArea));
getScenarioPanelModel().addShape(measurementAreaNew);
}
}
List<MeasurementArea> after = new ArrayList<>(getScenarioPanelModel().getMeasurementAreas());
UndoableEdit edit = new EditSubtractMeasurementArea(getScenarioPanelModel(), before, after);
undoSupport.postEdit(edit);
getScenarioPanelModel().notifyObservers();
}
private VPolygon getPolygonPoints(Shape shape){
List<VPoint> resultList = new ArrayList<>(); // use ArrayList for better index retrieval
PathIterator iterator = shape.getPathIterator(null);
Path2D.Double p = new Path2D.Double(shape);
double[] coords = new double[6];
while (!iterator.isDone()) {
int type = iterator.currentSegment(coords);
iterator.next();
if (type == PathIterator.SEG_LINETO || type == PathIterator.SEG_MOVETO ) {
resultList.add(new VPoint(coords[0], coords[1]));
}
}
return GeometryUtils.polygonFromPoints2D(resultList);
}
}
package org.vadere.gui.topographycreator.control;
import org.vadere.gui.components.control.DefaultSelectionMode;
import org.vadere.gui.components.control.IMode;
import org.vadere.gui.components.model.IDefaultModel;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.undo.UndoableEditSupport;
public class DrawLineMode extends DefaultSelectionMode {
enum DrawPathState {
START, END, ADD
}
private final UndoableEditSupport undoSupport;
private Path2D.Double path;
private Line2D.Double line;
private DrawPathState state = DrawPathState.START;
private int lineCount = 0;
private final IDrawPanelModel panelModel;
private final List<VPoint> pointList;
public DrawLineMode(final IDrawPanelModel panelModel, final UndoableEditSupport undoSupport) {
super(panelModel);
this.panelModel = panelModel;
this.undoSupport = undoSupport;
this.pointList = new ArrayList<>();
}
@Override
public void mouseDragged(MouseEvent event) {
if (SwingUtilities.isRightMouseButton(event) && state == DrawPathState.START) {
super.mouseDragged(event);
} else {
mouseMoved(event);
}
}
@Override
public void mousePressed(final MouseEvent event) {
if (SwingUtilities.isRightMouseButton(event) && state == DrawPathState.START ) {
super.mousePressed(event);
}
}
@Override
public void mouseReleased(final MouseEvent event) {
if (SwingUtilities.isRightMouseButton(event) && state == DrawPathState.START) {
super.mouseReleased(event);
}
}
@Override
public void mouseClicked(final MouseEvent event){
if (!SwingUtilities.isRightMouseButton(event)) {
if (SwingUtilities.isLeftMouseButton(event)) {
if (event.getClickCount() <= 1 && state == DrawPathState.START) {
panelModel.setMousePosition(event.getPoint());
panelModel.setStartSelectionPoint(event.getPoint());
path = new Path2D.Double(Path2D.WIND_NON_ZERO);
path.moveTo(panelModel.getMousePosition().x, panelModel.getMousePosition().y);
path.lineTo(panelModel.getMousePosition().x, panelModel.getMousePosition().y);
line = new VLine(panelModel.getMousePosition().x, panelModel.getMousePosition().y,
panelModel.getMousePosition().x, panelModel.getMousePosition().y);
panelModel.setSelectionShape(new VPolygon(path));
pointList.add(panelModel.getMousePosition());
state = DrawPathState.END;
panelModel.showSelection();
} else if (event.getClickCount() <= 1 && state == DrawPathState.END) {
path.lineTo(line.x2, line.y2);
pointList.add(new VPoint(line.x2, line.y2));
// dirty trick to see the first line!
VPolygon poly = new VPolygon(path);
poly.moveTo(line.x2, line.y2 + 0.0001 * panelModel.getScaleFactor());
panelModel.setSelectionShape(poly);
line = new Line2D.Double(panelModel.getMousePosition().x, panelModel.getMousePosition().y,
panelModel.getMousePosition().x, panelModel.getMousePosition().y);
panelModel.showSelection();
lineCount++;
path.closePath();
panelModel.setSelectionShape(new VPolygon(path));
new ActionAddElement("add element", panelModel, undoSupport).actionPerformed(null);
pointList.forEach(p -> System.out.println(p));
state = DrawPathState.START;
lineCount = 0;
pointList.clear();
panelModel.hideSelection();
}
panelModel.notifyObservers();
}
} else {
super.mouseClicked(event);
}
}
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
if (state == DrawPathState.END) {
VPoint cursorPosition = panelModel.getMousePosition();
line.x2 = cursorPosition.x;
line.y2 = cursorPosition.y;
VPolygon poly = new VPolygon(path);
poly.append(line, false);
panelModel.setSelectionShape(poly);
}
}
@Override
public IMode clone() {
return new DrawLineMode(panelModel, undoSupport);
}
}
package org.vadere.gui.topographycreator.control;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.topographycreator.model.IDrawPanelModel;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.Obstacle;
import java.util.List;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
public class EditSubtractMeasurementArea extends AbstractUndoableEdit {
private final IDrawPanelModel panelModel;
private final List<MeasurementArea> beforeMeasurementAreaList;
private final List<MeasurementArea> afterMeasurementAreaList;
public EditSubtractMeasurementArea(final IDrawPanelModel panelModel,
@NotNull final List<MeasurementArea> beforeMeasurementAreaList,
@NotNull final List<MeasurementArea> afterMeasurementAreaList) {
this.panelModel = panelModel;
this.beforeMeasurementAreaList = beforeMeasurementAreaList;
this.afterMeasurementAreaList = afterMeasurementAreaList;
}
@Override
public void undo() throws CannotUndoException {
panelModel.removeMeasurementAreaIf(predicate -> true); //remove all
beforeMeasurementAreaList.forEach(panelModel::addShape);
panelModel.notifyObservers();
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void redo() throws CannotRedoException {
panelModel.removeMeasurementAreaIf(predicate -> true); //remove all
afterMeasurementAreaList.forEach(panelModel::addShape);
panelModel.notifyObservers();
}
@Override
public boolean canRedo() {
return true;
}
@Override
public String getPresentationName() {
return "substract obstacles from measurementarea";
}
}
......@@ -14,6 +14,7 @@ import org.vadere.gui.components.control.IMode;
import org.vadere.gui.components.model.DefaultConfig;
import org.vadere.gui.components.model.IDefaultModel;
import org.vadere.simulator.projects.Scenario;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Teleporter;
......@@ -182,7 +183,11 @@ public interface IDrawPanelModel<T extends DefaultConfig> extends IDefaultModel<
void removeObstacleIf(final @NotNull Predicate<Obstacle> predicate);
void removeMeasurementAreaIf(final @NotNull Predicate<MeasurementArea> predicate);
List<Obstacle> getObstacles();
List<MeasurementArea> getMeasurementAreas();
Rectangle2D.Double getBounds();
}
......@@ -36,6 +36,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
private LinkedList<Source> sources;
private LinkedList<Target> targets;
private LinkedList<AbsorbingArea> absorbingAreas;
private LinkedList<MeasurementArea> measurementAreas;
private Teleporter teleporter;
private LinkedList<ScenarioElement> topographyElements;
private AttributesTopography attributes;
......@@ -48,6 +49,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
public TopographyBuilder() {
pedestrians = new LinkedList<>();
obstacles = new LinkedList<>();
measurementAreas = new LinkedList<>();
stairs = new LinkedList<>();
sources = new LinkedList<>();
targets = new LinkedList<>();
......@@ -74,6 +76,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
targets = new LinkedList<>(topography.getTargets());
absorbingAreas = new LinkedList<>(topography.getAbsorbingAreas());
teleporter = topography.getTeleporter();
measurementAreas = new LinkedList<>(topography.getMeasurementAreas());
} catch (SecurityException | IllegalArgumentException e) {
e.printStackTrace();
}
......@@ -86,6 +89,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
topographyElements.addAll(pedestrians);
topographyElements.addAll(sources);
topographyElements.addAll(targets);
topographyElements.addAll(measurementAreas);
topographyElements.addAll(absorbingAreas);
}
......@@ -136,6 +140,9 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
for (AgentWrapper pedestrian : pedestrians)
topography.addInitialElement(pedestrian.getAgentInitialStore());
for (MeasurementArea measurementArea : measurementAreas)
topography.addMeasurementArea(measurementArea);
topography.setTeleporter(teleporter);
return topography;
......@@ -171,6 +178,8 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
return absorbingAreas.remove(element);
case SOURCE:
return sources.remove(element);
case MEASUREMENT_AREA:
return measurementAreas.remove(element);
default:
return false;
}
......@@ -209,6 +218,11 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
this.obstacles.add(obstacle);
}
public void addMeasurementArea(final MeasurementArea area){
this.topographyElements.add(area);
this.measurementAreas.add(area);
}
public void addStairs(final Stairs stairs) {
this.topographyElements.add(stairs);
this.stairs.add(stairs);
......@@ -279,6 +293,14 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
return obstacles;
}
public List<MeasurementArea> getMeasurementAreas(){
return measurementAreas;
}
public Iterator<MeasurementArea> getMeasurementAreasIterator() {
return measurementAreas.iterator();
}
public Iterator<Stairs> getStairsIterator() {
return stairs.iterator();
}
......@@ -299,11 +321,17 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
return pedestrians.iterator();
}
public void removeObstacleIf(@NotNull final Predicate<Obstacle> predicate) {
topographyElements.removeIf(scenarioElement -> scenarioElement instanceof Obstacle && predicate.test((Obstacle)scenarioElement));
obstacles.removeIf(predicate);
}
public void removeMeasurementAreaIf(@NotNull final Predicate<MeasurementArea> predicate){
topographyElements.removeIf( scenarioElement -> scenarioElement instanceof MeasurementArea && predicate.test((MeasurementArea) scenarioElement));
measurementAreas.removeIf(predicate);
}
@Override
public Iterator<ScenarioElement> iterator() {
return topographyElements.iterator();
......
......@@ -16,6 +16,7 @@ import org.vadere.gui.components.model.DefaultConfig;
import org.vadere.gui.components.model.DefaultModel;
import org.vadere.simulator.projects.Scenario;
import org.vadere.state.attributes.scenario.AttributesTopography;
import org.vadere.state.scenario.MeasurementArea;
import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Teleporter;
......@@ -303,6 +304,9 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
case TELEPORTER:
topographyBuilder.setTeleporter((org.vadere.state.scenario.Teleporter) shape);
break;
case MEASUREMENT_AREA:
topographyBuilder.addMeasurementArea((org.vadere.state.scenario.MeasurementArea) shape);
break;
default:
throw new IllegalArgumentException("unsupported TopograpyhElementType.");
}
......@@ -373,6 +377,11 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
return topographyBuilder.getObstacles();
}
@Override
public List<MeasurementArea> getMeasurementAreas(){
return topographyBuilder.getMeasurementAreas();
}
@Override
public Double getBounds() {
return topographyBuilder.getAttributes().getBounds();
......@@ -388,6 +397,15 @@ public class TopographyCreatorModel extends DefaultModel implements IDrawPanelMo
setChanged();
}
@Override
public void removeMeasurementAreaIf(final @NotNull Predicate predicate){
if (selectedElement instanceof MeasurementArea){