Modify

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#21982 closed enhancement (wontfix)

Add MapCSS feet-and-inches to meters eval function

Reported by: happy5214 Owned by: team
Priority: normal Milestone:
Component: Core mappaint Version:
Keywords: Cc:

Description

Currently, the procedure for converting an OSM length tag value in customary/imperial units (e.g. a road width) to meters is extremely clunky, involving multiple conditionals and regexes. This may be the reason road widths using feet are not currently supported at all by the Lane and Road Attributes map style, which renders such roads using an unrealistic thin line (example attached; the north segment has a width of "40'", while the south segment has no width tag). I think this unit conversion would be more easily addressed in the JOSM code itself and then exposed as an eval function.

Attachments (1)

Screenshot_20220330_225501.png (65.4 KB ) - added by happy5214 3 years ago.
Example of Lane and Road Attributes map paint style when using customary units (north segment has width=40') for road width, compared to the default setting. Two sidewalks and infrastructure are also present.

Download all attachments as: .zip

Change History (9)

by happy5214, 3 years ago

Example of Lane and Road Attributes map paint style when using customary units (north segment has width=40') for road width, compared to the default setting. Two sidewalks and infrastructure are also present.

comment:1 by stoecker, 3 years ago

Resolution: wontfix
Status: newclosed

I'm not much in favour of further supporting non-metric units in the tags.

comment:2 by happy5214, 3 years ago

Americans should not be forced to make up metric conversions for tagging when values are legally defined (and constructed on-the-ground) in customary units. That's the data consumers' job.

Last edited 3 years ago by happy5214 (previous) (diff)

comment:3 by ZLima12, 3 years ago

We should be mapping what's on the ground. Like it or not, imperial measurements are here to stay in OSM, so long as countries still use them. It's no different from a country using one currency; a database should store values the way they're originally measured, not a conversion.

comment:4 by happy5214, 3 years ago

Since I've been told it's not exactly clear what I'm asking for, the request is for a MapCSS eval function that accepts a length value in either foot-inch format (e.g. 12'6") or meters (i.e. a decimal unit-less number) and returns the length value in meters. This would be added as a single static method in org.openstreetmap.josm.gui.mappaint.mapcss.Functions.

comment:5 by happy5214, 3 years ago

I'll even volunteer this (untested) implementation of the eval function I'm looking for.

    public static double feet_to_meters(String source) {
        try {
            return Double.parseDouble(source);
        } catch (NumberFormatException ex) { }

        List<String> matchList = Utils.getMatches(Pattern.compile("^(?:((?:\\d*\\.)?\\d+)\')?(?:((?:\\d*\\.)?\\d+)\")?$").matcher(source));
        if (matchList != null) {
            double feet = matchList.get(1) == null ? 0.0 : Double.parseDouble(matchList.get(1));
            double inches = matchList.get(2) == null ? 0.0 : Double.parseDouble(matchList.get(2));
            inches += 12 * feet;
            return 0.0254 * inches;
        } else {
            return null;
        }
    }

Edit: I've greatly shortened the code above (still untested).

Last edited 3 years ago by happy5214 (previous) (diff)

comment:6 by taylor.smock, 3 years ago

A couple of comments on the untested implementation:

1) The file to modify is source:trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java
2) Using exceptions can be expensive (from a perf standpoint). And silently hiding them tends to be a bad idea in general. In this case, you probably could get away with hiding it, but it should still be logged (e.g., Logging#trace)
3) You should not compile a regex on every call. Regex compiling can be fairly expensive.
4) There are no unit tests (this is something that is external facing, so we pretty much cannot change it if we ever merge it).

As a comment on unit conversions, I'd rather have something like double convert_units(String source, String default_unit, String to_unit). Preferentially, the default_unit and to_unit would be an enum, but I'd have to look at the mapcss parsing code to see how possible that would be.

comment:7 by happy5214, 3 years ago

I never claimed this was a complete patch, re. the unit tests (for example, I didn't add the function to the ExpressionFactory function list in that code, but I considered that relatively trivial).

  1. I'll have to look at the contributor's guide. Most of my work is with git, so I'm out of my element with svn.
  2. Is there a utility function to the effect of "string looks like a decimal number" I can use instead? That was the intent of that code.
  3. Should I make it a class constant?
  4. As I said above, I didn't think it was appropriate to write unit tests in a bug comment that wasn't an actual patch. I was told on OSMUS Slack to write a PoC to explain the requested feature (and the relative ease of implementation), and that's what I came up with.

A general convert_units function would be nice, but OSM doesn't write feet and inches using ft and in. The consensus is to use prime/double-prime notation (as I gave above) for those units.

in reply to:  7 comment:8 by taylor.smock, 3 years ago

Replying to happy5214:

  1. I'll have to look at the contributor's guide. Most of my work is with git, so I'm out of my element with svn.

https://github.com/JOSM/josm/ (JOSM SVN mirror on GitHub)

  1. Is there a utility function to the effect of "string looks like a decimal number" I can use instead? That was the intent of that code.
  2. Should I make it a class constant?

Not yet. If you look at the linked file, you'll notice that patterns are created once on class load (static final Pattern). I do tend to find myself creating regexes to check for numbers a lot. One of the patches I've got floating around somewhere created a PatternUtils class to cache patterns. I don't remember which ticket I was using that for though.

  1. As I said above, I didn't think it was appropriate to write unit tests in a bug comment that wasn't an actual patch. I was told on OSMUS Slack to write a PoC to explain the requested feature (and the relative ease of implementation), and that's what I came up with.

It probably would not be too difficult to do a basic implementation to convert units from imperial to metric. However, other programs use JOSM mapcss syntax (for example, I believe Osmose uses JOSM mapcss for some of its checks). So anything that would be non-JOSM specific has to be more thought out, as it may become an implementation detail that cannot easily be fixed later. A function to convert a specific type of unit to another specific type of unit is easy to do. But this can lead to many more public functions (e.g., chinese_to_metric, metric_to_chinese, nautical_to_metric, metric_to_nautical, etc.). Those could all be private functions, but that would be an implementation detail, not something public facing.

A general convert_units function would be nice, but OSM doesn't write feet and inches using ft and in. The consensus is to use prime/double-prime notation (as I gave above) for those units.

My bad -- I was thinking of something like IMPERIAL and METRIC (see source:trunk/src/org/openstreetmap/josm/data/SystemOfMeasurement.java for currently supported systems of measurement).

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain team.
as The resolution will be set.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.