source: osm/applications/editors/josm/plugins/smed2/jharbour/Jharbour.java@ 30197

Last change on this file since 30197 was 30184, checked in by malcolmh, 11 years ago

add dependent apps

File size: 7.2 KB
Line 
1/* Copyright 2013 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
10import java.io.*;
11import java.util.*;
12
13public class Jharbour {
14
15 static class Node {
16 public double lat;
17 public double lon;
18
19 public Node() {
20 lat = 0.0;
21 lon = 0.0;
22 }
23 public Node(double iLat, double iLon) {
24 lat = iLat;
25 lon = iLon;
26 }
27 }
28
29 static HashMap<Long, Node> nodes = new HashMap<Long, Node>();
30 static HashMap<Long, ArrayList<Long>> ways = new HashMap<Long, ArrayList<Long>>();
31
32 public static void main(String[] args) throws IOException {
33
34//BufferedReader in = new BufferedReader(new FileReader("/Users/mherring/boatsw/oseam/openseamap/renderer/work/tst.osm"));
35 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
36 PrintStream out = System.out;
37
38 ArrayList<String> tags = null;
39 ArrayList<Long> refs = null;
40 ArrayList<Long> outers = null;
41
42 boolean inOsm = false;
43 boolean inNode = false;
44 boolean inWay = false;
45 boolean inRel = false;
46 boolean isHarbour = false;
47 long id = 0;
48
49 String ln;
50 while ((ln = in.readLine()) != null) {
51 if (inOsm) {
52 if (ln.contains("</osm")) {
53 inOsm = false;
54 out.println("</harbours>");
55 } else if (inNode) {
56 if (ln.contains("</node")) {
57 inNode = false;
58 if (isHarbour) {
59 out.println(String.format(" <harbour node=\"%d\" lat=\"%f\" lon=\"%f\">", id, nodes.get(id).lat, nodes.get(id).lon));
60 for (String tag : tags) {
61 out.println(tag);
62 }
63 out.println(" </harbour>");
64 }
65 } else if (ln.contains("<tag")) {
66 tags.add(ln);
67 if (ln.contains("seamark:type") && (ln.contains("harbour") || ln.contains("anchorage"))) {
68 isHarbour = true;
69 }
70 }
71 } else if (inWay) {
72 if (ln.contains("</way")) {
73 inWay = false;
74 ways.put(id, refs);
75 if (isHarbour) {
76 Node node = findCentroid(refs);
77 out.println(String.format(" <harbour way=\"%d\" lat=\"%f\" lon=\"%f\">", id, node.lat, node.lon));
78 for (String tag : tags) {
79 out.println(tag);
80 }
81 out.println(" </harbour>");
82 }
83 } else if (ln.contains("<nd")) {
84 for (String token : ln.split("[ ]+")) {
85 if (token.matches("^ref=.+")) {
86 refs.add(Long.parseLong(token.split("[\"\']")[1]));
87 }
88 }
89 } else if (ln.contains("<tag")) {
90 tags.add(ln);
91 if (ln.contains("seamark:type") && (ln.contains("harbour") || ln.contains("anchorage"))) {
92 isHarbour = true;
93 }
94 }
95 } else if (inRel) {
96 if (ln.contains("</relation")) {
97 inRel = false;
98 if (isHarbour) {
99 refs = new ArrayList<Long>();
100 long first = 0;
101 long last = 0;
102 int sweep = outers.size();
103 while (!outers.isEmpty() && (sweep > 0)) {
104 long way = outers.remove(0);
105 if (refs.isEmpty()) {
106 refs.addAll(ways.get(way));
107 first = refs.get(0);
108 last = refs.get(refs.size()-1);
109 } else {
110 ArrayList<Long> nway = ways.get(way);
111 if (nway.get(0) == last) {
112 refs.addAll(nway);
113 last = refs.get(refs.size()-1);
114 sweep = outers.size();
115 } else if (nway.get(nway.size()-1) == last) {
116 Collections.reverse(nway);
117 refs.addAll(nway);
118 last = refs.get(refs.size()-1);
119 sweep = outers.size();
120 } else {
121 outers.add(way);
122 sweep--;
123 }
124 }
125 if (first == last) {
126 Node node = findCentroid(refs);
127 out.println(String.format(" <harbour rel=\"%d\" lat=\"%f\" lon=\"%f\">", id, node.lat, node.lon));
128 for (String tag : tags) {
129 out.println(tag);
130 }
131 out.println(" </harbour>");
132 refs = new ArrayList<Long>();
133 sweep = outers.size();
134 }
135 }
136 }
137 } else if (ln.contains("<member") && ln.contains("way") && ln.contains("outer")) {
138 for (String token : ln.split("[ ]+")) {
139 if (token.matches("^ref=.+")) {
140 outers.add(Long.parseLong(token.split("[\"\']")[1]));
141 }
142 }
143 } else if (ln.contains("<tag")) {
144 tags.add(ln);
145 if (ln.contains("seamark:type") && (ln.contains("harbour") || ln.contains("anchorage"))) {
146 isHarbour = true;
147 }
148 }
149 } else if (ln.contains("<node")) {
150 inNode = true;
151 isHarbour = false;
152 tags = new ArrayList<String>();
153 Node node = new Node();
154 for (String token : ln.split("[ ]+")) {
155 if (token.matches("^id=.+")) {
156 id = Long.parseLong(token.split("[\"\']")[1]);
157 nodes.put(id, node);
158 } else if (token.matches("^lat=.+")) {
159 node.lat = Double.parseDouble(token.split("[\"\']")[1]);
160 } else if (token.matches("^lon=.+")) {
161 node.lon = Double.parseDouble(token.split("[\"\']")[1]);
162 }
163 }
164 if (ln.contains("/>")) {
165 inNode = false;
166 }
167 } else if (ln.contains("<way")) {
168 inWay = true;
169 isHarbour = false;
170 tags = new ArrayList<String>();
171 refs = new ArrayList<Long>();
172 for (String token : ln.split("[ ]+")) {
173 if (token.matches("^id=.+")) {
174 id = Long.parseLong(token.split("[\"\']")[1]);
175 }
176 }
177 if (ln.contains("/>")) {
178 inWay = false;
179 }
180 } else if (ln.contains("<relation")) {
181 inRel = true;
182 isHarbour = false;
183 tags = new ArrayList<String>();
184 outers = new ArrayList<Long>();
185 for (String token : ln.split("[ ]+")) {
186 if (token.matches("^id=.+")) {
187 id = Long.parseLong(token.split("[\"\']")[1]);
188 }
189 }
190 if (ln.contains("/>")) {
191 inRel = false;
192 }
193 }
194 } else {
195 if (ln.contains("<osm")) {
196 inOsm = true;
197 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
198 out.println("<harbours>");
199 }
200 }
201 }
202 }
203
204 static Node findCentroid(ArrayList<Long> refs) {
205 double lat, lon, slat, slon, llat, llon, sarc;
206 boolean first = true;
207 slat = slon = sarc = lat = lon = llat = llon = 0.0;
208 if (refs.get(0).equals(refs.get(refs.size() - 1))) {
209 for (Long ref : refs) {
210 lat = nodes.get(ref).lat;
211 lon = nodes.get(ref).lon;
212 if (first) {
213 first = false;
214 } else {
215 double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
216 slat += (lat * arc);
217 slon += (lon * arc);
218 sarc += arc;
219 }
220 llon = lon;
221 llat = lat;
222 }
223 return new Node((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
224 } else {
225 for (Long ref : refs) {
226 lat = nodes.get(ref).lat;
227 lon = nodes.get(ref).lon;
228 if (first) {
229 first = false;
230 } else {
231 sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
232 }
233 llat = lat;
234 llon = lon;
235 }
236 double harc = sarc / 2;
237 sarc = 0.0;
238 first = true;
239 for (Long ref : refs) {
240 lat = nodes.get(ref).lat;
241 lon = nodes.get(ref).lon;
242 if (first) {
243 first = false;
244 } else {
245 sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
246 if (sarc > harc)
247 break;
248 }
249 harc -= sarc;
250 llat = lat;
251 llon = lon;
252 }
253 return new Node(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
254 }
255 }
256
257}
Note: See TracBrowser for help on using the repository browser.