Changeset 19387 in josm
- Timestamp:
- 2025-04-23T18:34:33+02:00 (8 days ago)
- Location:
- trunk
- Files:
-
- 2 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/ImageData.java
r19112 r19387 367 367 368 368 /** 369 * Update the GPS track direction of the image and trigger update. 370 * @param img the image to update 371 * @param trackDirection the new GPS track direction 372 * @since 19387 373 */ 374 public void updateImageGpsTrack(ImageEntry img, double trackDirection) { 375 img.setExifGpsTrack(trackDirection); 376 afterImageUpdated(img); 377 } 378 379 /** 380 * Update the image horizontal positioning error and trigger update. 381 * @param img the image to update 382 * @param hposerr the new horizontal positionning error 383 * @since 19387 384 */ 385 public void updateImageHPosErr(ImageEntry img, double hposerr) { 386 img.setExifHPosErr(hposerr); 387 afterImageUpdated(img); 388 } 389 390 /** 391 * Update the image GPS differential mode and trigger update. 392 * @param img the image to update 393 * @param gpsDiffMode the new GPS differential mode 394 * @since 19387 395 */ 396 public void updateImageGpsDiffMode(ImageEntry img, Integer gpsDiffMode) { 397 img.setGpsDiffMode(gpsDiffMode); 398 afterImageUpdated(img); 399 } 400 401 /** 402 * Update the image GPS 2d/3d mode value and trigger update. 403 * @param img the image to update 404 * @param gps2d3dMode the new 2d/3d GPS mode 405 * @since 19387 406 */ 407 public void updateImageGps2d3dMode(ImageEntry img, Integer gps2d3dMode) { 408 img.setGps2d3dMode(gps2d3dMode); 409 afterImageUpdated(img); 410 } 411 412 /** 413 * Update the image GPS DOP value and trigger update. 414 * @param img the image to update 415 * @param exifGpsDop the new GPS DOP value 416 * @since 19387 417 */ 418 public void updateImageExifGpsDop(ImageEntry img, Double exifGpsDop) { 419 img.setExifGpsDop(exifGpsDop); 420 afterImageUpdated(img); 421 } 422 423 /** 424 * Update the image GPS datum and trigger update. 425 * @param img the image to update 426 * @param exifGpsDatum the new datum string value 427 * @since 19387 428 */ 429 public void updateImageExifGpsDatum(ImageEntry img, String exifGpsDatum) { 430 img.setExifGpsDatum(exifGpsDatum); 431 afterImageUpdated(img); 432 } 433 434 /** 435 * Update the image GPS processing method and trigger update. 436 * @param img the image to update 437 * @param exifGpsProcMethod the new GPS processing method 438 * @since 19387 439 */ 440 public void updateImageExifGpsProcMethod(ImageEntry img, String exifGpsProcMethod) { 441 img.setExifGpsProcMethod(exifGpsProcMethod); 442 afterImageUpdated(img); 443 } 444 445 /** 369 446 * Manually trigger the {@link ImageDataUpdateListener#imageDataUpdated(ImageData)} 370 447 */ -
trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
r19316 r19387 146 146 String PT_TIME = "time"; 147 147 148 /** True Course/Bearing angle over ground. 149 * @since 19387 150 */ 151 String PT_COURSE = "course"; 152 148 153 /** Magnetic variation (in degrees) at the point. 0.0 <= value < 360.0 */ 149 154 String PT_MAGVAR = "magvar"; … … 189 194 */ 190 195 List<String> WPT_KEYS = Collections.unmodifiableList(Arrays.asList(PT_ELE, PT_TIME, PT_MAGVAR, PT_GEOIDHEIGHT, 191 GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, PT_SYM, PT_TYPE, 192 PT_ FIX, PT_SAT, PT_HDOP, PT_VDOP, PT_PDOP, PT_AGEOFDGPSDATA, PT_DGPSID, PT_STD_HDEV, PT_STD_VDEV));196 GPX_NAME, GPX_CMT, GPX_DESC, GPX_SRC, META_LINKS, PT_SYM, PT_TYPE, PT_FIX, PT_SAT, PT_COURSE, 197 PT_HDOP, PT_VDOP, PT_PDOP, PT_AGEOFDGPSDATA, PT_DGPSID, PT_STD_HDEV, PT_STD_VDEV)); 193 198 194 199 /** -
trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelation.java
r18494 r19387 2 2 package org.openstreetmap.josm.data.gpx; 3 3 4 import java.util.Arrays; 4 5 import java.util.ArrayList; 5 6 import java.util.Collection; … … 73 74 74 75 final GpxImageDirectionPositionSettings dirpos = settings.getDirectionPositionSettings(); 76 final GpxImageDatumSettings datumSettings = settings.getDatumSettings(); 75 77 final long offset = settings.getOffset(); 76 78 … … 142 144 } 143 145 WayPoint nextWp = i < size - 1 ? wps.get(i + 1) : null; 144 ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset, interpolate, tagTime, nextWp, dirpos); 146 ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset, 147 interpolate, tagTime, nextWp, dirpos, datumSettings); 145 148 prevWp = curWp; 146 149 prevWpTime = curWpTime; … … 149 152 } 150 153 if (trkTag && prevWp != null) { 151 ret += matchPoints(images, prevWp, prevWpTime, prevWp, prevWpTime, offset, false, trkTagTime, null, dirpos); 154 ret += matchPoints(images, prevWp, prevWpTime, prevWp, prevWpTime, offset, 155 false, trkTagTime, null, dirpos, datumSettings); 152 156 } 153 157 Logging.debug("Correlated {0} total points", ret); … … 210 214 } 211 215 212 private static int matchPoints(List<? extends GpxImageEntry> images, WayPoint prevWp, long prevWpTime, WayPoint curWp, long curWpTime, 213 long offset, boolean interpolate, int tagTime, WayPoint nextWp, GpxImageDirectionPositionSettings dirpos) { 216 static Double getHPosErr(WayPoint wp) { 217 if (wp != null) { 218 if (wp.attr.get(GpxConstants.PT_STD_HDEV) instanceof Float) { 219 Float hposerr = (Float) wp.attr.get(GpxConstants.PT_STD_HDEV); 220 if (hposerr != null) { 221 return hposerr.doubleValue(); 222 } 223 } else if (wp.attr.get(GpxConstants.PT_STD_HDEV) instanceof Double) { 224 Double hposerr = (Double) wp.attr.get(GpxConstants.PT_STD_HDEV); 225 if (hposerr != null) { 226 return hposerr; 227 } 228 } 229 } 230 return null; 231 } 232 233 static Double getGpsDop(WayPoint wp) { 234 if (wp != null) { 235 if (wp.attr.get(GpxConstants.PT_PDOP) != null) { 236 if (wp.attr.get(GpxConstants.PT_PDOP) instanceof Float) { 237 Float pdopvalue = (Float) wp.attr.get(GpxConstants.PT_PDOP); 238 return pdopvalue.doubleValue(); 239 } else if (wp.attr.get(GpxConstants.PT_PDOP) instanceof Double) { 240 Double pdopvalue = (Double) wp.attr.get(GpxConstants.PT_PDOP); 241 return pdopvalue.doubleValue(); 242 } 243 } else if (wp.attr.get(GpxConstants.PT_HDOP) != null) { 244 if (wp.attr.get(GpxConstants.PT_HDOP) instanceof Float) { 245 Float hdopvalue = (Float) wp.attr.get(GpxConstants.PT_HDOP); 246 return hdopvalue.doubleValue(); 247 } else if (wp.attr.get(GpxConstants.PT_HDOP) instanceof Double) { 248 Double hdopvalue = (Double) wp.attr.get(GpxConstants.PT_HDOP); 249 return hdopvalue.doubleValue(); 250 } 251 } 252 } 253 return null; 254 } 255 256 static Double getGpsTrack(WayPoint wp) { 257 if (wp != null) { 258 String trackvalue = wp.getString(GpxConstants.PT_COURSE); 259 Logging.debug("track angle value: {0}", trackvalue); 260 if (!Utils.isEmpty(trackvalue)) { 261 try { 262 return Double.valueOf(trackvalue); 263 } catch (NumberFormatException e) { 264 Logging.warn(e); 265 } 266 } 267 } 268 return null; 269 } 270 271 static String getGpsProcMethod(String prevGpsFixMode, final String curGpsFixMode, 272 final List<String> positioningModes) { 273 String gpsProcMethod = null; 274 Integer lowestProcIndex = null; 275 int lowestGnssModeIdx = 3; // 2d or higher index in positioningModes list are Gnss methods 276 try { 277 lowestProcIndex = Math.min(positioningModes.indexOf(prevGpsFixMode), positioningModes.indexOf(curGpsFixMode)); 278 if (lowestProcIndex < 0) { 279 return null; 280 } 281 gpsProcMethod = "GNSS" + " " + positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION"; 282 if (lowestProcIndex < lowestGnssModeIdx) { 283 gpsProcMethod = positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION"; 284 } else { 285 gpsProcMethod = "GNSS" + " " + positioningModes.get(lowestProcIndex).toUpperCase() + " " + "CORRELATION"; 286 } 287 gpsProcMethod = gpsProcMethod.replace("FLOAT RTK", "RTK_FLOAT"); 288 gpsProcMethod = gpsProcMethod.replace(" RTK ", " RTK_FIX "); 289 } catch (ArrayIndexOutOfBoundsException ex) { 290 Logging.warn(ex); 291 } 292 return gpsProcMethod; 293 } 294 295 static Integer getGps2d3dMode(String prevGpsFixMode, final String curGpsFixMode, 296 final List<String> positioningModes) { 297 Integer lowestMode = null; 298 lowestMode = Math.min(positioningModes.indexOf(prevGpsFixMode), positioningModes.indexOf(curGpsFixMode)); 299 if (lowestMode > 3) { 300 return 3; 301 } 302 if (lowestMode > 2) { 303 return 2; 304 } 305 return null; 306 } 307 308 // CHECKSTYLE.OFF: ParameterNumber 309 private static int matchPoints(List<? extends GpxImageEntry> 310 images, 311 WayPoint prevWp, 312 long prevWpTime, 313 WayPoint curWp, 314 long curWpTime, 315 long offset, 316 boolean interpolate, 317 int tagTime, 318 WayPoint nextWp, 319 GpxImageDirectionPositionSettings dirpos, 320 GpxImageDatumSettings datumSettings) { 214 321 215 322 final boolean isLast = nextWp == null; … … 237 344 Double speed = null; 238 345 Double prevElevation = null; 346 Double prevHPosErr = null; 347 Double prevGpsDop = null; 348 Double prevGpsTrack = null; 349 String prevGpsFixMode = null; 350 //list of differential GPS mode 351 //TODO move these lists in Gpx.Constants? 352 final List<String> diffMode = Arrays.asList("dgps", "float rtk", "rtk"); 353 final List<String> positioningModes = Arrays.asList("none", "manual", "estimated", "2d", "3d", "dgps", "float rtk", "rtk"); 354 239 355 240 356 if (prevWp != null && interpolate) { … … 245 361 } 246 362 prevElevation = getElevation(prevWp); 363 prevHPosErr = getHPosErr(prevWp); 364 prevGpsDop = getGpsDop(prevWp); 365 prevGpsTrack = getGpsTrack(prevWp); 366 prevGpsFixMode = prevWp.getString(GpxConstants.PT_FIX); 247 367 } 248 368 249 369 final Double curElevation = getElevation(curWp); 370 final Double curHPosErr = getHPosErr(curWp); 371 final Double curGpsDop = getGpsDop(curWp); 372 final Double curGpsTrack = getGpsTrack(curWp); 373 final String curGpsFixMode = curWp.getString(GpxConstants.PT_FIX); 250 374 251 375 if (!interpolate || isLast) { … … 267 391 curTmp.setPos(curWp.getCoor()); 268 392 } 393 //TODO fix this, nextWp doesn't exist here 269 394 if (nextWp != null && dirpos.isSetImageDirection()) { 270 395 double direction = curWp.bearing(nextWp); … … 318 443 curTmp.setElevation(prevElevation + (curElevation - prevElevation) * timeDiff + dirpos.getElevationShift()); 319 444 } 445 446 // Add exif GpsHPositioningerror interpolated value 447 if (curHPosErr != null && prevHPosErr != null) { 448 Double interpolatedValue = prevHPosErr + (curHPosErr - prevHPosErr) * timeDiff; 449 curTmp.setExifHPosErr(Math.round(interpolatedValue*10000)/10000.0); 450 } 451 452 // Add exif GpsDifferentialMode 453 // Get previous and current waypoint differential. As no interpolation is possible, 454 // set differential mode to 0 if any waypoint isn't in differential mode. 455 if (prevGpsFixMode != null) { 456 if (diffMode.contains(prevGpsFixMode) && diffMode.contains(curGpsFixMode)) { 457 curTmp.setGpsDiffMode(1); 458 } else { 459 curTmp.setGpsDiffMode(0); 460 } 461 } 462 463 // Add exif GpsMeasureMode 464 if (prevGpsFixMode != null && curGpsFixMode != null) { 465 Integer gps2d3dMode = getGps2d3dMode(prevGpsFixMode, curGpsFixMode, positioningModes); 466 if (gps2d3dMode != null) { 467 curTmp.setGps2d3dMode(gps2d3dMode); 468 } 469 } 470 471 // Add exif GpsProcessingMethod. As no interpolation is possible, 472 // set processing method to the "lowest" previous and current processing method value. 473 if (prevGpsFixMode != null && curGpsFixMode != null) { 474 String gpsProcMethod = getGpsProcMethod(prevGpsFixMode, curGpsFixMode, positioningModes); 475 if (gpsProcMethod != null) { 476 curTmp.setExifGpsProcMethod(gpsProcMethod); 477 } 478 } 479 480 // Add Exif GpsDop with interpolated GPS DOP value 481 if (curGpsDop != null && prevGpsDop != null) { 482 Double interpolatedValue = prevGpsDop + (curGpsDop - prevGpsDop) * timeDiff; 483 curTmp.setExifGpsDop(Math.round(interpolatedValue*100)/100.0); 484 } 485 486 // Add Exif GpsTrack tag 487 if (dirpos.isSetGpxTrackDirection()) { 488 if (curGpsTrack != null && prevGpsTrack != null) { 489 curTmp.setExifGpsTrack(prevGpsTrack + (curGpsTrack - prevGpsTrack) * timeDiff); 490 } 491 } 492 493 // Add GpsDatum tag 494 if (datumSettings.isSetImageGpsDatum()) { 495 if (diffMode.contains(prevGpsFixMode) && diffMode.contains(curGpsFixMode)) { 496 curTmp.setExifGpsDatum(datumSettings.getImageGpsDatum()); 497 } else //without differential mode, datum is WGS-84 498 curTmp.setExifGpsDatum("WGS-84"); 499 } 500 320 501 curTmp.setGpsTime(curImg.getExifInstant().minusMillis(offset)); 321 502 curTmp.flagNewGpsData(); … … 331 512 return ret; 332 513 } 514 // CHECKSTYLE.ON: ParameterNumber 333 515 334 516 private static double computeDirection(double direction, double angleOffset) { -
trunk/src/org/openstreetmap/josm/data/gpx/GpxImageCorrelationSettings.java
r18065 r19387 13 13 private final boolean forceTags; 14 14 private final GpxImageDirectionPositionSettings directionPositionSettings; 15 private final GpxImageDatumSettings datumSettings; 15 16 16 17 /** … … 20 21 */ 21 22 public GpxImageCorrelationSettings(long offset, boolean forceTags) { 22 this(offset, forceTags, new GpxImageDirectionPositionSettings(false, 0, 0, 0, 0)); 23 this(offset, forceTags, 24 new GpxImageDirectionPositionSettings(false, 0, false, 0, 0, 0), 25 new GpxImageDatumSettings(false, null) 26 ); 23 27 } 24 28 … … 31 35 public GpxImageCorrelationSettings(long offset, boolean forceTags, 32 36 GpxImageDirectionPositionSettings directionPositionSettings) { 37 this(offset, forceTags, directionPositionSettings, 38 new GpxImageDatumSettings(false, null)); 39 } 40 41 /** 42 * Constructs a new {@code GpxImageCorrelationSettings}. 43 * @param offset offset in milliseconds 44 * @param forceTags force tagging of all photos, otherwise prefs are used 45 * @param directionPositionSettings direction/position settings 46 * @param datumSettings GPS datum settings 47 * @since 19387 @datumSettings was added 48 */ 49 public GpxImageCorrelationSettings(long offset, boolean forceTags, 50 GpxImageDirectionPositionSettings directionPositionSettings, 51 GpxImageDatumSettings datumSettings) { 33 52 this.offset = offset; 34 53 this.forceTags = forceTags; 35 54 this.directionPositionSettings = Objects.requireNonNull(directionPositionSettings); 55 this.datumSettings = Objects.requireNonNull(datumSettings); 36 56 } 37 57 38 58 /** 39 59 * Returns the offset in milliseconds. … … 60 80 } 61 81 82 /** 83 * Returns the EXIF metadata datum settings. 84 * @return the EXIF metadata datum settings 85 * @since 19387 86 */ 87 public GpxImageDatumSettings getDatumSettings() { 88 return datumSettings; 89 } 90 62 91 @Override 63 92 public String toString() { 64 93 return "[offset=" + offset + ", forceTags=" + forceTags 65 + ", directionPositionSettings=" + directionPositionSettings + ']'; 94 + ", directionPositionSettings=" + directionPositionSettings 95 + ", datumSettings=" + datumSettings + ']'; 66 96 } 67 97 } -
trunk/src/org/openstreetmap/josm/data/gpx/GpxImageDirectionPositionSettings.java
r18065 r19387 10 10 private final boolean setImageDirection; 11 11 private final double imageDirectionAngleOffset; 12 private final boolean setGpxTrackDirection; 12 13 private final double shiftImageX; 13 14 private final double shiftImageY; … … 18 19 * @param setImageDirection determines if image direction must be set towards the next GPX waypoint 19 20 * @param imageDirectionAngleOffset direction angle offset in degrees 21 * @param setGpxTrackDirection determines if image course direction must be set 20 22 * @param shiftImageX image shift on X axis relative to the direction in meters 21 23 * @param shiftImageY image shift on Y axis relative to the direction in meters 22 24 * @param elevationShift image elevation shift in meters 25 * @since 19387 @setGpsTrackDirection was added 23 26 */ 24 27 public GpxImageDirectionPositionSettings( 25 boolean setImageDirection, double imageDirectionAngleOffset, double shiftImageX, double shiftImageY, double elevationShift) { 28 boolean setImageDirection, double imageDirectionAngleOffset, boolean setGpxTrackDirection, 29 double shiftImageX, double shiftImageY, double elevationShift) { 26 30 this.setImageDirection = setImageDirection; 27 31 this.imageDirectionAngleOffset = imageDirectionAngleOffset; 32 this.setGpxTrackDirection = setGpxTrackDirection; 28 33 this.shiftImageX = shiftImageX; 29 34 this.shiftImageY = shiftImageY; … … 45 50 public double getImageDirectionAngleOffset() { 46 51 return imageDirectionAngleOffset; 52 } 53 54 /** 55 * Determines if GPS course direction must be set. Angle value is from the gpx trace. 56 * @return {@code true} if image GPS course must be set 57 * @since 19387 58 */ 59 public boolean isSetGpxTrackDirection() { 60 return setGpxTrackDirection; 47 61 } 48 62 … … 74 88 public String toString() { 75 89 return "[setImageDirection=" + setImageDirection 76 + ", imageDirectionAngleOffset=" + imageDirectionAngleOffset + ", shiftImageX=" + shiftImageX 77 + ", shiftImageY=" + shiftImageY + ", elevationShift=" + elevationShift + ']'; 90 + ", imageDirectionAngleOffset=" + imageDirectionAngleOffset 91 + ", setImageGpxTrackDirection=" + setGpxTrackDirection 92 + ", shiftImageX=" + shiftImageX 93 + ", shiftImageY=" + shiftImageY 94 + ", elevationShift=" + elevationShift + ']'; 78 95 } 79 96 } -
trunk/src/org/openstreetmap/josm/data/gpx/GpxImageEntry.java
r19320 r19387 33 33 private LatLon exifCoor; 34 34 private Double exifImgDir; 35 private Double exifGpsTrack; 36 private Double exifHPosErr; 37 private Double exifGpsDop; 35 38 private Instant exifTime; 36 39 private Projections cameraProjection = Projections.UNKNOWN; … … 58 61 /** Elevation (altitude) in meters */ 59 62 private Double elevation; 63 /** GPS Differential mode */ 64 private Integer gpsDiffMode; 65 /** GPS Measure mode */ 66 private Integer gps2d3dMode; 67 /** GPS Datum */ 68 private String exifGpsDatum; 69 /** GPS processing method */ 70 private String exifGpsProcMethod; 60 71 /** The time after correlation with a gpx track */ 61 72 private Instant gpsTime; … … 89 100 exifCoor = other.exifCoor; 90 101 exifImgDir = other.exifImgDir; 102 exifGpsTrack = other.exifGpsTrack; 103 exifHPosErr = other.exifHPosErr; 104 gpsDiffMode = other.gpsDiffMode; 105 gps2d3dMode = other.gps2d3dMode; 106 exifGpsDop = other.exifGpsDop; 107 exifGpsDatum = other.exifGpsDatum; 108 exifGpsProcMethod = other.exifGpsProcMethod; 91 109 exifTime = other.exifTime; 92 110 isNewGpsData = other.isNewGpsData; … … 171 189 172 190 /** 191 * Return the GPS Differential mode value. The GPS Differential mode value from the temporary 192 * copy is returned if that copy exists. 193 * @return the differential mode value 194 * @since 19387 195 */ 196 @Override 197 public Integer getGpsDiffMode() { 198 if (tmp != null) 199 return tmp.gpsDiffMode; 200 return gpsDiffMode; 201 } 202 203 /** 204 * Return the GPS 2d or 3d mode value. The GPS mode value form the temporary 205 * copy is returned if that copy exists. 206 * @return the GPS 2d/3d mode value 207 * @since 19387 208 */ 209 @Override 210 public Integer getGps2d3dMode() { 211 if (tmp != null) 212 return tmp.gps2d3dMode; 213 return gps2d3dMode; 214 } 215 216 /** 217 * Return the GPS DOP value. The GPS DOP value from the temporary 218 * copy is returned if that copy exists. 219 * @return the DOP value 220 * @since 19387 221 */ 222 @Override 223 public Double getExifGpsDop() { 224 if (tmp != null) 225 return tmp.exifGpsDop; 226 return exifGpsDop; 227 } 228 229 /** 230 * Return the exif GPS coordinates datum value. 231 * @return The datum value 232 * @since 19387 233 */ 234 @Override 235 public String getExifGpsDatum() { 236 if (tmp != null) 237 return tmp.exifGpsDatum; 238 return exifGpsDatum; 239 } 240 241 /** 242 * Return the exif GPS processing method string 243 * @return the processing method string 244 * @since 19387 245 */ 246 @Override 247 public String getExifGpsProcMethod() { 248 if (tmp != null) 249 return tmp.exifGpsProcMethod; 250 return exifGpsProcMethod; 251 } 252 253 /** 173 254 * Returns the GPS time value. The GPS time value from the temporary copy 174 255 * is returned if that copy exists. … … 272 353 return tmp.exifImgDir; 273 354 return exifImgDir; 355 } 356 357 /** 358 * Convenient way to determine if this entry has a EXIF GPS track angle value, 359 * without the cost of building a defensive copy. 360 * @return {@code true} if this entry has a EXIF track angle value 361 * @since 19387 362 */ 363 @Override 364 public Double getExifGpsTrack() { 365 if (tmp != null) 366 return tmp.exifGpsTrack; 367 return exifGpsTrack; 368 } 369 370 /** 371 * Convenient way to determine if this entry has a EXIF GPS horizontal positionning error value, 372 * without the cost of building a defensive copy. 373 * @return {@code true} if this entry has a EXIF GPS horizontal positionning error value 374 * @since 19387 375 */ 376 @Override 377 public Double getExifHPosErr() { 378 if (tmp != null) 379 return tmp.exifHPosErr; 380 return exifHPosErr; 274 381 } 275 382 … … 347 454 348 455 /** 456 * Sets GPS Differential mode. 457 * @param gpsDiffMode GPS Differential mode 458 * @since 19387 459 */ 460 @Override 461 public void setGpsDiffMode(Integer gpsDiffMode) { 462 this.gpsDiffMode = gpsDiffMode; 463 } 464 465 /** 466 * Sets GPS 2d/3d mode. 467 * @param gps2d3dMode GPS 2d/3d mode value 468 * @since 19387 469 */ 470 @Override 471 public void setGps2d3dMode(Integer gps2d3dMode) { 472 this.gps2d3dMode = gps2d3dMode; 473 } 474 475 /** 476 * Sets GPS DOP value. 477 * @param exifGpsDop GPS DOP value 478 * @since 19387 479 */ 480 @Override 481 public void setExifGpsDop(Double exifGpsDop) { 482 this.exifGpsDop = exifGpsDop; 483 } 484 485 /** 486 * Sets the GPS Datum. 487 * @param exifGpsDatum GPS Datum 488 * @since 19387 489 */ 490 @Override 491 public void setExifGpsDatum(String exifGpsDatum) { 492 this.exifGpsDatum = exifGpsDatum; 493 } 494 495 /** 496 * Sets the GPS Processing Method. 497 * @param exifGpsProcMethod GPS Processing Method 498 * @since 19387 499 */ 500 @Override 501 public void setExifGpsProcMethod(String exifGpsProcMethod) { 502 this.exifGpsProcMethod = exifGpsProcMethod; 503 } 504 505 /** 349 506 * Sets associated file. 350 507 * @param file associated file … … 411 568 public void setExifImgDir(Double exifDir) { 412 569 this.exifImgDir = exifDir; 570 } 571 572 /** 573 * Sets the exif GPS track (move direction angle) 574 * @param exifGpsTrack the exif GPS track angle 575 * @since 19387 576 */ 577 @Override 578 public void setExifGpsTrack(Double exifGpsTrack) { 579 this.exifGpsTrack = exifGpsTrack; 580 } 581 582 /** 583 * Sets the exif horizontal positioning error 584 * @param exifHposErr the Exif horizontal positionning error 585 * @since 19387 586 */ 587 @Override 588 public void setExifHPosErr(Double exifHPosErr) { 589 this.exifHPosErr = exifHPosErr; 413 590 } 414 591 … … 508 685 public int hashCode() { 509 686 return Objects.hash(height, width, isNewGpsData, 510 elevation, exifCoor, exifGpsTime, exifImgDir, exifOrientation, exifTime, 511 iptcCaption, iptcHeadline, iptcKeywords, iptcObjectName, 512 file, gpsTime, pos, speed, tmp, cameraProjection); 687 elevation, exifCoor, exifGpsTime, exifImgDir, exifGpsTrack, exifHPosErr, 688 exifGpsDop, gpsDiffMode, gps2d3dMode, exifGpsDatum, exifGpsProcMethod, 689 exifOrientation, exifTime, iptcCaption, iptcHeadline, iptcKeywords, 690 iptcObjectName, file, gpsTime, pos, speed, tmp, cameraProjection); 513 691 } 514 692 … … 527 705 && Objects.equals(exifGpsTime, other.exifGpsTime) 528 706 && Objects.equals(exifImgDir, other.exifImgDir) 707 && Objects.equals(exifGpsTrack, other.exifGpsTrack) 708 && Objects.equals(exifHPosErr, other.exifHPosErr) 709 && Objects.equals(gpsDiffMode, other.gpsDiffMode) 710 && Objects.equals(gps2d3dMode, other.gps2d3dMode) 711 && Objects.equals(exifGpsDop, other.exifGpsDop) 712 && Objects.equals(exifGpsDatum, other.exifGpsDatum) 713 && Objects.equals(exifGpsProcMethod, other.exifGpsProcMethod) 529 714 && Objects.equals(exifOrientation, other.exifOrientation) 530 715 && Objects.equals(exifTime, other.exifTime) … … 571 756 * temporary variable is deleted. 572 757 * @see #discardTmp() 758 * @since 19387 exifGpsTrack, exifHPosErr, gpsDiffMode, gps2d3dMode, exifGpsDop, exifGpsDatum, exifGpsProcMethod added 573 759 */ 574 760 public void applyTmp() { … … 579 765 gpsTime = tmp.gpsTime; 580 766 exifImgDir = tmp.exifImgDir; 767 exifGpsTrack = tmp.exifGpsTrack; 768 exifHPosErr = tmp.exifHPosErr; 769 gpsDiffMode = tmp.gpsDiffMode; 770 gps2d3dMode = tmp.gps2d3dMode; 771 exifGpsDop = tmp.exifGpsDop; 772 exifGpsDatum = tmp.exifGpsDatum; 773 exifGpsProcMethod = tmp.exifGpsProcMethod; 581 774 isNewGpsData = isNewGpsData || tmp.isNewGpsData; 582 775 tmp = null; -
trunk/src/org/openstreetmap/josm/data/imagery/street_level/IImageEntry.java
r18599 r19387 220 220 221 221 /** 222 * Return the GPS Differential mode value. The differential mode value from the temporary 223 * copy is returned if that copy exists. 224 * @return the fix mode value 225 * @since 19387 226 */ 227 Integer getGpsDiffMode(); 228 229 /** 230 * Return the GPS 2d/3d mode value. The 2d/3d mode value from the temporary 231 * copy is returned if that copy exists. 232 * @return the 2d/3d mode value 233 * @since 19387 234 */ 235 Integer getGps2d3dMode(); 236 237 /** 238 * Return the GPS DOP value. The GPS DOP value from the temporary 239 * copy is return if that copy exists. 240 * @return the GPS DOP value 241 * @since 19387 242 */ 243 Double getExifGpsDop(); 244 245 /** 246 * Return the GPS datum value. The GPS datum value from the temporary 247 * copy is return if that copy exists. 248 * @return the GPS datum value 249 * @since 19387 250 */ 251 String getExifGpsDatum(); 252 253 /** 254 * Return the GPS processing method. The processing method value from the temporary 255 * copy is return if that copy exists. 256 * @return the GPS processing method 257 * @since 19387 258 */ 259 String getExifGpsProcMethod(); 260 261 /** 222 262 * Returns the image direction. The image direction from the temporary 223 263 * copy is returned if that copy exists. … … 225 265 */ 226 266 Double getExifImgDir(); 227 267 268 /** 269 * Returns the image GPS track direction. The GPS track direction from the temporary 270 * copy is returned if that copy exists. 271 * @return the image GPS track direction angle 272 * @since 19387 273 */ 274 Double getExifGpsTrack(); 275 276 /** 277 * Returns the image horizontal positionning error. The image positionning error 278 * from the temporary copy is returned if that copy exists. 279 * @return the image horizontal positionning error 280 * @since 19387 281 */ 282 Double getExifHPosErr(); 283 228 284 /** 229 285 * Convenient way to determine if this entry has a EXIF time, without the cost of building a defensive copy. … … 253 309 254 310 /** 311 * Returns the Exif GPS Time value. The Exif GPS time value from the temporary copy 312 * is returned if that copy exists. 313 * @return the Exif GPS time value 314 * @since 19387 315 */ 316 Instant getExifGpsInstant(); 317 318 /** 255 319 * Returns the IPTC caption. 256 320 * @return the IPTC caption -
trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
r19271 r19387 979 979 addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_TYPE, null, null); 980 980 981 // Angle info 982 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_COURSE, "gps:course"); 983 981 984 // Accuracy info 982 985 addStringIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_FIX, "gps:fix", null); … … 985 988 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_VDOP, "gps:vdop"); 986 989 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_PDOP, "gps:pdop"); 990 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_STD_HDEV, "gps:stdhdev"); 991 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_STD_VDEV, "gps:stdvdev"); 987 992 addDoubleIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_AGEOFDGPSDATA, "gps:ageofdgpsdata"); 988 993 addIntegerIfPresent(wpt, n, gpxPrefix, GpxConstants.PT_DGPSID, "gps:dgpsid"); -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r19327 r19387 54 54 import org.openstreetmap.josm.data.gpx.GpxImageCorrelation; 55 55 import org.openstreetmap.josm.data.gpx.GpxImageCorrelationSettings; 56 import org.openstreetmap.josm.data.gpx.GpxImageDatumSettings; 56 57 import org.openstreetmap.josm.data.gpx.GpxTimeOffset; 57 58 import org.openstreetmap.josm.data.gpx.GpxTimezone; … … 169 170 Config.getPref().put("geoimage.delta", delta.formatOffset()); 170 171 Config.getPref().putBoolean("geoimage.showThumbs", yLayer.useThumbs); 172 Config.getPref().put("geoimage.datum", tfDatum.getText()); 171 173 172 174 yLayer.useThumbs = cbShowThumbs.isSelected(); … … 247 249 private ExtendedDialog syncDialog; 248 250 private JPanel outerPanel; 251 private JPanel expertPanel; 249 252 private JosmComboBox<GpxDataWrapper> cbGpx; 250 253 private JButton buttonSupport; … … 254 257 private JCheckBox cbTaggedImg; 255 258 private JCheckBox cbShowThumbs; 259 private JSeparator sepExtendedTags; 260 private JLabel labelExtTags; 261 private JLabel labelDatum; 256 262 private JLabel statusBarText; 257 263 private JSeparator sepDirectionPosition; 258 264 private ImageDirectionPositionPanel pDirectionPosition; 265 private JCheckBox cbAddGpsDatum; 266 private JosmTextField tfDatum; 259 267 260 268 // remember the last number of matched photos … … 473 481 } 474 482 483 static String loadGpsDatum() { 484 String gpsDatum = Config.getPref().get("geoimage.datum", "WGS-84"); 485 return gpsDatum; 486 } 487 475 488 @Override 476 489 public void actionPerformed(ActionEvent ae) { … … 542 555 543 556 int y = 0; 544 GBC gbc = GBC.eol(); 545 gbc.gridx = 0; 546 gbc.gridy = y++; 547 panelTf.add(panelCb, gbc); 548 549 gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 12); 550 gbc.gridx = 0; 551 gbc.gridy = y++; 557 panelTf.add(panelCb, GBC.eol().grid(0, y++)); 558 559 GBC gbc = GBC.eol().grid(0, y++).fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 12); 552 560 panelTf.add(new JSeparator(SwingConstants.HORIZONTAL), gbc); 553 561 554 gbc = GBC.std(); 555 gbc.gridx = 0; 556 gbc.gridy = y; 557 panelTf.add(new JLabel(tr("Timezone: ")), gbc); 558 559 gbc = GBC.std().fill(GridBagConstraints.HORIZONTAL); 560 gbc.gridx = 1; 561 gbc.gridy = y++; 562 panelTf.add(new JLabel(tr("Timezone: ")), GBC.std(0, y)); 563 564 gbc = GBC.std(1, y++).fill(GridBagConstraints.HORIZONTAL); 562 565 gbc.weightx = 1.; 563 566 panelTf.add(tfTimezone, gbc); 564 567 565 gbc = GBC.std(); 566 gbc.gridx = 0; 567 gbc.gridy = y; 568 gbc = GBC.std(0, y); 568 569 panelTf.add(new JLabel(tr("Offset:")), gbc); 569 570 570 gbc = GBC.std().fill(GridBagConstraints.HORIZONTAL); 571 gbc.gridx = 1; 572 gbc.gridy = y++; 571 gbc = GBC.std(1, y++).fill(GridBagConstraints.HORIZONTAL); 573 572 gbc.weightx = 1.; 574 573 panelTf.add(tfOffset, gbc); 575 574 576 gbc = GBC.std().insets(5, 5, 5, 5); 577 gbc.gridx = 2; 578 gbc.gridy = y-2; 579 gbc.gridheight = 2; 580 gbc.gridwidth = 2; 575 gbc = GBC.std(2, y-2).insets(5, 5, 5, 5).span(2, 2); 581 576 gbc.fill = GridBagConstraints.BOTH; 582 577 gbc.weightx = 0.5; 583 578 panelTf.add(buttonViewGpsPhoto, gbc); 584 579 585 gbc = GBC.std().fill(GridBagConstraints.BOTH).insets(5, 5, 5, 5); 586 gbc.gridx = 1; 587 gbc.gridy = y++; 580 gbc = GBC.std(1, y++).fill(GridBagConstraints.BOTH).insets(5, 5, 5, 5); 588 581 gbc.weightx = 0.5; 589 582 panelTf.add(buttonAdvanced, gbc); … … 595 588 panelTf.add(buttonAdjust, gbc); 596 589 597 gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0); 598 gbc.gridx = 0; 599 gbc.gridy = y++; 590 gbc = GBC.eol().grid(0, y++).fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0); 600 591 panelTf.add(new JSeparator(SwingConstants.HORIZONTAL), gbc); 601 602 gbc = GBC.eol(); 603 gbc.gridx = 0; 604 gbc.gridy = y++; 605 panelTf.add(labelPosition, gbc); 606 607 gbc = GBC.eol(); 608 gbc.gridx = 1; 609 gbc.gridy = y++; 610 panelTf.add(cbExifImg, gbc); 611 612 gbc = GBC.eol(); 613 gbc.gridx = 1; 614 gbc.gridy = y++; 615 panelTf.add(cbTaggedImg, gbc); 616 617 gbc = GBC.eol(); 618 gbc.gridx = 0; 619 gbc.gridy = y++; 620 panelTf.add(cbShowThumbs, gbc); 621 592 panelTf.add(labelPosition, GBC.eol().grid(0, y++)); 593 panelTf.add(cbExifImg, GBC.eol().grid(1, y++)); 594 panelTf.add(cbTaggedImg, GBC.eol().grid(1, y++)); 595 panelTf.add(cbShowThumbs, GBC.eol().grid(0, y++)); 596 597 //Image direction and position offset GUI 622 598 gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0); 623 599 sepDirectionPosition = new JSeparator(SwingConstants.HORIZONTAL); … … 631 607 panelTf.add(pDirectionPosition, gbc); 632 608 609 //Extended tags GUI panel 610 expertPanel = new JPanel(new GridBagLayout()); 611 gbc = GBC.eol().grid(0, 0).fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0); 612 sepExtendedTags = new JSeparator(SwingConstants.HORIZONTAL); 613 expertPanel.add(sepExtendedTags, gbc); 614 615 labelExtTags = new JLabel(tr("Extended tags")); 616 cbAddGpsDatum = new JCheckBox(tr("Set datum for images coordinates")); 617 cbAddGpsDatum.addActionListener(e -> tfDatum.setEnabled(!tfDatum.isEnabled())); 618 619 labelDatum = new JLabel(tr("Datum: ")); 620 //TODO An AutoCompComboBox would be nice to list the recent datum values. I don't have the skill to add it. 621 tfDatum = new JosmTextField(loadGpsDatum(), 8); 622 tfDatum.setToolTipText(tr("<html>Enter the datum for your images coordinates. Default value is WGS-84.<br>" + 623 "For RTK it could be your local CRS epsg code.<br>(e.g. EPSG:9782 for France mainland.)</html>")); 624 tfDatum.setEnabled(false); 625 626 expertPanel.add(labelExtTags, GBC.eol().grid(0, 1)); 627 expertPanel.add(cbAddGpsDatum, GBC.eol().grid(0, 2)); 628 expertPanel.add(labelDatum, GBC.std(1, 3)); 629 expertPanel.add(tfDatum, GBC.eol().grid(2, 3)); 630 631 //Add expertPanel to panelTf 632 gbc = GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 12, 0, 0); 633 gbc.gridy = y++; 634 panelTf.add(expertPanel, gbc); 635 633 636 final JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10)); 634 637 statusPanel.setBorder(BorderFactory.createLoweredBevelBorder()); … … 652 655 cbExifImg.addItemListener(statusBarUpdaterWithRepaint); 653 656 cbTaggedImg.addItemListener(statusBarUpdaterWithRepaint); 657 cbAddGpsDatum.addItemListener(statusBarUpdaterWithRepaint); 658 tfDatum.getDocument().addDocumentListener(statusBarUpdater); 654 659 pDirectionPosition.addChangeListenerOnComponents(statusBarUpdaterWithRepaint); 655 660 pDirectionPosition.addItemListenerOnComponents(statusBarUpdaterWithRepaint); … … 679 684 } 680 685 686 public GpxImageDatumSettings getSettings() { 687 return new GpxImageDatumSettings( 688 cbAddGpsDatum.isSelected(), 689 tfDatum.getText()); 690 } 691 681 692 @Override 682 693 public void expertChanged(boolean isExpert) { … … 689 700 if (pDirectionPosition != null) { 690 701 pDirectionPosition.setVisible(isExpert); 702 } 703 if (expertPanel != null) { 704 expertPanel.setVisible(isExpert); 691 705 } 692 706 if (syncDialog != null) { … … 787 801 lastNumMatched = GpxImageCorrelation.matchGpxTrack(dateImgLst, selGpx.data, 788 802 pDirectionPosition.isVisible() ? 789 new GpxImageCorrelationSettings(offsetMs, forceTags, pDirectionPosition.getSettings()) : 803 new GpxImageCorrelationSettings(offsetMs, forceTags, pDirectionPosition.getSettings(), 804 new GpxImageDatumSettings(cbAddGpsDatum.isSelected(), tfDatum.getText())) : 790 805 new GpxImageCorrelationSettings(offsetMs, forceTags)); 791 806 -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDirectionPositionPanel.java
r18078 r19387 29 29 private final JCheckBox cChangeImageDirection = new JCheckBox(); 30 30 private final JSpinner sOffsetDegrees = new JSpinner(new SpinnerNumberModel(0, -360, 360, 1)); 31 private final JCheckBox cSetGpxTrackTag = new JCheckBox(); 31 32 32 33 private final JSpinner sX = new JSpinner(new SpinnerNumberModel(0.0, -50.0, 50.0, 0.1)); … … 38 39 * @param changeDirectionText the text displayed for the change image direction combobox 39 40 */ 40 protected ImageDirectionPositionPanel(String changeDirectionText) { 41 protected ImageDirectionPositionPanel(String changeDirectionText, boolean hideGpxTrack) { 41 42 super(new GridBagLayout()); 42 43 … … 46 47 addSetting(tr("Offset angle in degrees:"), sOffsetDegrees); 47 48 sOffsetDegrees.setEnabled(false); 49 if (!hideGpxTrack) { 50 cChangeImageDirection.addActionListener(e -> cSetGpxTrackTag.setEnabled(!cSetGpxTrackTag.isEnabled())); 51 cSetGpxTrackTag.setText(tr("Set image course direction (from gpx track)")); 52 add(cSetGpxTrackTag, GBC.eol().insets(0, 0, 0, 5)); 53 cSetGpxTrackTag.setEnabled(false); 54 } 48 55 49 56 add(new JSeparator(SwingConstants.HORIZONTAL), … … 62 69 */ 63 70 public static ImageDirectionPositionPanel forGpxTrace() { 64 return new ImageDirectionPositionPanel(tr("Set image direction towards the next GPX waypoint")); 71 return new ImageDirectionPositionPanel(tr("Set image direction towards the next GPX waypoint"), false); 65 72 } 66 73 … … 70 77 */ 71 78 public static ImageDirectionPositionPanel forImageSequence() { 72 return new ImageDirectionPositionPanel(tr("Set image direction towards the next one")); 79 return new ImageDirectionPositionPanel(tr("Set image direction towards the next one"), true); 73 80 } 74 81 … … 87 94 cChangeImageDirection.isSelected(), 88 95 (Integer) sOffsetDegrees.getValue(), 96 cSetGpxTrackTag.isSelected(), 89 97 (Double) sX.getValue(), 90 98 (Double) sY.getValue(), … … 110 118 public void addItemListenerOnComponents(ItemListener listener) { 111 119 cChangeImageDirection.addItemListener(listener); 120 cSetGpxTrackTag.addItemListener(listener); 112 121 } 113 122 -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageMetadata.java
r19249 r19387 117 117 118 118 /** 119 * Get the exifcoordinates119 * Get the EXIF coordinates 120 120 * @return The location of the image 121 121 */ … … 123 123 124 124 /** 125 * Get the exifdirection125 * Get the EXIF direction 126 126 * @return The image direction 127 127 */ … … 129 129 130 130 /** 131 * Get the last time the source was modified 131 * Get the EXIF GPS track direction. 132 * @return The GPS track direction 133 * @since 19387 134 */ 135 Double getExifGpsTrack(); 136 137 /** 138 * Get the EXIF Horizontal positioning error. 139 * @return The image horizontal positioning error 140 * @since 19387 141 */ 142 Double getExifHPosErr(); 143 144 /** 145 * Get the GPS Differential mode. 146 * @return The image gnss fix mode 147 * @since 19387 148 */ 149 Integer getGpsDiffMode(); 150 151 /** 152 * Get the GPS 2d/3d mode. 153 * @return The image gnss 2d/3d mode 154 * @since 19387 155 */ 156 Integer getGps2d3dMode(); 157 158 /** 159 * Get the EXIF GPS DOP value. 160 * @return The image GPS DOP value 161 * @since 19387 162 */ 163 Double getExifGpsDop(); 164 165 /** 166 * Get the GPS datum value. 167 * @return The image GPS datum value 168 * @since 19387 169 */ 170 String getExifGpsDatum(); 171 172 /** 173 * Get the EXIF GPS processing method. 174 * @return The image GPS processing method 175 * @since 19387 176 */ 177 String getExifGpsProcMethod(); 178 179 /** 180 * Get the last time the source was modified. 132 181 * @return The last time the source was modified 133 182 */ … … 194 243 195 244 /** 196 * Set the exifcoordinates197 * @param exifCoor The exifcoordinates245 * Sets the EXIF coordinates 246 * @param exifCoor The EXIF coordinates 198 247 */ 199 248 void setExifCoor(ILatLon exifCoor); 200 249 201 250 /** 202 * Set the exifdirection251 * Sets the EXIF direction 203 252 * @param exifDir The direction 204 253 */ 205 254 void setExifImgDir(Double exifDir); 255 256 /** 257 * Sets the EXIF GPS track direction. 258 * @param exifGpsTrack The GPS track direction 259 * @since 19387 260 */ 261 void setExifGpsTrack(Double exifGpsTrack); 262 263 /** 264 * Sets the EXIF horizontal positioning error. 265 * @param exifHposErr the EXIF horizontal positionning error 266 * @since 19387 267 */ 268 void setExifHPosErr(Double exifHPosErr); 269 270 /** 271 * Sets the EXIF GPS DOP value. 272 * @param exifGpsDop the EXIF GPS DOP value 273 * @since 19387 274 */ 275 void setExifGpsDop(Double exifGpsDop); 276 277 /** 278 * Sets the GPS Differential mode. 279 * @param gpsDiffMode GPS Differential mode 280 * @since 19387 281 */ 282 void setGpsDiffMode(Integer gpsDiffMode); 283 284 /** 285 * Sets the GPS 2d/3d mode. 286 * @param gps2d3dMode GPS 2d/3d mode 287 * @since 19387 288 */ 289 void setGps2d3dMode(Integer gps2d3dMode); 290 291 /** 292 * Sets the GPS datum value. 293 * @param exifGpsDatum GPS datum 294 * @since 19387 295 */ 296 void setExifGpsDatum(String exifGpsDatum); 297 298 /** 299 * Sets the GPS processing method. 300 * @param exifGpsProcMethod GPS processing method 301 * @since 19387 302 */ 303 void setExifGpsProcMethod(String exifGpsProcMethod); 206 304 207 305 /** -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageUtils.java
r18592 r19387 192 192 } 193 193 194 try { 195 ifNotNull(ExifReader.readGpsTrackDirection(dirGps), image::setExifGpsTrack); 196 } catch (IndexOutOfBoundsException ex) { 197 Logging.debug(ex); 198 } 199 200 try { 201 ifNotNull(ExifReader.readHpositioningError(dirGps), image::setExifHPosErr); 202 } catch (IndexOutOfBoundsException ex) { 203 Logging.debug(ex); 204 } 205 206 try { 207 ifNotNull(ExifReader.readGpsDiffMode(dirGps), image::setGpsDiffMode); 208 } catch (IndexOutOfBoundsException ex) { 209 Logging.debug(ex); 210 } 211 212 try { 213 ifNotNull(ExifReader.readGpsMeasureMode(dirGps), image::setGps2d3dMode); 214 } catch (IndexOutOfBoundsException ex) { 215 Logging.debug(ex); 216 } 217 218 try { 219 ifNotNull(ExifReader.readGpsDop(dirGps), image::setExifGpsDop); 220 } catch (IndexOutOfBoundsException ex) { 221 Logging.debug(ex); 222 } 223 224 try { 225 ifNotNull(ExifReader.readGpsDatum(dirGps), image::setExifGpsDatum); 226 } catch (IndexOutOfBoundsException ex) { 227 Logging.debug(ex); 228 } 229 230 try { 231 ifNotNull(ExifReader.readGpsProcessingMethod(dirGps), image::setExifGpsProcMethod); 232 } catch (IndexOutOfBoundsException ex) { 233 Logging.debug(ex); 234 } 235 194 236 ifNotNull(dirGps.getGpsDate(), d -> image.setExifGpsTime(d.toInstant())); 195 237 } -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
r19266 r19387 89 89 private final ImageZoomAction imageZoomAction = new ImageZoomAction(); 90 90 private final ImageCenterViewAction imageCenterViewAction = new ImageCenterViewAction(); 91 private final ImageExtendedInfoAction imageExtendedInfoAction = new ImageExtendedInfoAction(); 91 92 private final ImageNextAction imageNextAction = new ImageNextAction(); 92 93 private final ImageRemoveAction imageRemoveAction = new ImageRemoveAction(); … … 104 105 private Future<?> imgLoadingFuture; 105 106 private boolean centerView; 107 private boolean extendedImgInfo; 106 108 107 109 // Only one instance of that class is present at one time … … 164 166 private JButton btnDeleteFromDisk; 165 167 private JToggleButton tbCentre; 168 private JToggleButton tbImgExtInfo; 166 169 /** The layer tab (used to select images when multiple layers provide images, makes for easy switching) */ 167 170 private final HideableTabbedPane layers = new HideableTabbedPane(); … … 235 238 tbCentre.setPreferredSize(buttonDim); 236 239 240 extendedImgInfo = Config.getPref().getBoolean("geoimage.viewer.extendedinfo", false); 241 tbImgExtInfo = new JToggleButton(imageExtendedInfoAction); 242 tbImgExtInfo.setSelected(extendedImgInfo); 243 tbImgExtInfo.setPreferredSize(buttonDim); 244 237 245 JButton btnZoomBestFit = new JButton(imageZoomAction); 238 246 btnZoomBestFit.setPreferredSize(buttonDim); … … 243 251 JPanel buttons = new JPanel(); 244 252 addButtonGroup(buttons, this.btnFirst, this.btnPrevious, this.btnNext, this.btnLast); 245 addButtonGroup(buttons, this.tbCentre, btnZoomBestFit); 253 addButtonGroup(buttons, this.tbCentre, btnZoomBestFit, this.tbImgExtInfo); 246 254 addButtonGroup(buttons, this.btnDelete, this.btnDeleteFromDisk); 247 255 addButtonGroup(buttons, this.btnCopyPath, this.btnOpenExternal); … … 584 592 } 585 593 594 private class ImageExtendedInfoAction extends JosmAction { 595 ImageExtendedInfoAction() { 596 super(null, new ImageProvider("info"), tr("Display image extended metadata"), Shortcut.registerShortcut( 597 "geoimage:extendedinfos", tr(GEOIMAGE_FILLER, tr("Toggle Osd extended informations")), 598 KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), 599 false, null, false); 600 } 601 602 @Override 603 public void actionPerformed(ActionEvent e) { 604 final JToggleButton button = (JToggleButton) e.getSource(); 605 extendedImgInfo = button.isEnabled() && button.isSelected(); 606 Config.getPref().putBoolean("geoimage.viewer.extendedinfo", extendedImgInfo); 607 refresh(false); 608 } 609 } 610 586 611 private class ImageRemoveAction extends JosmAction { 587 612 ImageRemoveAction() { … … 1000 1025 osd.append(tr("\nSpeed: {0} km/h", Math.round(entry.getSpeed()))); 1001 1026 } 1002 if (entry.getExifImgDir() != null) {1003 osd.append(tr("\nDirection {0}\u00b0", Math.round(entry.getExifImgDir())));1004 }1005 1006 1027 DateTimeFormatter dtf = DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.MEDIUM) 1007 // Set timezone to UTC since UTC is assumed when parsing the EXIF timestamp, 1008 // see see org.openstreetmap.josm.tools.ExifReader.readTime(com.drew.metadata.Metadata) 1009 .withZone(ZoneOffset.UTC); 1010 1028 // Set timezone to UTC since UTC is assumed when parsing the EXIF timestamp, 1029 // see see org.openstreetmap.josm.tools.ExifReader.readTime(com.drew.metadata.Metadata) 1030 .withZone(ZoneOffset.UTC); 1011 1031 if (entry.hasExifTime()) { 1012 osd.append(tr("\nEXIF time: {0}", dtf.format(entry.getExifInstant()))); 1013 } 1014 if (entry.hasGpsTime()) { 1015 osd.append(tr("\nGPS time: {0}", dtf.format(entry.getGpsInstant()))); 1032 if (Config.getPref().getBoolean("geoimage.viewer.extendedinfo", false)) { 1033 osd.append(tr("\nEXIF DTO time: {0}", dtf.format(entry.getExifInstant()))); 1034 } else { 1035 osd.append(tr("\nEXIF time: {0}", dtf.format(entry.getExifInstant()))); 1036 } 1037 } 1038 1039 if (Config.getPref().getBoolean("geoimage.viewer.extendedinfo", false)) { 1040 if (entry.getExifGpsInstant() != null) { 1041 osd.append(tr("\nEXIF GPS time: {0}", dtf.format(entry.getExifGpsInstant()))); 1042 } 1043 if (entry.hasGpsTime()) { 1044 osd.append(tr("\nCorr GPS time: {0}", dtf.format(entry.getGpsInstant()))); 1045 } 1046 if (entry.getExifImgDir() != null) { 1047 osd.append(tr("\nDirection {0}\u00b0", Math.round(entry.getExifImgDir()))); 1048 } 1049 if (entry.getExifGpsTrack() != null) { 1050 osd.append(tr("\nGPS direction: {0}\u00b0", Math.round(entry.getExifGpsTrack()))); 1051 } 1052 if (entry.getExifHPosErr() != null) { 1053 osd.append(tr("\nHpos errror: {0}m", entry.getExifHPosErr())); 1054 } 1055 if (entry.getGps2d3dMode() != null) { 1056 osd.append(tr("\n2d/3d mode: {0}d", entry.getGps2d3dMode())); 1057 } 1058 if (entry.getGpsDiffMode() != null) { 1059 osd.append(tr("\nDifferential: {0}", entry.getGpsDiffMode())); 1060 } 1061 if (entry.getExifGpsDop() != null) { 1062 osd.append(tr("\nDOP: {0}", entry.getExifGpsDop())); 1063 } 1064 if (entry.getExifGpsDatum() != null) { 1065 osd.append(tr("\nDatum: {0}", entry.getExifGpsDatum().toString())); 1066 } 1067 if (entry.getExifGpsProcMethod() != null) { 1068 osd.append(tr("\nProc. method: {0}", entry.getExifGpsProcMethod().toString())); 1069 } 1016 1070 } 1017 1071 Optional.ofNullable(entry.getIptcCaption()).map(s -> tr("\nCaption: {0}", s)).ifPresent(osd::append); … … 1146 1200 } 1147 1201 1202 /** 1203 * Reload the image or reload only the image info. Call this if want to update the OSD. 1204 * @param imageChanged reload the image if true. Reload only the OSD if false. 1205 * @since 19387 1206 */ 1207 public void refresh(boolean imageChanged) { 1208 if (SwingUtilities.isEventDispatchThread()) { 1209 this.updateButtonsNonNullEntry(currentEntry, imageChanged); 1210 } else { 1211 GuiHelper.runInEDT(this::refresh); 1212 } 1213 } 1214 1148 1215 private void registerOnLayer(Layer layer) { 1149 1216 if (layer instanceof IGeoImageLayer) { -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/RemoteEntry.java
r19050 r19387 38 38 private Integer exifOrientation; 39 39 private Double elevation; 40 private Integer gpsDiffMode; 41 private Integer gps2d3dMode; 42 private Double exifHPosErr; 43 private Double exifGpsDop; 44 private String exifGpsDatum; 45 private String exifGpsProcMethod; 40 46 private Double speed; 41 47 private Double exifImgDir; 48 private Double exifGpsTrack; 42 49 private ILatLon exifCoor; 43 50 private Instant exifTime; … … 118 125 } 119 126 127 /** 128 * @since 19387 129 */ 130 @Override 131 public void setGpsDiffMode(Integer gpsDiffMode) { 132 this.gpsDiffMode = gpsDiffMode; 133 } 134 135 /** 136 * @since 19387 137 */ 138 @Override 139 public void setGps2d3dMode(Integer gps2d3dMode) { 140 this.gps2d3dMode = gps2d3dMode; 141 } 142 143 /** 144 * @since 19387 145 */ 146 @Override 147 public void setExifGpsDatum(String exifGpsDatum) { 148 this.exifGpsDatum = exifGpsDatum; 149 } 150 151 /** 152 * @since 19387 153 */ 154 @Override 155 public void setExifGpsProcMethod(String exifGpsProcMethod) { 156 this.exifGpsProcMethod = exifGpsProcMethod; 157 } 158 120 159 @Override 121 160 public void setElevation(Double elevation) { … … 153 192 } 154 193 194 /** 195 * @since 19387 196 */ 197 @Override 198 public void setExifGpsTrack(Double exifGpsTrack) { 199 this.exifGpsTrack = exifGpsTrack; 200 } 201 202 /** 203 * @since 19387 204 */ 205 @Override 206 public void setExifHPosErr(Double exifHPosError) { 207 this.exifHPosErr = exifHPosError; 208 } 209 210 /** 211 * @since 19387 212 */ 213 @Override 214 public void setExifGpsDop(Double exifGpsDop) { 215 this.exifGpsDop = exifGpsDop; 216 } 217 155 218 @Override 156 219 public void setIptcCaption(String iptcCaption) { … … 213 276 } 214 277 278 /** 279 * @since 19387 280 */ 281 @Override 282 public Integer getGpsDiffMode() { 283 return this.gpsDiffMode; 284 } 285 286 /** 287 * @since 19387 288 */ 289 @Override 290 public Integer getGps2d3dMode() { 291 return this.gps2d3dMode; 292 } 293 294 /** 295 * @since 19387 296 */ 297 @Override 298 public String getExifGpsDatum() { 299 return this.exifGpsDatum; 300 } 301 302 /** 303 * @since 19387 304 */ 305 @Override 306 public String getExifGpsProcMethod() { 307 return this.exifGpsProcMethod; 308 } 309 310 /** 311 * @since 19387 312 */ 215 313 @Override 216 314 public Double getExifImgDir() { 217 315 return this.exifImgDir; 316 } 317 318 /** 319 * @since 19387 320 */ 321 @Override 322 public Double getExifGpsTrack() { 323 return this.exifGpsTrack; 324 } 325 326 /** 327 * @since 19387 328 */ 329 @Override 330 public Double getExifHPosErr() { 331 return this.exifHPosErr; 332 } 333 334 /** 335 * @since 19387 336 */ 337 @Override 338 public Double getExifGpsDop() { 339 return this.exifGpsDop; 218 340 } 219 341 … … 336 458 return Objects.hash(this.uri, this.pos, 337 459 this.exifOrientation, this.elevation, this.speed, this.exifImgDir, 338 this.exifCoor, this.exifTime, this.exifGpsTime, this.gpsTime, 339 this.iptcObjectName, this.iptcCaption, this.iptcHeadline, this.iptcKeywords, 340 this.projection, this.title); 460 this.exifGpsTrack, this.exifCoor, this.exifTime, this.exifGpsTime, 461 this.gpsTime, this.exifHPosErr, this.exifGpsDop, this.gpsDiffMode, 462 this.gps2d3dMode, this.exifGpsDatum, this.exifGpsProcMethod, 463 this.iptcObjectName, this.iptcCaption, this.iptcHeadline, 464 this.iptcKeywords, this.projection, this.title); 341 465 } 342 466 … … 353 477 && Objects.equals(this.exifGpsTime, other.exifGpsTime) 354 478 && Objects.equals(this.exifImgDir, other.exifImgDir) 479 && Objects.equals(this.exifGpsTrack, other.exifGpsTrack) 480 && Objects.equals(this.exifHPosErr, other.exifHPosErr) 481 && Objects.equals(this.exifGpsDop, other.exifGpsDop) 355 482 && Objects.equals(this.exifOrientation, other.exifOrientation) 356 483 && Objects.equals(this.exifTime, other.exifTime) … … 363 490 && Objects.equals(this.projection, other.projection) 364 491 && Objects.equals(this.speed, other.speed) 492 && Objects.equals(this.gpsDiffMode, other.gpsDiffMode) 493 && Objects.equals(this.gps2d3dMode, other.gps2d3dMode) 494 && Objects.equals(this.exifGpsDatum, other.exifGpsDatum) 495 && Objects.equals(this.exifGpsProcMethod, other.exifGpsProcMethod) 365 496 && Objects.equals(this.title, other.title); 366 497 } -
trunk/src/org/openstreetmap/josm/io/nmea/NmeaParser.java
r19325 r19387 467 467 if (!accu.isEmpty() && currentwp != null) { 468 468 Double.parseDouble(accu); 469 currentwp.put( "course", accu);469 currentwp.put(GpxConstants.PT_COURSE, accu); 470 470 } 471 471 } … … 543 543 if (!accu.isEmpty() && !currentwp.attr.containsKey("course")) { 544 544 Double.parseDouble(accu); 545 currentwp.put( "course", accu);545 currentwp.put(GpxConstants.PT_COURSE, accu); 546 546 } 547 547 -
trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java
r18069 r19387 23 23 * Session exporter for {@link GeoImageLayer}. 24 24 * @since 5505 25 * @since 19387 exifGpsTrack, exifHPosErr, gpsDiffMode, gps2d3dMode, exifGpsDop, exifGpsDatum, exifGpsProcMethod exporter added 25 26 */ 26 27 public class GeoImageSessionExporter extends AbstractSessionExporter<GeoImageLayer> { … … 106 107 addAttr("exif-image-direction", entry.getExifImgDir().toString(), imgElem, support); 107 108 } 109 if (entry.getExifGpsTrack() != null) { 110 addAttr("exif-gps-track", entry.getExifGpsTrack().toString(), imgElem, support); 111 } 112 if (entry.getExifHPosErr() != null) { 113 addAttr("exif-gps-hposerr", entry.getExifHPosErr().toString(), imgElem, support); 114 } 115 if (entry.getGpsDiffMode() != null) { 116 addAttr("exif-gps-diffmode", entry.getGpsDiffMode().toString(), imgElem, support); 117 } 118 if (entry.getGps2d3dMode() != null) { 119 addAttr("exif-gps-2d3dmode", entry.getGps2d3dMode().toString(), imgElem, support); 120 } 121 if (entry.getExifGpsDop() != null) { 122 addAttr("exif-gps-dop", entry.getExifGpsDop().toString(), imgElem, support); 123 } 124 if (entry.getExifGpsDatum() != null) { 125 addAttr("exif-gps-datum", entry.getExifGpsDatum().toString(), imgElem, support); 126 } 127 if (entry.getExifGpsProcMethod() != null) { 128 addAttr("exif-gps-procmethod", entry.getExifGpsProcMethod().toString(), imgElem, support); 129 } 108 130 if (entry.hasNewGpsData()) { 109 131 addAttr("is-new-gps-data", Boolean.toString(entry.hasNewGpsData()), imgElem, support); -
trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java
r19050 r19387 26 26 * Session importer for {@link GeoImageLayer}. 27 27 * @since 5505 28 * @since 19387 exifGpsTrack, exifHPosErr, gpsDiffMode, gps2d3dMode, exifGpsDop, exifGpsDatum, exifGpsProcMethod importer added 28 29 */ 29 30 public class GeoImageSessionImporter implements SessionLayerImporter { … … 109 110 entry.setExifImgDir(Double.valueOf(attrElem.getTextContent())); 110 111 break; 112 case "exif-gps-track": 113 entry.setExifGpsTrack(Double.valueOf(attrElem.getTextContent())); 114 break; 115 case "exif-gps-hposerr": 116 entry.setExifHPosErr(Double.valueOf(attrElem.getTextContent())); 117 break; 118 case "exif-gps-diffmode": 119 entry.setGpsDiffMode(Integer.valueOf(attrElem.getTextContent())); 120 break; 121 case "exif-gps-2d3dmode": 122 entry.setGps2d3dMode(Integer.valueOf(attrElem.getTextContent())); 123 break; 124 case "exif-gps-dop": 125 entry.setExifGpsDop(Double.valueOf(attrElem.getTextContent())); 126 break; 127 case "exif-gps-datum": 128 entry.setExifGpsDatum(attrElem.getTextContent()); 129 break; 130 case "exif-gps-procmethod": 131 entry.setExifGpsProcMethod(attrElem.getTextContent()); 132 break; 111 133 case "is-new-gps-data": 112 134 if (Boolean.parseBoolean(attrElem.getTextContent())) { -
trunk/src/org/openstreetmap/josm/tools/ExifReader.java
r19101 r19387 125 125 126 126 /** 127 * Returns the GPS date/time from the given JPEG file. 128 * @param filename The JPEG file to read 129 * @return The GPS date/time read in the EXIF section, or {@code null} if not found 130 * @since 19387 131 */ 132 public static Instant readGpsInstant(File filename) { 133 try { 134 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 135 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 136 return readGpsInstant(dirGps); 137 } catch (JpegProcessingException | IOException e) { 138 Logging.error(e); 139 } 140 return null; 141 } 142 143 /** 144 * Returns the GPS date/time from the given JPEG file. 145 * @param dirGps The EXIF GPS directory 146 * @return The GPS date/time read in the EXIF section, or {@code null} if not found 147 * @since 19387 148 */ 149 public static Instant readGpsInstant(GpsDirectory dirGps) { 150 if (dirGps != null) { 151 try { 152 Instant dateTimeStamp = dirGps.getGpsDate().toInstant(); 153 return dateTimeStamp; 154 } catch (UncheckedParseException | DateTimeException e) { 155 Logging.error(e); 156 } 157 } 158 return null; 159 } 160 161 /** 127 162 * Returns the image orientation of the given JPEG file. 128 163 * @param filename The JPEG file to read … … 219 254 } 220 255 256 /** 257 * Returns the GPS track direction of the given JPEG file. 258 * @param filename The JPEG file to read 259 * @return The GPS track direction of the image when it was captures (in degrees between 0.0 and 359.99), 260 * or {@code null} if not found 261 * @since 19387 262 */ 263 public static Double readGpsTrackDirection(File filename) { 264 try { 265 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 266 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 267 return readGpsTrackDirection(dirGps); 268 } catch (JpegProcessingException | IOException e) { 269 Logging.error(e); 270 } 271 return null; 272 } 273 274 /** 275 * Returns the GPS track direction of the given EXIF GPS directory. 276 * @param dirGps The EXIF GPS directory 277 * @return The GPS track direction of the image when it was captured (in degrees between 0.0 and 359.99), 278 * or {@code null} if missing or if {@code dirGps} is null 279 * @since 19387 280 */ 281 public static Double readGpsTrackDirection(GpsDirectory dirGps) { 282 if (dirGps != null) { 283 Rational trackDirection = dirGps.getRational(GpsDirectory.TAG_TRACK); 284 if (trackDirection != null) { 285 return trackDirection.doubleValue(); 286 } 287 } 288 return null; 289 } 290 221 291 private static double readAxis(GpsDirectory dirGps, int gpsTag, int gpsTagRef, char cRef) throws MetadataException { 222 292 double value; … … 319 389 } 320 390 return ele; 391 } 392 } 393 return null; 394 } 395 396 /** 397 * Returns the GPS horizontal positionning error of the given JPEG file. 398 * @param filename The JPEG file to read 399 * @return The GPS horizontal positionning error of the camera when the image was captured (in m), 400 * or {@code null} if not found 401 * @since 19387 402 */ 403 public static Double readHpositioningError(File filename) { 404 try { 405 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 406 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 407 return readHpositioningError(dirGps); 408 } catch (JpegProcessingException | IOException e) { 409 Logging.error(e); 410 } 411 return null; 412 } 413 414 /** 415 * Returns the GPS horizontal positionning error of the given EXIF GPS directory. 416 * @param dirGps The EXIF GPS directory 417 * @return The GPS horizontal positionning error of the camera when the image was captured (in m), 418 * or {@code null} if missing or if {@code dirGps} is null 419 * @since 19387 420 */ 421 public static Double readHpositioningError(GpsDirectory dirGps) { 422 if (dirGps != null) { 423 Double hposerr = dirGps.getDoubleObject(GpsDirectory.TAG_H_POSITIONING_ERROR); 424 if (hposerr != null) { 425 return hposerr.doubleValue(); 426 } 427 } 428 return null; 429 } 430 431 /** 432 * Returns the GPS differential mode of the given JPEG file. 433 * @param filename The JPEG file to read 434 * @return The GPS differential mode of the camera when the image was captured, 435 * <ul> 436 * <li>0 : no differential correction</li> 437 * <li>1 : differential correction</li> 438 * <li>or {@code null} if not found</li> 439 * </ul> 440 * @since 19387 441 */ 442 public static Integer readGpsDiffMode(File filename) { 443 try { 444 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 445 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 446 return readGpsDiffMode(dirGps); 447 } catch (JpegProcessingException | IOException e) { 448 Logging.error(e); 449 } 450 return null; 451 } 452 453 /** 454 * Returns the GPS differential mode of the given EXIF GPS directory. 455 * @param dirGps The EXIF GPS directory 456 * @return The GPS differential mode of the camera when the image was captured, 457 * <ul> 458 * <li>0 : no differential correction</li> 459 * <li>1 : differential correction</li> 460 * <li>or {@code null} if missing or if {@code dirGps} is null</li> 461 * </ul> 462 * @since 19387 463 */ 464 public static Integer readGpsDiffMode(GpsDirectory dirGps) { 465 if (dirGps != null) { 466 Integer gpsDiffMode = dirGps.getInteger(GpsDirectory.TAG_DIFFERENTIAL); 467 if (gpsDiffMode != null) { 468 return gpsDiffMode.intValue(); 469 } 470 } 471 return null; 472 } 473 474 /** 475 * Returns the GPS 2d/3d mode of the given JPEG file. 476 * @param filename The JPEG file to read 477 * @return The GPS 2d/3d mode of the camera when the image was captured, 478 * <ul> 479 * <li>2 : 2d mode</li> 480 * <li>2 : 3d mode</li> 481 * <li>or {@code null} if not found</li> 482 * </ul> 483 * @since 19387 484 */ 485 public static Integer readGpsMeasureMode(File filename) { 486 try { 487 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 488 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 489 return readGpsMeasureMode(dirGps); 490 } catch (JpegProcessingException | IOException e) { 491 Logging.error(e); 492 } 493 return null; 494 } 495 496 /** 497 * Returns the GPS 2d/3d mode of the given EXIF GPS directory. 498 * @param dirGps The EXIF GPS directory 499 * @return The 2d/3d mode of the camera when the image was captured, 500 * <ul> 501 * <li>2 : 2d mode</li> 502 * <li>3 : 3d mode</li> 503 * <li>or {@code null} if missing or if {@code dirGps} is null</li> 504 * </ul> 505 * @since 19387 506 */ 507 public static Integer readGpsMeasureMode(GpsDirectory dirGps) { 508 if (dirGps != null) { 509 Integer gps2d3dMode = dirGps.getInteger(GpsDirectory.TAG_MEASURE_MODE); 510 if (gps2d3dMode != null) { 511 return gps2d3dMode.intValue(); 512 } 513 } 514 return null; 515 } 516 517 /** 518 * Returns the GPS DOP value of the given JPEG file. 519 * @param filename The JPEG file to read 520 * @return The GPS DOP value of the camera when the image was captured, 521 * or {@code null} if not found 522 * @since 19387 523 */ 524 public static Double readGpsDop(File filename) { 525 try { 526 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 527 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 528 return readGpsDop(dirGps); 529 } catch (JpegProcessingException | IOException e) { 530 Logging.error(e); 531 } 532 return null; 533 } 534 535 /** 536 * Returns the GPS DOP value of the given EXIF GPS directory. 537 * @param dirGps The EXIF GPS directory 538 * @return The GPS DOP value of the camera when the image was captured, 539 * or {@code null} if missing or if {@code dirGps} is null 540 * @since 19387 541 */ 542 public static Double readGpsDop(GpsDirectory dirGps) { 543 if (dirGps != null) { 544 Double gpsDop = dirGps.getDoubleObject(GpsDirectory.TAG_DOP); 545 if (gpsDop != null) { 546 return gpsDop.doubleValue(); 547 } 548 } 549 return null; 550 } 551 552 /** 553 * Returns the GPS datum value of the given JPEG file. 554 * @param filename The JPEG file to read 555 * @return The GPS datum value of the camera when the image was captured, 556 * or {@code null} if not found 557 * @since 19387 558 */ 559 public static String readGpsDatum(File filename) { 560 try { 561 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 562 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 563 return readGpsDatum(dirGps); 564 } catch (JpegProcessingException | IOException e) { 565 Logging.error(e); 566 } 567 return null; 568 } 569 570 /** 571 * Returns the GPS datum value of the given EXIF GPS directory. 572 * @param dirGps The EXIF GPS directory 573 * @return The GPS datum value of the camera when the image was captured, 574 * or {@code null} if missing or if {@code dirGps} is null 575 * @since 19387 576 */ 577 public static String readGpsDatum(GpsDirectory dirGps) { 578 if (dirGps != null) { 579 String gpsDatum = dirGps.getString(GpsDirectory.TAG_MAP_DATUM); 580 if (gpsDatum != null) { 581 return gpsDatum.toString(); 582 } 583 } 584 return null; 585 } 586 587 /** 588 * Return the GPS processing method of the given JPEG file. 589 * @param filename The JPEG file to read 590 * @return The GPS processing method. Possible values from the EXIF specs are: 591 * <ul> 592 * <li>GPS</li> 593 * <li>QZSS</li> 594 * <li>GALILEO</li> 595 * <li>GLONASS</li> 596 * <li>BEIDOU</li> 597 * <li>NAVIC</li> 598 * <li>CELLID</li> 599 * <li>WLAN</li> 600 * <li>MANUAL</li> 601 * </ul> 602 * Other values, and combined space separated values are possible too. 603 * or {@code null} if missing 604 * @since 19387 605 */ 606 public static String readGpsProcessingMethod(File filename) { 607 try { 608 final Metadata metadata = JpegMetadataReader.readMetadata(filename); 609 final GpsDirectory dirGps = metadata.getFirstDirectoryOfType(GpsDirectory.class); 610 return readGpsProcessingMethod(dirGps); 611 } catch (JpegProcessingException | IOException e) { 612 Logging.error(e); 613 } 614 return null; 615 } 616 617 /** 618 * Return the GPS processing method of the given EXIF GPS directory. 619 * @param dirGps The EXIF GPS directory 620 * @return The GPS processing method. Possible values from the EXIF specs are: 621 * <ul> 622 * <li>GPS</li> 623 * <li>QZSS</li> 624 * <li>GALILEO</li> 625 * <li>GLONASS</li> 626 * <li>BEIDOU</li> 627 * <li>NAVIC</li> 628 * <li>CELLID</li> 629 * <li>WLAN</li> 630 * <li>MANUAL</li> 631 * </ul> 632 * Other values, and combined space separated values are possible too. 633 * or {@code null} if missing or if {@code dirGps} is null 634 * @since 19387 635 */ 636 public static String readGpsProcessingMethod(GpsDirectory dirGps) { 637 if (dirGps != null) { 638 String gpsProcessingMethod = dirGps.getDescription(GpsDirectory.TAG_PROCESSING_METHOD); 639 if (gpsProcessingMethod != null) { 640 return gpsProcessingMethod.toString(); 321 641 } 322 642 } -
trunk/test/unit/org/openstreetmap/josm/data/ImageDataTest.java
r18444 r19387 446 446 447 447 @Test 448 void testUpdateHPosErr() { 449 List<ImageEntry> list = getOneImage(); 450 ImageData data = new ImageData(list); 451 452 new Expectations(list.get(0)) {{ 453 list.get(0).setExifHPosErr(1.23); 454 list.get(0).flagNewGpsData(); 455 }}; 456 data.updateImageHPosErr(list.get(0), 1.23); 457 } 458 459 @Test 460 void testUpdateGpsDatum() { 461 List<ImageEntry> list = getOneImage(); 462 ImageData data = new ImageData(list); 463 464 new Expectations(list.get(0)) {{ 465 list.get(0).setExifGpsDatum("WGS-84"); 466 list.get(0).flagNewGpsData(); 467 }}; 468 data.updateImageExifGpsDatum(list.get(0), "WGS-84"); 469 } 470 471 @Test 472 void testUpdateGpsTrack() { 473 List<ImageEntry> list = getOneImage(); 474 ImageData data = new ImageData(list); 475 476 new Expectations(list.get(0)) {{ 477 list.get(0).setExifGpsTrack(180.5); 478 list.get(0).flagNewGpsData(); 479 }}; 480 data.updateImageGpsTrack(list.get(0), 180.5); 481 } 482 483 @Test 484 void testUpdateGpsDop() { 485 List<ImageEntry> list = getOneImage(); 486 ImageData data = new ImageData(list); 487 488 new Expectations(list.get(0)) {{ 489 list.get(0).setExifGpsDop(1.9); 490 list.get(0).flagNewGpsData(); 491 }}; 492 data.updateImageExifGpsDop(list.get(0), 1.9); 493 } 494 495 @Test 496 void testUpdateGpsProcMethod() { 497 List<ImageEntry> list = getOneImage(); 498 ImageData data = new ImageData(list); 499 500 new Expectations(list.get(0)) {{ 501 list.get(0).setExifGpsProcMethod("GNSS RTK CORRELATION"); 502 list.get(0).flagNewGpsData(); 503 }}; 504 data.updateImageExifGpsProcMethod(list.get(0), "GNSS RTK CORRELATION"); 505 } 506 507 @Test 508 void testUpdateGpsDifferentialMode() { 509 List<ImageEntry> list = getOneImage(); 510 ImageData data = new ImageData(list); 511 512 new Expectations(list.get(0)) {{ 513 list.get(0).setGpsDiffMode(1); 514 list.get(0).flagNewGpsData(); 515 }}; 516 data.updateImageGpsDiffMode(list.get(0), 1); 517 } 518 519 @Test 520 void testUpdateGps2d3dMode() { 521 List<ImageEntry> list = getOneImage(); 522 ImageData data = new ImageData(list); 523 524 new Expectations(list.get(0)) {{ 525 list.get(0).setGps2d3dMode(3); 526 list.get(0).flagNewGpsData(); 527 }}; 528 data.updateImageGps2d3dMode(list.get(0), 3); 529 } 530 531 @Test 448 532 void testTriggerListenerOnUpdate() { 449 533 List<ImageEntry> list = getOneImage(); -
trunk/test/unit/org/openstreetmap/josm/data/gpx/GpxImageCorrelationTest.java
r18853 r19387 351 351 assertEquals(Double.valueOf(150.0d), GpxImageCorrelation.getElevation(wp)); 352 352 } 353 354 /** 355 * Unit test of {@link GpxImageCorrelation#getHPosErr} 356 */ 357 @Test 358 void testGetHorizontalPosError() { 359 assertNull(GpxImageCorrelation.getHPosErr(null)); 360 WayPoint wp = new WayPoint(LatLon.ZERO); 361 assertNull(GpxImageCorrelation.getHPosErr(wp)); 362 wp.put(GpxConstants.PT_STD_HDEV, 1.5f); 363 assertEquals(1.5f, GpxImageCorrelation.getHPosErr(wp)); 364 } 365 366 /** 367 * Unit test of {@link GpxImageCorrelation#getGpsDop} 368 */ 369 @Test 370 void testGetGpsDop() { 371 assertNull(GpxImageCorrelation.getGpsDop(null)); 372 WayPoint wp = new WayPoint(LatLon.ZERO); 373 assertNull(GpxImageCorrelation.getGpsDop(wp)); 374 wp.put(GpxConstants.PT_HDOP, 2.1f); 375 assertEquals(2.1f, GpxImageCorrelation.getGpsDop(wp)); 376 wp.put(GpxConstants.PT_PDOP, 0.9f); 377 assertEquals(0.9f, GpxImageCorrelation.getGpsDop(wp)); 378 wp.put(GpxConstants.PT_PDOP, 1.2d); 379 assertEquals(1.2d, GpxImageCorrelation.getGpsDop(wp)); 380 } 381 382 /** 383 * Unit test of {@link GpxImageCorrelation#getGpsTrack} 384 */ 385 @Test 386 void testGetGpsTrack() { 387 assertNull(GpxImageCorrelation.getHPosErr(null)); 388 WayPoint wp = new WayPoint(LatLon.ZERO); 389 assertNull(GpxImageCorrelation.getGpsTrack(wp)); 390 wp.put(GpxConstants.PT_COURSE, ""); 391 assertNull(GpxImageCorrelation.getGpsTrack(wp)); 392 wp.put(GpxConstants.PT_COURSE, "not a number"); 393 assertNull(GpxImageCorrelation.getGpsTrack(wp)); 394 wp.put(GpxConstants.PT_COURSE, "167.0"); 395 assertEquals(Double.valueOf(167.0d), GpxImageCorrelation.getGpsTrack(wp), 0.01d); 396 } 397 398 /** 399 * Unit test of {@link GpxImageCorrelation#getGpsProcMethod} 400 */ 401 @Test 402 void testGetGpsProcMethod() { 403 final List<String> positionningModes = Arrays.asList("none", "manual", "estimated", "2d", "3d", "dgps", "float rtk", "rtk"); 404 assertNull(GpxImageCorrelation.getGpsProcMethod(null, null, positionningModes)); 405 assertNull(GpxImageCorrelation.getGpsProcMethod("", "", positionningModes)); 406 assertNull(GpxImageCorrelation.getGpsProcMethod("3d", null, positionningModes)); 407 assertNull(GpxImageCorrelation.getGpsProcMethod("", "dgps", positionningModes)); 408 assertEquals("MANUAL CORRELATION", GpxImageCorrelation.getGpsProcMethod("manual", "rtk", positionningModes)); 409 assertEquals("ESTIMATED CORRELATION", GpxImageCorrelation.getGpsProcMethod("estimated", "2d", positionningModes)); 410 assertEquals("GNSS DGPS CORRELATION", GpxImageCorrelation.getGpsProcMethod("rtk", "dgps", positionningModes)); 411 assertEquals("GNSS RTK_FLOAT CORRELATION", GpxImageCorrelation.getGpsProcMethod("float rtk", "rtk", positionningModes)); 412 assertEquals("GNSS RTK_FIX CORRELATION", GpxImageCorrelation.getGpsProcMethod("rtk", "rtk", positionningModes)); 413 } 414 415 /** 416 * Unit test of {@link GpxImageCorrelation#getGps2d3dMode} 417 */ 418 @Test 419 void testGetGps2d3dMode() { 420 final List<String> positionningModes = Arrays.asList("none", "manual", "estimated", "2d", "3d", "dgps", "float rtk", "rtk"); 421 assertNull(GpxImageCorrelation.getGps2d3dMode(null, null, positionningModes)); 422 assertNull(GpxImageCorrelation.getGps2d3dMode("", "", positionningModes)); 423 assertNull(GpxImageCorrelation.getGps2d3dMode("3d", null, positionningModes)); 424 assertNull(GpxImageCorrelation.getGps2d3dMode("", "dgps", positionningModes)); 425 assertNull(GpxImageCorrelation.getGps2d3dMode("estimated", "rtk", positionningModes)); 426 assertEquals(2, GpxImageCorrelation.getGps2d3dMode("2d", "2d", positionningModes)); 427 assertEquals(2, GpxImageCorrelation.getGps2d3dMode("2d", "3d", positionningModes)); 428 assertEquals(3, GpxImageCorrelation.getGps2d3dMode("3d", "dgps", positionningModes)); 429 } 353 430 } -
trunk/test/unit/org/openstreetmap/josm/tools/ExifReaderTest.java
r18853 r19387 22 22 */ 23 23 class ExifReaderTest { 24 private File orientationSampleFile, directionSampleFile; 24 private File orientationSampleFile, directionSampleFile, positionErrorSampleFile; 25 25 26 26 /** … … 31 31 directionSampleFile = new File("nodist/data/exif-example_direction.jpg"); 32 32 orientationSampleFile = new File("nodist/data/exif-example_orientation=6.jpg"); 33 positionErrorSampleFile = new File("nodist/data/exif-position-error.jpg"); 33 34 } 34 35 … … 56 57 } 57 58 59 /** 60 * Test reading GPS date and time 61 */ 62 @Test 63 void testReadGpsDateTime() { 64 Instant date = ExifReader.readGpsInstant(positionErrorSampleFile); 65 assertEquals(Instant.parse("2024-04-30T16:36:42Z"), date); 66 } 67 58 68 /** 59 69 * Test orientation extraction … … 102 112 103 113 /** 114 * Test horizontal position error extraction 115 */ 116 @Test 117 void testReadHorPosError() { 118 assertEquals(Double.valueOf(0.014), ExifReader.readHpositioningError(positionErrorSampleFile)); 119 } 120 121 /** 122 * Test GPS track course extraction 123 */ 124 @Test 125 void testReadGpsTrack() { 126 assertEquals(Double.valueOf(298), ExifReader.readGpsTrackDirection(positionErrorSampleFile)); 127 } 128 129 /** 130 * Test GPS differential mode extraction 131 */ 132 @Test 133 void testReadGpsDiffmode() { 134 assertEquals(Integer.valueOf(1), ExifReader.readGpsDiffMode(positionErrorSampleFile)); 135 } 136 137 /** 138 * Test GPS DOP value extraction 139 */ 140 @Test 141 void testReadGpsDop() { 142 assertEquals(Double.valueOf(0.92), ExifReader.readGpsDop(positionErrorSampleFile)); 143 } 144 145 /** 146 * Test GPS measure mode (2D/3D) extraction 147 */ 148 @Test 149 void testReadGps2d3dMode() { 150 assertEquals(Integer.valueOf(3), ExifReader.readGpsMeasureMode(positionErrorSampleFile)); 151 } 152 153 /** 154 * Test GPS datum extraction 155 */ 156 @Test 157 void testReadGpsDatum() { 158 assertEquals(String.valueOf("EPSG:9782"), ExifReader.readGpsDatum(positionErrorSampleFile)); 159 } 160 161 /** 162 * Test GPS processing method extraction 163 */ 164 @Test 165 void testReadGpsProcMethod() { 166 assertEquals(String.valueOf("GNSS RTK_FIX CORRELATION"), ExifReader.readGpsProcessingMethod(positionErrorSampleFile)); 167 } 168 169 /** 104 170 * Non-regression test for ticket <a href="https://josm.openstreetmap.de/ticket/11685">#11685</a> 105 171 * @throws IOException if an error occurs during reading
Note:
See TracChangeset
for help on using the changeset viewer.