Opened 16 years ago

Closed 16 years ago

Last modified 16 years ago

#64 closed enhancement (fixed)

ps.map: patch to set customized scalebar units

Reported by: alf Owned by: hamish
Priority: minor Milestone: 6.4.0
Component: Ps.map Version: svn-trunk
Keywords: scalebar Cc: grass-dev@…
CPU: All Platform: All

Description

The patch enhanced ps.map with two new parameters:

  • scaleunits: scale units by this factor
  • unitslabel: label for units

Please review and apply if possible.

Alessandro Frigeri

Attachments (3)

psmap_units.diff (4.2 KB ) - added by alf 16 years ago.
two new parameters
psmap_units_perk.diff (5.7 KB ) - added by perk 16 years ago.
1. background for unitslabel 2. nicer nice_number()
psmap_units_grass7.diff (4.4 KB ) - added by mlennert 16 years ago.

Download all attachments as: .zip

Change History (14)

by alf, 16 years ago

Attachment: psmap_units.diff added

two new parameters

comment:1 by hamish, 16 years ago

Cc: grass-dev@… added
Owner: changed from grass-dev@… to hamish
Priority: majorminor
Status: newassigned

The idea of adding a label to the scalebar has been on the TODO list for a long time, thanks. (same for barscale legends; taken from 'r.support units=')

as for scalebar units factor I wonder if we can do something more automatic? e.g. see nviz's or the Tcl gis.m profile tool's scale bar magic: it reads distance units from g.proj settings, and then switches to miles from feet or kilometers from meters when the distances passes a certain threshold.

thanks for the contribution,

Hamish

by perk, 16 years ago

Attachment: psmap_units_perk.diff added
  1. background for unitslabel 2. nicer nice_number()

comment:2 by perk, 16 years ago

I made two changes to this patch. First, background did not affect the units label. I fixed that. Second, I had trouble with getting labels with like "400.000", which I suspected is nice_number() trying to represent something like "400.00000091". To fix this, I modified nice_number() to round the number to 3 decimal places (the maximum it uses anyway) before it does anything else.

comment:3 by mlennert, 16 years ago

CPU: Unspecified
Platform: Unspecified

I have trouble applying any of the two above patches to trunk, probably because of reformatting...

Any reason why this patch shouldn't be committed to svn ?

Moritz

comment:4 by neteler, 16 years ago

I guess you need to revert locally to a pre-indentation version, see http://trac.osgeo.org/grass/wiki/HowToSVN#Revertingsubmittedchanges . Then apply the patches, then run tools/grass_indent.sh locally and svn update back to the current version. The patch here should remain and should be easy to extract then.

Markus

PS: yes, a pity that it wasn't applied earlier as suggested.

comment:5 by hamish, 16 years ago

Component: defaultps.map
CPU: UnspecifiedAll
Keywords: scalebar added
Platform: UnspecifiedAll

Moritz:

Any reason why this patch shouldn't be committed to svn ?

The need this patch scratches is real, but I have not yet been able to dedicate the time to properly consider if it is the right approach to solve it. see my original comment to this wish -- we can make the units automatic like the Tcl profile tool and NVIZ's scalebar; obviously 0 to 60000m should be converted to km. I think the Tcl and NVIZ threshold rules are pretty good and we could use them; or perhaps d.barscale's heuristic rules. Only issue with that is if user wants miles not km (like 'd.barscale -f').

I don't like to bother users with lots of complicated controls for things which it is reasonable for the software to do for them.

another semi-related idea is to add an option to take legend units from the raster map's 'r.support units=' setting.

Sorry for the delay in dealing with this, my available time these days is rather limited.

Hamish

by mlennert, 16 years ago

Attachment: psmap_units_grass7.diff added

comment:6 by mlennert, 16 years ago

I don't like to bother users with lots of complicated controls for things which it is reasonable for the software to do for them.

