Ignore:
Timestamp:
2009-05-05T17:23:06+02:00 (16 years ago)
Author:
stoecker
Message:

close #2306 - patch by TAA - better match images

Location:
applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojDialog.java

    r13927 r14916  
    167167            }
    168168            if (entry.speed != null) {
    169                 osd.append(tr("\n{0} km/h", (long) (3.6 * entry.speed)));
     169                osd.append(tr("\n{0} km/h", Math.round(entry.speed)));
    170170            }
    171171            imgDisplay.setOsdText(osd.toString());
  • applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojLayer.java

    r13927 r14916  
    7070        LatLon coor;
    7171        EastNorth pos;
    72         /** Speed in meter per second */
     72        /** Speed in kilometer per second */
    7373        Double speed;
    7474        /** Elevation (altitude) in meters */
  • applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/CorrelateGpxWithImages.java

    r13927 r14916  
    962962    }
    963963
    964     private int matchPoints(ArrayList<ImageEntry> dateImgLst, WayPoint prevWp, long prevDateWp, WayPoint curWp, long curDateWp) {
    965         double interval = prevDateWp > 0 ? ((int)Math.abs(curDateWp - prevDateWp)) : 1;
     964    private int matchPoints(ArrayList<ImageEntry> dateImgLst, WayPoint prevWp, long prevDateWp,
     965                                                                   WayPoint curWp, long curDateWp) {
     966        // Time between the track point and the previous one, 5 sec if first point, i.e. photos take
     967        // 5 sec before the first track point can be assumed to be take at the starting position
     968        long interval = prevDateWp > 0 ? ((int)Math.abs(curDateWp - prevDateWp)) : 5;
    966969        int ret = 0;
    967         int i = getLastIndexOfListBefore(dateImgLst, curDateWp, interval);
    968         if (i >= 0 && i < dateImgLst.size() && dateImgLst.get(i).time.getTime()/1000+interval > prevDateWp) {
    969             Double speed = null;
    970             Double prevElevation = null;
    971             Double curElevation = null;
    972             if (prevWp != null) {
    973                 double distance = getDistance(prevWp, curWp);
    974                 speed = new Double((1000 * distance) / (curDateWp - prevDateWp));
    975                 try {
    976                     prevElevation = new Double((String) prevWp.attr.get("ele"));
    977                 } catch(Exception e) {}
    978             }
     970       
     971        // i is the index of the timewise last photo that has the same or earlier EXIF time
     972        int i = getLastIndexOfListBefore(dateImgLst, curDateWp);
     973
     974        // no photos match
     975        if (i < 0)           
     976            return 0;       
     977           
     978        Double speed = null;
     979        Double prevElevation = null;
     980        Double curElevation = null;
     981       
     982        if (prevWp != null) {
     983            double distance = getDistance(prevWp, curWp);
     984            // This is in km/h, 3.6 * m/s
     985            if (curDateWp > prevDateWp)
     986                speed = 3.6 * distance / (curDateWp - prevDateWp);   
    979987            try {
    980                 curElevation = new Double((String) curWp.attr.get("ele"));
    981             } catch (Exception e) {}
    982 
    983             while(i >= 0 && inRadius(dateImgLst.get(i).time.getTime()/1000, curDateWp, interval)) {
    984                 if(dateImgLst.get(i).coor == null) {
     988                prevElevation = new Double((String) prevWp.attr.get("ele"));
     989            } catch(Exception e) {}
     990        }
     991       
     992        try {
     993            curElevation = new Double((String) curWp.attr.get("ele"));
     994        } catch (Exception e) {}
     995       
     996        // First trackpoint, then interval is set to five seconds, i.e. photos up to five seconds
     997        // before the first point will be geotagged with the starting point       
     998        if(prevDateWp == 0 || curDateWp <= prevDateWp) {
     999            while(i >= 0 && (dateImgLst.get(i).time.getTime()/1000) <= curDateWp
     1000                        && (dateImgLst.get(i).time.getTime()/1000) >= (curDateWp - interval)) {
     1001                if(dateImgLst.get(i).coor == null) {               
    9851002                    dateImgLst.get(i).pos = curWp.eastNorth;
    9861003                    dateImgLst.get(i).coor = Main.proj.eastNorth2latlon(dateImgLst.get(i).pos);
     
    9911008                i--;
    9921009            }
    993 
    994             if (prevDateWp != 0) {
    995                 long imgDate;
    996                 while(i >= 0
    997                         && (imgDate = dateImgLst.get(i).time.getTime()/1000) > prevDateWp) {
    998                     if(dateImgLst.get(i).coor == null) {
    999                         dateImgLst.get(i).pos = new EastNorth(
    1000                                 prevWp.eastNorth.east() + ((curWp.eastNorth.east() - prevWp.eastNorth.east()) * (imgDate - prevDateWp)) / (curDateWp - prevDateWp),
    1001                                 prevWp.eastNorth.north() + ((curWp.eastNorth.north() - prevWp.eastNorth.north()) * (imgDate - prevDateWp)) / (curDateWp - prevDateWp));
    1002                         dateImgLst.get(i).coor = Main.proj.eastNorth2latlon(dateImgLst.get(i).pos);
    1003                         dateImgLst.get(i).speed = speed;
    1004                         if (curElevation != null && prevElevation != null) {
    1005                             dateImgLst.get(i).elevation = prevElevation + ((curElevation - prevElevation) * (imgDate - prevDateWp)) / (curDateWp - prevDateWp);
    1006                         }
    1007                         ret++;
    1008                     }
    1009                     i--;
    1010                 }
    1011             }
     1010            return ret;
     1011        }
     1012
     1013        // This code gives a simple linear interpolation of the coordinates between current and
     1014        // previous track point assuming a constant speed in between
     1015        long imgDate;
     1016        while(i >= 0 && (imgDate = dateImgLst.get(i).time.getTime()/1000) >= prevDateWp) {
     1017
     1018            if(dateImgLst.get(i).coor == null) {
     1019                // The values of timeDiff are between 0 and 1, it is not seconds but a dimensionless
     1020                // variable
     1021                double timeDiff = (double)(imgDate - prevDateWp) / interval;
     1022                dateImgLst.get(i).pos = new EastNorth(
     1023                        interpolate(prevWp.eastNorth.east(),  curWp.eastNorth.east(),  timeDiff),
     1024                        interpolate(prevWp.eastNorth.north(), curWp.eastNorth.north(), timeDiff));
     1025                dateImgLst.get(i).coor = Main.proj.eastNorth2latlon(dateImgLst.get(i).pos);
     1026                dateImgLst.get(i).speed = speed;
     1027           
     1028                if (curElevation != null && prevElevation != null)
     1029                    dateImgLst.get(i).elevation = interpolate(prevElevation, curElevation, timeDiff);
     1030           
     1031                ret++;
     1032            }
     1033            i--;
    10121034        }
    10131035        return ret;
    10141036    }
    10151037
    1016     private int getLastIndexOfListBefore(ArrayList<ImageEntry> dateImgLst, long searchedDate, double interval) {
    1017         int lstSize = dateImgLst.size();
    1018         if (lstSize == 0 || searchedDate < dateImgLst.get(0).time.getTime()/1000) {
     1038    private double interpolate(double val1, double val2, double time) {
     1039        return val1 + (val2 - val1) * time;
     1040    }
     1041
     1042    private int getLastIndexOfListBefore(ArrayList<ImageEntry> dateImgLst, long searchedDate) {
     1043        int lstSize= dateImgLst.size();
     1044
     1045        // No photos or the first photo taken is later than the search period
     1046        if(lstSize == 0 || searchedDate < dateImgLst.get(0).time.getTime()/1000)
    10191047            return -1;
    1020         } else if (searchedDate-interval > dateImgLst.get(lstSize - 1).time.getTime()/1000) {
    1021             return lstSize;
    1022         } else if (inRadius(searchedDate, dateImgLst.get(lstSize - 1).time.getTime()/1000, interval)) {
    1023             return lstSize - 1;
    1024         } else if (inRadius(searchedDate , dateImgLst.get(0).time.getTime()/1000, interval)) {
    1025             int curIndex = 0;
    1026             while (curIndex + 1 < lstSize
    1027                     && inRadius(dateImgLst.get(curIndex + 1).time.getTime()/1000, searchedDate, interval)) {
    1028                 curIndex++;
    1029             }
    1030             return curIndex;
    1031         }
    1032 
    1033         int curIndex = 0;
    1034         int startIndex=0;
    1035         int endIndex = lstSize - 1;
    1036         while (endIndex - startIndex > 1) {
    1037             curIndex = (endIndex + startIndex) / 2;
    1038             long curDate = dateImgLst.get(curIndex).time.getTime()/1000;
    1039             if (curDate-interval < searchedDate) {
    1040                 startIndex = curIndex;
    1041             } else if (curDate+interval > searchedDate) {
    1042                 endIndex = curIndex;
    1043             } else {
    1044                 // Check that there is no image _after_ that one that have exactly the same date.
    1045                 while (curIndex + 1 < lstSize
    1046                         && inRadius(dateImgLst.get(curIndex + 1).time.getTime()/1000, searchedDate, interval)) {
    1047                     curIndex++;
    1048                 }
    1049                 return curIndex;
    1050             }
    1051         }
    1052         return startIndex;
    1053     }
     1048           
     1049        // The search period is later than the last photo
     1050        if (searchedDate > dateImgLst.get(lstSize - 1).time.getTime() / 1000)
     1051            return lstSize-1;   
     1052
     1053        // The searched index is somewhere in the middle, do a binary search from the beginning
     1054        int curIndex= 0;
     1055        int startIndex= 0;
     1056        int endIndex= lstSize-1;
     1057        while (endIndex - startIndex > 1) {           
     1058            curIndex= (int) Math.round((double)(endIndex + startIndex)/2);
     1059            if (searchedDate > dateImgLst.get(curIndex).time.getTime()/1000)
     1060                startIndex= curIndex;
     1061            else
     1062                endIndex= curIndex;
     1063        }
     1064        if (searchedDate < dateImgLst.get(endIndex).time.getTime()/1000)
     1065            return startIndex;
     1066 
     1067        // This final loop is to check if photos with the exact same EXIF time follows
     1068        while ((endIndex < (lstSize-1)) && (dateImgLst.get(endIndex).time.getTime()
     1069                                                == dateImgLst.get(endIndex + 1).time.getTime()))
     1070            endIndex++;
     1071        return endIndex;
     1072    }
     1073
    10541074
    10551075    private String formatTimezone(double timezone) {
     
    11601180        return ret;
    11611181    }
    1162    
    1163     private boolean inRadius(long time1, long time2, double interval) {
    1164         return Math.abs(time1 - time2) < interval;
    1165     }
    11661182}
Note: See TracChangeset for help on using the changeset viewer.