source: osm/applications/editors/josm/plugins/indoor_sweepline/src/indoor_sweepline/IndoorSweeplineModel.java@ 32109

Last change on this file since 32109 was 32109, checked in by roland, 8 years ago

Fixed various bugs (see git repo)

File size: 9.1 KB
Line 
1package indoor_sweepline;
2
3import java.util.List;
4import java.util.Vector;
5import javax.swing.DefaultComboBoxModel;
6import org.openstreetmap.josm.Main;
7import org.openstreetmap.josm.data.coor.LatLon;
8import org.openstreetmap.josm.data.osm.DataSet;
9import org.openstreetmap.josm.gui.layer.OsmDataLayer;
10
11
12/* TODO:
13- focus to useful table entry after cell edit
14- keyboard shortcuts
15*/
16
17
18public class IndoorSweeplineModel
19{
20 public enum Type
21 {
22 CORRIDOR,
23 PLATFORM
24 };
25
26
27 public IndoorSweeplineModel(OsmDataLayer activeLayer, LatLon center)
28 {
29 target = new ModelGeography(activeLayer.data, center);
30
31 beams = new Vector<Beam>();
32 strips = new Vector<Strip>();
33 type = Type.CORRIDOR;
34 level = "-1";
35 addBeam();
36 addStrip();
37 addBeam();
38
39 structureBox = new DefaultComboBoxModel<String>();
40 }
41
42
43 private ModelGeography target;
44
45
46 public void addBeam()
47 {
48 CorridorPart.ReachableSide side = CorridorPart.ReachableSide.LEFT;
49 if (beams.size() == 0)
50 side = CorridorPart.ReachableSide.RIGHT;
51
52 double width = 10.;
53 if (beams.size() > 0)
54 {
55 width = 0;
56 for (CorridorPart part : beams.elementAt(beams.size() - 1).getBeamParts())
57 width += part.width;
58 }
59
60 double offset = 0;
61 for (int i = 0; i < strips.size(); ++i)
62 offset += strips.elementAt(i).width;
63
64 if (strips.size() == 0)
65 {
66 Vector<Double> blueprint = new Vector<Double>();
67 blueprint.addElement(0.);
68 blueprint.addElement(10.);
69 beams.add(new Beam(blueprint, 0., side));
70 }
71 else
72 beams.add(new Beam(strips.elementAt(strips.size()-1).lhs,
73 beams.elementAt(beams.size()-1).getBeamOffset(), side));
74
75 if (strips.size() > 0)
76 strips.elementAt(beams.size()-2).rhs = beams.elementAt(beams.size()-1).leftHandSideStrips();
77
78 updateOsmModel();
79 }
80
81
82 public void addStrip()
83 {
84 strips.add(new Strip(target.getDataSet()));
85 if (beams.size() > 1)
86 {
87 beams.elementAt(beams.size()-1).setDefaultSide(CorridorPart.ReachableSide.ALL);
88 strips.elementAt(strips.size()-2).rhs = beams.elementAt(strips.size()-1).leftHandSideStrips();
89 }
90 strips.elementAt(strips.size()-1).lhs = beams.elementAt(strips.size()-1).rightHandSideStrips();
91
92 updateOsmModel();
93 }
94
95
96 public int leftRightCount()
97 {
98 return beams.size() + strips.size();
99 }
100
101
102 public DefaultComboBoxModel<String> structures()
103 {
104 structureBox.removeAllElements();
105 double offset = 0;
106 for (int i = 0; i < strips.size(); ++i)
107 {
108 if (i < beams.size())
109 structureBox.addElement(Double.toString(offset));
110 structureBox.addElement(Double.toString(offset) + " - "
111 + Double.toString(offset + strips.elementAt(i).width));
112 offset += strips.elementAt(i).width;
113 }
114 if (strips.size() < beams.size())
115 structureBox.addElement(Double.toString(offset));
116
117 return structureBox;
118 }
119
120
121 public Strip getStrip(int index)
122 {
123 return strips.elementAt(index / 2);
124 }
125
126
127 public double getStripWidth(int index)
128 {
129 return strips.elementAt(index / 2).width;
130 }
131
132
133 public void setStripWidth(int index, double value)
134 {
135 strips.elementAt(index / 2).width = value;
136
137 updateOsmModel();
138 }
139
140
141 public double getBeamOffset(int index)
142 {
143 return beams.elementAt(index / 2).getBeamOffset();
144 }
145
146 public void setBeamOffset(int index, double beamOffset)
147 {
148 beams.elementAt(index / 2).setBeamOffset(beamOffset);
149 updateOsmModel();
150 }
151
152
153 public List<CorridorPart> getBeamParts(int index)
154 {
155 return beams.elementAt(index / 2).getBeamParts();
156 }
157
158
159 public void addCorridorPart(int beamIndex, boolean append, double value)
160 {
161 beams.elementAt(beamIndex / 2).addCorridorPart(append, value);
162 if (beamIndex / 2 > 0)
163 strips.elementAt(beamIndex / 2 - 1).rhs = beams.elementAt(beamIndex / 2).leftHandSideStrips();
164 if (beamIndex / 2 < strips.size())
165 strips.elementAt(beamIndex / 2).lhs = beams.elementAt(beamIndex / 2).rightHandSideStrips();
166
167 updateOsmModel();
168 }
169
170
171 public void setCorridorPartWidth(int beamIndex, int partIndex, double value)
172 {
173 beams.elementAt(beamIndex / 2).setCorridorPartWidth(partIndex, value);
174 if (beamIndex / 2 > 0)
175 strips.elementAt(beamIndex / 2 - 1).rhs = beams.elementAt(beamIndex / 2).leftHandSideStrips();
176 if (beamIndex / 2 < strips.size())
177 strips.elementAt(beamIndex / 2).lhs = beams.elementAt(beamIndex / 2).rightHandSideStrips();
178
179 updateOsmModel();
180 }
181
182
183 public void setCorridorPartType(int beamIndex, int partIndex, CorridorPart.Type type)
184 {
185 if (beamIndex % 2 == 0)
186 {
187 beams.elementAt(beamIndex / 2).setCorridorPartType(partIndex, type);
188 if (beamIndex / 2 > 0)
189 strips.elementAt(beamIndex / 2 - 1).rhs = beams.elementAt(beamIndex / 2).leftHandSideStrips();
190 if (beamIndex / 2 < strips.size())
191 strips.elementAt(beamIndex / 2).lhs = beams.elementAt(beamIndex / 2).rightHandSideStrips();
192 }
193 else
194 {
195 if (type != CorridorPart.Type.PASSAGE && type != CorridorPart.Type.VOID)
196 strips.elementAt(beamIndex / 2).setCorridorPartType(partIndex, type);
197 }
198
199 updateOsmModel();
200 }
201
202
203 public void setCorridorPartSide(int beamIndex, int partIndex, CorridorPart.ReachableSide side)
204 {
205 beams.elementAt(beamIndex / 2).setCorridorPartSide(partIndex, side);
206 if (beamIndex / 2 > 0)
207 strips.elementAt(beamIndex / 2 - 1).rhs = beams.elementAt(beamIndex / 2).leftHandSideStrips();
208 if (beamIndex / 2 < strips.size())
209 strips.elementAt(beamIndex / 2).lhs = beams.elementAt(beamIndex / 2).rightHandSideStrips();
210
211 updateOsmModel();
212 }
213
214
215 public Type getType()
216 {
217 return type;
218 }
219
220 public void setType(Type type)
221 {
222 this.type = type;
223 updateOsmModel();
224 }
225
226
227 public String getLevel()
228 {
229 return level;
230 }
231
232 public void setLevel(String level)
233 {
234 this.level = level;
235 updateOsmModel();
236 }
237
238
239 private Vector<Beam> beams;
240 private Vector<Strip> strips;
241 private Type type;
242 private String level;
243
244 DefaultComboBoxModel<String> structureBox;
245
246
247 private void updateOsmModel()
248 {
249 distributeWays();
250 Main.map.mapView.repaint();
251 }
252
253
254 public class SweepPolygonCursor
255 {
256 public SweepPolygonCursor(int stripIndex, int partIndex)
257 {
258 this.stripIndex = stripIndex;
259 this.partIndex = partIndex;
260 }
261
262 public boolean equals(SweepPolygonCursor rhs)
263 {
264 return rhs != null
265 && stripIndex == rhs.stripIndex && partIndex == rhs.partIndex;
266 }
267
268 public int stripIndex;
269 public int partIndex;
270 }
271
272
273 private void distributeWays()
274 {
275 target.startGeographyBuild(beams, strips);
276
277 Vector<Vector<Boolean>> stripRefs = new Vector<Vector<Boolean>>();
278 for (Strip strip : strips)
279 {
280 Vector<Boolean> refs = new Vector<Boolean>();
281 if (strip.lhs.size() < strip.rhs.size())
282 refs.setSize(strip.rhs.size());
283 else
284 refs.setSize(strip.lhs.size());
285 stripRefs.add(refs);
286 }
287
288 Boolean truePtr = new Boolean(true);
289 for (int i = 0; i < stripRefs.size(); ++i)
290 {
291 Vector<Boolean> refs = stripRefs.elementAt(i);
292 for (int j = 0; j < refs.size(); ++j)
293 {
294 if (refs.elementAt(j) == null)
295 {
296 target.startWay();
297
298 SweepPolygonCursor cursor = new SweepPolygonCursor(i, j);
299
300 boolean toTheLeft = true;
301 while (stripRefs.elementAt(cursor.stripIndex).elementAt(cursor.partIndex) == null)
302 {
303 stripRefs.elementAt(cursor.stripIndex).setElementAt(truePtr, cursor.partIndex);
304 if (toTheLeft && cursor.partIndex < strips.elementAt(cursor.stripIndex).lhs.size())
305 {
306 target.appendCorridorPart(
307 strips.elementAt(cursor.stripIndex).partAt(cursor.partIndex),
308 strips.elementAt(cursor.stripIndex).geographyAt(cursor.partIndex),
309 cursor.stripIndex,
310 beams.elementAt(cursor.stripIndex).getBeamPartIndex(!toTheLeft, cursor.partIndex),
311 level);
312 toTheLeft = beams.elementAt(cursor.stripIndex).appendNodes(
313 cursor, toTheLeft, target.beamAt(cursor.stripIndex), level);
314 }
315 else if (!toTheLeft && cursor.partIndex < strips.elementAt(cursor.stripIndex).rhs.size())
316 {
317 target.appendCorridorPart(
318 strips.elementAt(cursor.stripIndex).partAt(cursor.partIndex),
319 strips.elementAt(cursor.stripIndex).geographyAt(cursor.partIndex),
320 cursor.stripIndex + 1,
321 beams.elementAt(cursor.stripIndex + 1).getBeamPartIndex(!toTheLeft, cursor.partIndex),
322 level);
323 toTheLeft = beams.elementAt(cursor.stripIndex + 1).appendNodes(
324 cursor, toTheLeft, target.beamAt(cursor.stripIndex + 1), level);
325 }
326 else
327 toTheLeft = appendUturn(cursor, toTheLeft);
328 }
329
330 target.finishWay(strips.elementAt(cursor.stripIndex), cursor.partIndex, j % 2 == 0, level);
331 }
332 }
333 }
334
335 target.finishGeographyBuild(type, level);
336 }
337
338
339 private boolean appendUturn(SweepPolygonCursor cursor, boolean toTheLeft)
340 {
341 Strip strip = strips.elementAt(cursor.stripIndex);
342 target.appendUturnNode(strip, cursor.partIndex, cursor.stripIndex,
343 beams.elementAt(toTheLeft ? cursor.stripIndex + 1 : cursor.stripIndex).
344 getBeamPartIndex(toTheLeft, cursor.partIndex),
345 toTheLeft, level);
346
347 if (cursor.partIndex % 2 == 0)
348 ++cursor.partIndex;
349 else
350 --cursor.partIndex;
351 return !toTheLeft;
352 }
353}
Note: See TracBrowser for help on using the repository browser.