Changeset 5226 in osm
- Timestamp:
- 2007-10-29T15:02:21+01:00 (17 years ago)
- Location:
- applications/editors/josm/plugins
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/utilsplugin/src/UtilsPlugin/SimplifyWayAction.java
r5142 r5226 103 103 for (int i = from+1; i < to; i++) { 104 104 Node n = wnew.nodes.get(i); 105 double xte = radtometers(linedist(105 double xte = Math.abs(EARTH_RAD * xtd( 106 106 fromN.coor.lat(), fromN.coor.lon(), 107 n.coor.lat(),n.coor.lon(),108 toN.coor.lat(),toN.coor.lon()));107 toN.coor.lat(), toN.coor.lon(), 108 n.coor.lat(), n.coor.lon())); 109 109 if (xte > xtemax) { 110 110 xtemax = xte; … … 120 120 } 121 121 122 /* ---------------------------------------------------------------------- 123 * Everything below this comment was converted from C to Java by Frederik 124 * Ramm. The original sources are the files grtcirc.c and smplrout.c from 125 * the gpsbabel source code (www.gpsbabel.org), which is under GPL. The 126 * relevant code portions have been written by Robert Lipe. 127 * 128 * Method names have been left unchanged where possible. 122 public static double EARTH_RAD = 6378137.0; 123 124 /* From Aviaton Formulary v1.3 125 * http://williams.best.vwh.net/avform.htm 129 126 */ 130 131 public static double EARTH_RAD = 6378137.0; 132 public static double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; 133 134 public static double[] crossproduct(double[] v1, double[] v2) { 135 double[] rv = new double[3]; 136 rv[0] = v1[1]*v2[2]-v2[1]*v1[2]; 137 rv[1] = v1[2]*v2[0]-v2[2]*v1[0]; 138 rv[2] = v1[0]*v2[1]-v1[1]*v2[0]; 139 return rv; 127 public static double dist(double lat1, double lon1, double lat2, double lon2) { 128 return 2*Math.asin(Math.sqrt(Math.pow(Math.sin((lat1-lat2)/2), 2) + 129 Math.cos(lat1)*Math.cos(lat2)*Math.pow(Math.sin((lon1-lon2)/2), 2))); 140 130 } 141 131 142 public static double dotproduct(double[] v1, double[] v2) { 143 return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]; 132 public static double course(double lat1, double lon1, double lat2, double lon2) { 133 return Math.atan2(Math.sin(lon1-lon2)*Math.cos(lat2), 134 Math.cos(lat1)*Math.sin(lat2)-Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon1-lon2)) % (2*Math.PI); 144 135 } 145 136 146 public static double radtomiles(double rads) { 147 return (rads*radmiles); 148 } 149 150 public static double radtometers(double rads) { 151 return (rads * EARTH_RAD); 152 } 153 154 public static double veclen(double[] vec) { 155 return Math.sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); 156 } 157 158 public static double gcdist(double lat1, double lon1, double lat2, double lon2) 159 { 160 double res; 161 double sdlat, sdlon; 162 163 sdlat = Math.sin((lat1 - lat2) / 2.0); 164 sdlon = Math.sin((lon1 - lon2) / 2.0); 165 166 res = Math.sqrt(sdlat * sdlat + Math.cos(lat1) * Math.cos(lat2) * sdlon * sdlon); 167 168 if (res > 1.0) { 169 res = 1.0; 170 } else if (res < -1.0) { 171 res = -1.0; 172 } 173 174 res = Math.asin(res); 175 return 2.0 * res; 176 } 177 178 static double linedist(double lat1, double lon1, double lat2, double lon2, double lat3, double lon3) { 179 180 double dot; 181 182 /* degrees to radians */ 183 lat1 = Math.toRadians(lat1); lon1 = Math.toRadians(lon1); 184 lat2 = Math.toRadians(lat2); lon2 = Math.toRadians(lon2); 185 lat3 = Math.toRadians(lat3); lon3 = Math.toRadians(lon3); 186 187 /* polar to ECEF rectangular */ 188 double[] v1 = new double[3]; 189 double[] v2 = new double[3]; 190 double[] v3 = new double[3]; 191 v1[0] = Math.cos(lon1)*Math.cos(lat1); v1[1] = Math.sin(lat1); v1[2] = Math.sin(lon1)*Math.cos(lat1); 192 v2[0] = Math.cos(lon2)*Math.cos(lat2); v2[1] = Math.sin(lat2); v2[2] = Math.sin(lon2)*Math.cos(lat2); 193 v3[0] = Math.cos(lon3)*Math.cos(lat3); v3[1] = Math.sin(lat3); v3[2] = Math.sin(lon3)*Math.cos(lat3); 194 195 /* 'va' is the axis; the line that passes through the center of the earth 196 * and is perpendicular to the great circle through point 1 and point 2 197 * It is computed by taking the cross product of the '1' and '2' vectors.*/ 198 double[] va = crossproduct(v1, v2); 199 double la = veclen(va); 200 201 if (la != 0) { 202 va[0] /= la; 203 va[1] /= la; 204 va[2] /= la; 205 206 /* dot is the component of the length of '3' that is along the axis. 207 * What's left is a non-normalized vector that lies in the plane of 208 * 1 and 2. */ 209 210 dot = dotproduct(v3, va); 211 212 double[] vp = new double[3]; 213 vp[0]=v3[0]-dot*va[0]; 214 vp[1]=v3[1]-dot*va[1]; 215 vp[2]=v3[2]-dot*va[2]; 216 217 double lp = veclen(vp); 218 219 if (lp != 0) { 220 221 /* After this, 'p' is normalized */ 222 vp[0] /= lp; 223 vp[1] /= lp; 224 vp[2] /= lp; 225 226 double[] cp1 = crossproduct(v1, vp); 227 double dp1 = dotproduct(cp1, va); 228 229 double[] cp2 = crossproduct(v2, vp); 230 double dp2 = dotproduct(cp2, va); 231 232 if ( dp1 >= 0 && dp2 >= 0 ) { 233 /* rather than call gcdist and all its sines and cosines and 234 * worse, we can get the angle directly. It's the arctangent 235 * of the length of the component of vector 3 along the axis 236 * divided by the length of the component of vector 3 in the 237 * plane. We already have both of those numbers. 238 * 239 * atan2 would be overkill because lp and Math.abs are both 240 * known to be positive. */ 241 return Math.atan(Math.abs(dot)/lp); 242 } 243 244 /* otherwise, get the distance from the closest endpoint */ 245 double c1 = dotproduct(v1, vp); 246 double c2 = dotproduct(v2, vp); 247 dp1 = Math.abs(dp1); 248 dp2 = Math.abs(dp2); 249 250 /* This is a hack. d$n$ is proportional to the sine of the angle 251 * between point $n$ and point p. That preserves orderedness up 252 * to an angle of 90 degrees. c$n$ is proportional to the cosine 253 * of the same angle; if the angle is over 90 degrees, c$n$ is 254 * negative. In that case, we flop the sine across the y=1 axis 255 * so that the resulting value increases as the angle increases. 256 * 257 * This only works because all of the points are on a unit sphere. */ 258 259 if (c1 < 0) { 260 dp1 = 2 - dp1; 261 } 262 if (c2 < 0) { 263 dp2 = 2 - dp2; 264 } 265 266 if (Math.abs(dp1) < Math.abs(dp2)) { 267 return gcdist(lat1,lon1,lat3,lon3); 268 } else { 269 return gcdist(lat2,lon2,lat3,lon3); 270 } 271 } else { 272 /* lp is 0 when 3 is 90 degrees from the great circle */ 273 return Math.PI/2; 274 } 275 } else { 276 /* la is 0 when 1 and 2 are either the same point or 180 degrees apart */ 277 dot = dotproduct(v1, v2); 278 if (dot >= 0) { 279 return gcdist(lat1,lon1,lat3,lon3); 280 } else { 281 return 0; 282 } 283 } 137 public static double xtd(double lat1, double lon1, double lat2, double lon2, double lat3, double lon3) { 138 double dist_AD = dist(lat1, lon1, lat3, lon3); 139 double crs_AD = course(lat1, lon1, lat3, lon3); 140 double crs_AB = course(lat1, lon1, lat2, lon2); 141 return Math.asin(Math.sin(dist_AD)*Math.sin(crs_AD-crs_AB)); 284 142 } 285 143 }
Note:
See TracChangeset
for help on using the changeset viewer.