[OSM-dev] JOSM Images
Ben Gimpert
ben at somethingmodern.com
Thu May 4 11:54:38 BST 2006
Since I'm feeling particularly self-loathing this morning, I went ahead
and wrote a strict ISO 8601 parser for JOSM's image layer-ing. It also
has the expected more lenient "lazy" parsing as a fallback. Here it is
as a patch for Imi:
<<BEGIN_PATCH
Index: josm/gui/layer/GeoImageLayer.java
===================================================================
--- josm/gui/layer/GeoImageLayer.java (revision 101)
+++ josm/gui/layer/GeoImageLayer.java (working copy)
@@ -70,6 +70,104 @@
EastNorth pos;
Icon icon;
}
+
+ private static Date parseDateString(String s) {
+ // First check for strictly ISO 8601 formatted timestamps:
+ {
+ Pattern re = Pattern.compile("^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d+)(Z|([+-]\\d\\d:\\d\\d))$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SS zzzzzzzzz");
+ double frac = Double.parseDouble("0." + m.group(7));
+ int millis = (int) (frac * 1000);
+ String parsable = m.group(1) + "/" + m.group(2) + "/" + m.group(3) + " " + m.group(4) + ":" + m.group(5) + ":" + m.group(6) + ":" + millis;
+ if (m.group(8).equalsIgnoreCase("Z")) {
+ parsable += " GMT+00:00";
+ }
+ else {
+ parsable += " GMT" + m.group(8);
+ }
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(Z|([+-]\\d\\d:\\d\\d))$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss zzzzzzzzz");
+ String parsable = m.group(1) + "/" + m.group(2) + "/" + m.group(3) + " " + m.group(4) + ":" + m.group(5) + ":" + m.group(6);
+ if (m.group(7).equalsIgnoreCase("Z")) {
+ parsable += " GMT+00:00";
+ }
+ else {
+ parsable += " GMT" + m.group(7);
+ }
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(Z|([+-]\\d\\d:\\d\\d))$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm zzzzzzzzz");
+ String parsable = m.group(1) + "/" + m.group(2) + "/" + m.group(3) + " " + m.group(4) + ":" + m.group(5);
+ if (m.group(6).equalsIgnoreCase("Z")) {
+ parsable += " GMT+00:00";
+ }
+ else {
+ parsable += " GMT" + m.group(6);
+ }
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("^(\\d{4})-(\\d\\d)-(\\d\\d)$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+ String parsable = m.group(1) + "/" + m.group(2) + "/" + m.group(3);
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("^(\\d{4})-(\\d\\d)$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM");
+ String parsable = m.group(1) + "/" + m.group(2);
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("^\\d{4}$");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
+ String parsable = m.group(1);
+ return dateFormat.parse(parsable);
+ }
+ }
+ // Now check for lazy-er formats:
+ {
+ Pattern re = Pattern.compile("(\\d\\d/\\d\\d/\\d{4}).(\\d\\d:\\d\\d:\\d\\d)");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+ String parsable = m.group(1) + " " + m.group(2);
+ return dateFormat.parse(parsable);
+ }
+ }
+ {
+ Pattern re = Pattern.compile("(\\d\\d)-(\\d\\d)-(\\d{4}).(\\d\\d:\\d\\d:\\d\\d)");
+ Matcher m = re.matcher(s);
+ if (m.matches()) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+ String parsable = m.group(1) + "/" + m.group(2) + "/" + m.group(3) + " " + m.group(4);
+ return dateFormat.parse(parsable);
+ }
+ }
+ return null;
+ }
private static final class Loader extends PleaseWaitRunnable {
boolean cancelled = false;
@@ -87,16 +185,15 @@
// check the gps layer for time loops (and process it on the way)
Date last = null;
- Pattern reg = Pattern.compile("(\\d\\d/\\d\\d/\\d{4}).(\\d\\d:\\d\\d:\\d\\d)");
try {
for (Collection<GpsPoint> c : gpsLayer.data) {
for (GpsPoint p : c) {
if (p.time == null)
throw new IOException("No time for point "+p.latlon.lat()+","+p.latlon.lon());
- Matcher m = reg.matcher(p.time);
- if (!m.matches())
+ Date d = parseDateString(p.time);
+ if (d == null) {
throw new IOException("Cannot read time from point "+p.latlon.lat()+","+p.latlon.lon());
- Date d = dateFormat.parse(m.group(1)+" "+m.group(2));
+ }
gps.add(new TimedPoint(d, p.eastNorth));
if (last != null && last.after(d))
throw new IOException("Time loop in gps data.");
@@ -152,7 +249,6 @@
private long delta = Long.parseLong(Main.pref.get("tagimages.delta", "0"));
private long gpstimezone = Long.parseLong(Main.pref.get("tagimages.gpstimezone", "0"))*60*60*1000;
private boolean mousePressed = false;
- private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
private MouseAdapter mouseAdapter;
public static final class GpsTimeIncorrect extends Exception {
<<EOF_PATCH
On Thu, May 04, 2006 at 10:17:54AM +0100, Andy Robinson wrote:
> Yes, the gpx format for <time> requires:
>
> "Creation/modification timestamp for element. Date and time in are in
> Univeral Coordinated Time (UTC), not local time! Conforms to ISO 8601
> specification for date/time representation. Fractional seconds are allowed
> for millisecond timing in tracklogs."
>
> ie 2006-04-29T05:51:09Z
>
> http://www.w3.org/TR/NOTE-datetime for ref.
>
> Andy
>
> Andy Robinson
> Andy_J_Robinson at blueyonder.co.uk
>
> >-----Original Message-----
> >From: dev-bounces at openstreetmap.org [mailto:dev-bounces at openstreetmap.org]
> >On Behalf Of Immanuel Scholz
> >Sent: 04 May 2006 09:47
> >To: dev at openstreetmap.org
> >Subject: Re: [OSM-dev] JOSM Images
> >
> >Hi,
> >
> >
> >> If I convert the file so that the dates are like 05/03/2006 16:32:47
> >> then everything works, so it's clearly a problem with parsing the time
> >> in the .gpx file.
> >
> >Yep. Exactly this. I used the "poor men's date parsing", which means it
> >currently can only read time that is in exactly your described format.
> >
> >This is a bug for sure (or call it "missing feature" ;), JOSM should
> >rather use some more general way to try to parse in the date time.
> >
> >Unfortunatly, I start my 4-week-holiday tomorrow at 5:30am and haven't
> >packed yet, so it is very unlikely that you will see this implemented
> >before end of may :-( (Maybe if someone bring a laptop with eclipse and
> >inet-access along to the IoW ;-D )
> >
> >
> >> I have one feature request that would make a lot of difference. I've
> >> started adding a reference to the image as a tag on the relevant way.
> >
> >Wouldn't it be better to make it a reference on a node? (Point Of Interest)
> >
> >
> >> It would be really nice if there was some way to select the name of
> >> the image file (without the path?) so that it can be pasted into a
> >> key-value field. Something like Ctrl+C when the image is selected
> >> would do. This would save time and reduce typing errors.
> >
> >Yea... can you add both things (the parsing thing as bug, this as an
> >feature) to trac?
> >
> >
> >Ciao, Imi.
> >
> >
> >
> >_______________________________________________
> >dev mailing list
> >dev at openstreetmap.org
> >http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/dev
>
>
>
>
> _______________________________________________
> dev mailing list
> dev at openstreetmap.org
> http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/dev
More information about the dev
mailing list