/** output a point */ private void wayPoint(WayPoint pnt, int mode) { String type; switch (mode) { case WAY_POINT: type = "wpt"; break; case ROUTE_POINT: type = "rtept"; break; case TRACK_POINT: type = "trkpt"; break; default: throw new RuntimeException(tr("Unknown mode {0}.", mode)); } if (pnt != null) { LatLon c = pnt.getCoor(); String coordAttr = "lat=\"" + c.lat() + "\" lon=\"" + c.lon() + '\"'; if (pnt.attr.isEmpty()) { inline(type, coordAttr); } else { openAtt(type, coordAttr); writeAttr(pnt, WPT_KEYS); closeln(type); } } }
static int matchPoints( List<ImageEntry> images, WayPoint prevWp, long prevWpTime, WayPoint curWp, long curWpTime, long offset) { // Time between the track point and the previous one, 5 sec if first point, i.e. photos take // 5 sec before the first track point can be assumed to be take at the starting position long interval = prevWpTime > 0 ? Math.abs(curWpTime - prevWpTime) : 5 * 1000; int ret = 0; // i is the index of the timewise last photo that has the same or earlier EXIF time int i = getLastIndexOfListBefore(images, curWpTime); // no photos match if (i < 0) return 0; Double speed = null; Double prevElevation = null; if (prevWp != null) { double distance = prevWp.getCoor().greatCircleDistance(curWp.getCoor()); // This is in km/h, 3.6 * m/s if (curWpTime > prevWpTime) { speed = 3600 * distance / (curWpTime - prevWpTime); } prevElevation = getElevation(prevWp); } Double curElevation = getElevation(curWp); // First trackpoint, then interval is set to five seconds, i.e. photos up to five seconds // before the first point will be geotagged with the starting point if (prevWpTime == 0 || curWpTime <= prevWpTime) { while (i >= 0) { final ImageEntry curImg = images.get(i); long time = curImg.getExifTime().getTime(); if (time > curWpTime || time < curWpTime - interval) { break; } if (curImg.tmp.getPos() == null) { curImg.tmp.setPos(curWp.getCoor()); curImg.tmp.setSpeed(speed); curImg.tmp.setElevation(curElevation); curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset)); curImg.flagNewGpsData(); ret++; } i--; } return ret; } // This code gives a simple linear interpolation of the coordinates between current and // previous track point assuming a constant speed in between while (i >= 0) { ImageEntry curImg = images.get(i); long imgTime = curImg.getExifTime().getTime(); if (imgTime < prevWpTime) { break; } if (curImg.tmp.getPos() == null && prevWp != null) { // The values of timeDiff are between 0 and 1, it is not seconds but a dimensionless // variable double timeDiff = (double) (imgTime - prevWpTime) / interval; curImg.tmp.setPos(prevWp.getCoor().interpolate(curWp.getCoor(), timeDiff)); curImg.tmp.setSpeed(speed); if (curElevation != null && prevElevation != null) { curImg.tmp.setElevation(prevElevation + (curElevation - prevElevation) * timeDiff); } curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset)); curImg.flagNewGpsData(); ret++; } i--; } return ret; }