source: osm/applications/editors/josm/plugins/seachart/src/s57/S57box.java@ 31955

Last change on this file since 31955 was 31846, checked in by malcolmh, 9 years ago

[seachart] add jbasemap

File size: 6.2 KB
Line 
1/* Copyright 2014 Malcolm Herring
2 *
3 * This is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License.
6 *
7 * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
8 */
9
10package s57;
11
12import java.util.ArrayList;
13
14import s57.S57map.*;
15import s57.S57obj.*;
16
17public class S57box { //S57 bounding box truncation
18
19 enum Ext {I, N, W, S, E }
20
21 public static void bBox(S57map map) {
22 /* Truncations
23 * Points: delete point features outside BB
24 * Lines: Truncate edges at BB boundaries
25 * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
26 * Remove nodes outside BB
27 * Remove edges that are completely outside BB
28 */
29 class Land {
30 long first;
31 Snode start;
32 Ext sbound;
33 long last;
34 Snode end;
35 Ext ebound;
36 Feature land;
37
38 Land(Feature l) {
39 land = l;
40 first = last = 0;
41 start = end = null;
42 sbound = ebound = Ext.I;
43 }
44 }
45 if (map.features.get(Obj.COALNE) != null) {
46 ArrayList<Feature> coasts = new ArrayList<>();
47 ArrayList<Land> lands = new ArrayList<>();
48 if (map.features.get(Obj.LNDARE) == null) {
49 map.features.put(Obj.LNDARE, new ArrayList<Feature>());
50 }
51 for (Feature feature : map.features.get(Obj.COALNE)) {
52 Feature land = map.new Feature();
53 land.id = ++map.xref;
54 land.type = Obj.LNDARE;
55 land.reln = Rflag.MASTER;
56 land.objs.put(Obj.LNDARE, map.new ObjTab());
57 land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
58 if (feature.geom.prim == Pflag.AREA) {
59 land.geom = feature.geom;
60 map.features.get(Obj.LNDARE).add(land);
61 } else if (feature.geom.prim == Pflag.LINE) {
62 land.geom.prim = Pflag.LINE;
63 land.geom.elems.addAll(feature.geom.elems);
64 coasts.add(land);
65 }
66 }
67 while (coasts.size() > 0) {
68 Feature land = coasts.remove(0);
69 Edge fedge = map.edges.get(land.geom.elems.get(0).id);
70 long first = fedge.first;
71 long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
72 if (coasts.size() > 0) {
73 boolean added = true;
74 while (added) {
75 added = false;
76 for (int i = 0; i < coasts.size(); i++) {
77 Feature coast = coasts.get(i);
78 Edge edge = map.edges.get(coast.geom.elems.get(0).id);
79 if (edge.first == last) {
80 land.geom.elems.add(coast.geom.elems.get(0));
81 last = edge.last;
82 coasts.remove(i--);
83 added = true;
84 } else if (edge.last == first) {
85 land.geom.elems.add(0, coast.geom.elems.get(0));
86 first = edge.first;
87 coasts.remove(i--);
88 added = true;
89 }
90 }
91 }
92 }
93 lands.add(new Land(land));
94 }
95 ArrayList<Land> islands = new ArrayList<>();
96 for (Land land : lands) {
97 map.sortGeom(land.land);
98 if (land.land.geom.prim == Pflag.AREA) {
99 islands.add(land);
100 map.features.get(Obj.LNDARE).add(land.land);
101 }
102 }
103 for (Land island : islands) {
104 lands.remove(island);
105 }
106 for (Land land : lands) {
107 GeomIterator git = map.new GeomIterator(land.land.geom);
108 Snode prev = null;
109 Ext bprev = Ext.I;
110 Ext ext;
111 land.ebound = land.sbound = Ext.I;
112 while (git.hasComp()) {
113 git.nextComp();
114 while (git.hasEdge()) {
115 git.nextEdge();
116 while (git.hasNode()) {
117 long ref = git.nextRef(false);
118 Snode node = map.nodes.get(ref);
119 if (node == null)
120 continue;
121 if (land.first == 0) {
122 land.first = ref;
123 }
124 if (prev == null) {
125 prev = node;
126 }
127 if ((node.lat >= map.bounds.maxlat) && (node.lon < map.bounds.maxlon)) {
128 ext = Ext.N;
129 } else if (node.lon <= map.bounds.minlon) {
130 ext = Ext.W;
131 } else if (node.lat <= map.bounds.minlat) {
132 ext = Ext.S;
133 } else if (node.lon >= map.bounds.maxlon) {
134 ext = Ext.E;
135 } else {
136 ext = Ext.I;
137 }
138 if (ext == Ext.I) {
139 if (land.start == null) {
140 land.start = prev;
141 land.sbound = bprev;
142 }
143 land.end = null;
144 land.ebound = Ext.I;
145 } else {
146 if ((land.start != null) && (land.end == null)) {
147 land.end = node;
148 land.ebound = ext;
149 }
150 }
151 prev = node;
152 bprev = ext;
153 land.last = ref;
154 }
155 }
156 }
157 }
158 islands = new ArrayList<>();
159 for (Land land : lands) {
160 if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
161 islands.add(land);
162 }
163 }
164 for (Land island : islands) {
165 lands.remove(island);
166 }
167 while (lands.size() > 0) {
168 Land land = lands.get(0);
169 Edge nedge = map.new Edge();
170 nedge.first = land.last;
171 Ext bound = land.ebound;
172 Snode last = land.end;
173 double delta = Math.PI;
174 int idx = -1;
175 Land next = null;
176 while (idx < 0) {
177 for (int i = 0; i < lands.size(); i++) {
178 next = lands.get(i);
179 if (next.sbound == bound) {
180 double diff = -Math.PI;
181 switch (bound) {
182 case N:
183 diff = last.lon - next.start.lon;
184 break;
185 case W:
186 diff = last.lat - next.start.lat;
187 break;
188 case S:
189 diff = next.start.lon - last.lon;
190 break;
191 case E:
192 diff = next.start.lat - last.lat;
193 break;
194 default:
195 continue;
196 }
197 if ((diff >= 0.0) && (diff < delta)) {
198 delta = diff;
199 idx = i;
200 }
201 }
202 }
203 if (idx < 0) {
204 long ref = (long) bound.ordinal();
205 last = map.nodes.get(ref);
206 nedge.nodes.add(ref);
207 ref = ref < 4 ? ++ref : 1;
208 for (Ext e : Ext.values()) {
209 if (ref == e.ordinal()) {
210 bound = e;
211 break;
212 }
213 }
214 }
215 }
216 next = lands.get(idx);
217 nedge.last = next.first;
218 map.edges.put(++map.xref, nedge);
219 land.land.geom.elems.add(map.new Prim(map.xref));
220 if (next != land) {
221 land.land.geom.elems.addAll(next.land.geom.elems);
222 land.ebound = next.ebound;
223 land.end = next.end;
224 land.last = next.last;
225 lands.remove(idx);
226 }
227 map.sortGeom(land.land);
228 if (land.land.geom.prim == Pflag.AREA) {
229 map.features.get(Obj.LNDARE).add(land.land);
230 lands.remove(land);
231 }
232 }
233 }
234 return;
235
236 }
237
238}
Note: See TracBrowser for help on using the repository browser.