Changeset 29266 in osm for applications/editors/josm/plugins/smed2/src/seamap/SeaMap.java
- Timestamp:
- 2013-02-19T18:02:02+01:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/smed2/src/seamap/SeaMap.java
r29215 r29266 10 10 package seamap; 11 11 12 import java.util.ArrayList; 13 import java.util.EnumMap; 14 import java.util.HashMap; 12 import java.util.*; 15 13 16 14 import s57.S57att; … … 23 21 public class SeaMap { 24 22 25 public enum Fflag {26 UNKN, NODE, LINE, AREA27 }28 29 23 public enum Nflag { 30 24 ANON, ISOL, CONN 31 25 } 32 33 public class Coord{26 27 public class Snode { 34 28 public double lat; 35 29 public double lon; 36 30 public Nflag flg; 37 31 38 public Coord(double ilat, double ilon) { 32 public Snode() { 33 flg = Nflag.ANON; 34 lat = 0; 35 lon = 0; 36 } 37 public Snode(double ilat, double ilon) { 38 flg = Nflag.ANON; 39 39 lat = ilat; 40 40 lon = ilon; 41 flg = Nflag.ANON; 42 } 43 public Coord(double ilat, double ilon, Nflag iflg) { 41 } 42 public Snode(double ilat, double ilon, Nflag iflg) { 44 43 lat = ilat; 45 44 lon = ilon; … … 47 46 } 48 47 } 48 49 public class Edge { 50 public boolean forward; 51 public long first; 52 public long last; 53 public ArrayList<Long> nodes; 54 public Edge() { 55 forward = true; 56 first = 0; 57 last = 0; 58 nodes = new ArrayList<Long>(); 59 } 60 } 61 62 public class Side { 63 Edge edge; 64 boolean forward; 65 public Side(Edge iedge, boolean ifwd) { 66 edge = iedge; 67 forward = ifwd; 68 } 69 } 70 71 public class Bound { 72 public boolean outer; 73 ArrayList<Side> sides; 74 public Bound() { 75 outer = true; 76 sides = new ArrayList<Side>(); 77 } 78 public Bound(Side iside, boolean irole) { 79 outer = irole; 80 sides = new ArrayList<Side>(); 81 sides.add(iside); 82 } 83 } 84 85 public class Area extends ArrayList<Bound> { 86 public Area() { 87 super(); 88 } 89 } 49 90 50 91 public class AttItem { … … 57 98 } 58 99 } 59 100 60 101 public class AttMap extends EnumMap<Att, AttItem> { 61 102 public AttMap() { … … 76 117 } 77 118 78 public class NodeTab extends HashMap<Long, Coord> {119 public class NodeTab extends HashMap<Long, Snode> { 79 120 public NodeTab() { 80 121 super(); … … 82 123 } 83 124 84 public class WayTab extends HashMap<Long,ArrayList<Long>> {85 public WayTab() {125 public class EdgeTab extends HashMap<Long, Edge> { 126 public EdgeTab() { 86 127 super(); 87 128 } 88 129 } 89 130 90 public class MpolyTab extends HashMap<Long,Long> {91 public MpolyTab() {131 public class AreaTab extends HashMap<Long, Area> { 132 public AreaTab() { 92 133 super(); 93 134 } … … 104 145 super(); 105 146 } 147 } 148 149 public enum Fflag { 150 UNKN, POINT, LINE, AREA 106 151 } 107 152 … … 112 157 public AttMap atts; 113 158 public ObjMap objs; 159 public long area; 160 public Snode centre; 114 161 115 162 Feature() { … … 119 166 atts = new AttMap(); 120 167 objs = new ObjMap(); 168 area = 0; 169 centre = new Snode(); 121 170 } 122 171 } 123 172 124 173 public NodeTab nodes; 125 public WayTab ways;126 public WayTab mpolys;127 public MpolyTab outers;174 public EdgeTab edges; 175 public AreaTab areas; 176 128 177 public FtrMap features; 129 178 public FtrTab index; 130 179 131 180 private Feature feature; 132 private ArrayList<Long> list; 181 private Edge edge; 182 private ArrayList<Long> outers; 183 private ArrayList<Long> inners; 133 184 134 185 public SeaMap() { 135 186 nodes = new NodeTab(); 136 ways = new WayTab(); 137 mpolys = new WayTab(); 138 outers = new MpolyTab(); 187 edges = new EdgeTab(); 188 areas = new AreaTab(); 139 189 feature = new Feature(); 140 190 features = new FtrMap(); … … 143 193 144 194 public void addNode(long id, double lat, double lon) { 145 nodes.put(id, new Coord(Math.toRadians(lat), Math.toRadians(lon)));195 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon))); 146 196 feature = new Feature(); 147 197 feature.refs = id; 148 feature.flag = Fflag.NODE; 149 } 150 151 public void moveNode(long id, double lat, double lon) { 152 nodes.put(id, new Coord(Math.toRadians(lat), Math.toRadians(lon))); 153 } 154 155 public void addWay(long id) { 156 list = new ArrayList<Long>(); 157 ways.put(id, list); 198 feature.flag = Fflag.POINT; 199 edge = null; 200 } 201 202 public void addEdge(long id) { 158 203 feature = new Feature(); 159 204 feature.refs = id; 160 205 feature.flag = Fflag.LINE; 161 } 162 163 public void addMpoly(long id) { 164 list = new ArrayList<Long>(); 165 mpolys.put(id, list); 206 edge = new Edge(); 207 } 208 209 public void addToEdge(long node) { 210 if (edge.first == 0) { 211 edge.first = node; 212 } else { 213 if (edge.last != 0) { 214 edge.nodes.add(edge.last); 215 } 216 edge.last = node; 217 } 218 } 219 220 public void addArea(long id) { 166 221 feature = new Feature(); 167 222 feature.refs = id; 168 223 feature.flag = Fflag.AREA; 169 } 170 171 public void addToWay(long node) { 172 list.add(node); 173 } 174 175 public void addToMpoly(long way, boolean outer) { 224 outers = new ArrayList<Long>(); 225 inners = new ArrayList<Long>(); 226 edge = null; 227 } 228 229 public void addToArea(long id, boolean outer) { 176 230 if (outer) { 177 list.add(0, way); 178 outers.put(way, feature.refs); 231 outers.add(id); 179 232 } else { 180 list.add(way); 181 } 182 } 183 184 public void tagsDone(long id) { 185 if ((feature.type != Obj.UNKOBJ) && !((feature.flag == Fflag.LINE) && (list.size() < 2))) { 186 index.put(id, feature); 187 if ((feature.flag == Fflag.LINE) && (list.size() > 0) && (list.get(0).equals(list.get(list.size() - 1)))) { 188 feature.flag = Fflag.AREA; 189 } 190 if (features.get(feature.type) == null) { 191 features.put(feature.type, new ArrayList<Feature>()); 192 } 193 features.get(feature.type).add(feature); 194 } 195 } 196 233 inners.add(id); 234 } 235 } 236 197 237 public void addTag(String key, String val) { 198 238 String subkeys[] = key.split(":"); … … 235 275 } 236 276 } 277 278 public void tagsDone(long id) { 279 if ((feature.type != Obj.UNKOBJ) && !((edge != null) && (edge.last == 0))) { 280 index.put(id, feature); 281 if (features.get(feature.type) == null) { 282 features.put(feature.type, new ArrayList<Feature>()); 283 } 284 features.get(feature.type).add(feature); 285 } 286 switch (feature.flag) { 287 case POINT: 288 Snode node = nodes.get(id); 289 if (node.flg != Nflag.CONN) { 290 node.flg = Nflag.ISOL; 291 } 292 break; 293 case LINE: 294 edges.put(id, edge); 295 nodes.get(edge.first).flg = Nflag.CONN; 296 nodes.get(edge.last).flg = Nflag.CONN; 297 if (edge.first == edge.last) { 298 feature.flag = Fflag.AREA; 299 Area area = new Area(); 300 area.add(new Bound(new Side(edge, edge.forward), true)); 301 areas.put(id, area); 302 } 303 break; 304 case AREA: 305 Area area = new Area(); 306 for (ArrayList<Long> role = outers; role != null; role = inners) { 307 while (!role.isEmpty()) { 308 Edge edge = edges.get(role.remove(0)); 309 long node1 = edge.first; 310 long node2 = edge.last; 311 Bound bound = new Bound(new Side(edge, edge.forward), (role == outers)); 312 if (node1 != node2) { 313 for (ListIterator<Long> it = role.listIterator(0); it.hasNext(); ) { 314 Edge nedge = edges.get(it.next()); 315 if (nedge.first == node2) { 316 bound.sides.add(new Side(nedge, true)); 317 it.remove(); 318 if (nedge.last == node2) break; 319 } else if (nedge.last == node2) { 320 bound.sides.add(new Side(nedge, false)); 321 it.remove(); 322 if (nedge.first == node2) break; 323 } 324 } 325 } 326 area.add(bound); 327 } 328 if (role == outers) { 329 if (area.isEmpty()) { 330 role = null; 331 } else { 332 areas.put(id, area); 333 } 334 } 335 } 336 break; 337 } 338 feature.centre = findCentroid(feature); 339 } 340 341 public double signedArea(Bound bound) { 342 Snode node; 343 double lat, lon, llon, llat; 344 lat = lon = llon = llat = 0; 345 double sigma = 0; 346 ListIterator<Long> it; 347 for (Side side : bound.sides) { 348 if (side.forward) { 349 node = nodes.get(side.edge.first); 350 lat = node.lat; 351 lon = node.lon; 352 it = side.edge.nodes.listIterator(); 353 while (it.hasNext()) { 354 llon = lon; 355 llat = lat; 356 node = nodes.get(it.next()); 357 lat = node.lat; 358 lon = node.lon; 359 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat)); 360 } 361 llon = lon; 362 llat = lat; 363 node = nodes.get(side.edge.last); 364 lat = node.lat; 365 lon = node.lon; 366 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat)); 367 } else { 368 node = nodes.get(side.edge.last); 369 lat = node.lat; 370 lon = node.lon; 371 it = side.edge.nodes.listIterator(side.edge.nodes.size()); 372 while (it.hasPrevious()) { 373 llon = lon; 374 llat = lat; 375 node = nodes.get(it.previous()); 376 lat = node.lat; 377 lon = node.lon; 378 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat)); 379 } 380 llon = lon; 381 llat = lat; 382 node = nodes.get(side.edge.first); 383 lat = node.lat; 384 lon = node.lon; 385 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat)); 386 } 387 } 388 return sigma; 389 } 390 391 public boolean handOfArea(Bound bound) { 392 return (signedArea(bound) < 0); 393 } 394 395 public double calcArea(Bound bound) { 396 return Math.abs(signedArea(bound)) * 3444 * 3444 / 2.0; 397 } 398 399 public Snode findCentroid(Feature feature) { 400 double lat, lon, slat, slon, sarc, llat, llon; 401 lat = lon = slat = slon = sarc = llat = llon = 0; 402 switch (feature.flag) { 403 case POINT: 404 return nodes.get(feature.refs); 405 case LINE: 406 Edge edge = edges.get(feature.refs); 407 llat = nodes.get(edge.first).lat; 408 llon = nodes.get(edge.first).lon; 409 for (long id : edge.nodes) { 410 lat = nodes.get(id).lat; 411 lon = nodes.get(id).lon; 412 sarc += (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 413 llat = lat; 414 llon = lon; 415 } 416 lat = nodes.get(edge.last).lat; 417 lon = nodes.get(edge.last).lon; 418 sarc += (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 419 double harc = sarc / 2; 420 sarc = 0; 421 llat = nodes.get(edge.first).lat; 422 llon = nodes.get(edge.first).lon; 423 for (long id : edge.nodes) { 424 lat = nodes.get(id).lat; 425 lon = nodes.get(id).lon; 426 sarc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 427 if (sarc > harc) break; 428 harc -= sarc; 429 llat = lat; 430 llon = lon; 431 } 432 if (sarc <= harc) { 433 lat = nodes.get(edge.last).lat; 434 lon = nodes.get(edge.last).lon; 435 sarc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 436 } 437 double frac = harc / sarc; 438 return new Snode(llat + ((lat - llat) / frac), llon + ((lon - llon) / frac)); 439 case AREA: 440 Bound bound = areas.get(feature.refs).get(0); 441 Snode node; 442 ListIterator<Long> it; 443 for (Side side : bound.sides) { 444 if (side.forward) { 445 node = nodes.get(side.edge.first); 446 lat = node.lat; 447 lon = node.lon; 448 it = side.edge.nodes.listIterator(); 449 while (it.hasNext()) { 450 llon = lon; 451 llat = lat; 452 node = nodes.get(it.next()); 453 lat = node.lat; 454 lon = node.lon; 455 double arc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 456 slat += (lat * arc); 457 slon += (lon * arc); 458 sarc += arc; 459 } 460 llon = lon; 461 llat = lat; 462 node = nodes.get(side.edge.last); 463 lat = node.lat; 464 lon = node.lon; 465 double arc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 466 slat += (lat * arc); 467 slon += (lon * arc); 468 sarc += arc; 469 } else { 470 node = nodes.get(side.edge.last); 471 lat = node.lat; 472 lon = node.lon; 473 it = side.edge.nodes.listIterator(side.edge.nodes.size()); 474 while (it.hasPrevious()) { 475 llon = lon; 476 llat = lat; 477 node = nodes.get(it.previous()); 478 lat = node.lat; 479 lon = node.lon; 480 double arc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 481 slat += (lat * arc); 482 slon += (lon * arc); 483 sarc += arc; 484 } 485 llon = lon; 486 llat = lat; 487 node = nodes.get(side.edge.first); 488 lat = node.lat; 489 lon = node.lon; 490 double arc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat))); 491 slat += (lat * arc); 492 slon += (lon * arc); 493 sarc += arc; 494 } 495 } 496 return new Snode((sarc > 0.0 ? slat/sarc : 0.0), (sarc > 0.0 ? slon/sarc : 0.0)); 497 } 498 return null; 499 } 500 237 501 }
Note:
See TracChangeset
for help on using the changeset viewer.