In the case of the scalebar, I would like to keep the possibility to decide the units by myself. It's the classical power vs usability problem, but I think imposing units on the user is not the solution either.

Maybe a solution would be to apply the suggested patch now, leaving the door open for a 'scaleunits auto' option or something like this...

In any case, I have attached a patch that should work with the current grass7 trunk.

Moritz

in reply to:  6 comment:7 by hamish, 16 years ago

Replying to mlennert:

In the case of the scalebar, I would like to keep the possibility to decide the units by myself.

I agree it would be useful.

It's the classical power vs usability problem, but I think imposing units on the user is not the solution either.

Right.

Maybe a solution would be to apply the suggested patch now, leaving the door open for a 'scaleunits auto' option or something like this...

The trouble with that is that it is not nice to rescind commands later after people have started to write scripts using the new command.

I think the solution will be to add a "units" instruction with the default as auto. That leaves the door open for us to let this evolve at little. Besides auto that we'd add meters, kilometers, feet, miles, nautmiles (r.buffer opts). I do not know if it is noticeable to bother with feet versus survey feet for a scalebar. For correctness I suppose we should. All the GIS lib functions for that are in place so it is not so hard to do it.

Auto would switch meters->km etc. at set breakpoints, the same as gis.m's profile tool, nviz's scalebar, d.barscale.

In any case, I have attached a patch that should work with the current grass7 trunk.

thanks for that. I'll try and get some work done on ps.map in the next days.

Hamish

comment:8 by hamish, 16 years ago

Resolution: fixed
Status: assignedclosed

Hi,

I have now added a new "units" instruction to the ps.map scalebar. Everything should be obvious and automatic. You get a nice label too.

usage:

units auto|meters|kilometers|feet|miles|nautmiles

the default is auto in which case it grabs the units label from PROJ_UNITS.

example:

# spearfish dataset
ps.map out=test.ps << EOF
raster elevation.dem
scalebar f
  length 4
  units nautmiles
  height 0.15
  where 3 7
  end
grid 1852
  end
end
EOF

thanks to Alessandro Frigeri for figuring out the label placement.

Hamish

comment:9 by hamish, 16 years ago

(related) I have added some code to ps.map's floating point (smooth) colortable legend which will print a label for the map's data units if present. Data units can be set with r.support.

I am not very happy with the x placement. The offset to the right is currently based on the length of the tick labels and the fontsize, but as the fonts are proportional width and the fontsize is based on the font height, it's a bit of a fudge. It's too close for small numbers and too far away for large numbers.

I don't know if it is possible to get the right-hand coordinate of a PS pseudo-text box when the text is left-justified. I do not wish to right-justify those labels.

I suppose the answer is to derive some function of max_label_length, but I fear that will only hold for the default font=Helvetica.

Or move the label above/below the legend.

Hamish

in reply to:  9 ; comment:10 by glynn, 16 years ago

Replying to hamish:

I don't know if it is possible to get the right-hand coordinate of a PS pseudo-text box when the text is left-justified. I do not wish to right-justify those labels.

You can use the stringwidth operator to obtain the width of a string (the distance that the current point will move if you show the string). If the string is short, you can obtain the bounding box with a combination of the charpath and pathbbox operators (if the string is long, charpath may overflow the maximum path length).

in reply to:  10 comment:11 by hamish, 16 years ago

hamish:

I don't know if it is possible to get the right-hand coordinate of a PS pseudo-text box when the text is left-justified. I do not wish to right-justify those labels.

Replying to glynn:

You can use the stringwidth operator to obtain the width of a string (the distance that the current point will move if you show the string). If the string is short, you can obtain the bounding box with a combination of the charpath and pathbbox operators (if the string is long, charpath may overflow the maximum path length).

ok, thanks. I made a note of that in the source. For now I've worked out a better placement algorithm and it seems to work ok.

I also added a few different placement options (above, to the right, below, ..) but for now control of that is only by modifying the source code directly.

Hamish

Note: See TracTickets for help on using tickets.