Open bazzaar opened 11 months ago
Perhaps this grammar code could be a help, it parses angles defined by just minutes, seconds or both, and it also parses proj-string's
which use different quote characters, used by PROJ utility cs2cs
for example. It also incorporates E-W, N-S indicator for Latitude/Longitude, and allows for fractional seconds. It also allows for parsing of simple DMS strings without geographic info. It's a bit clunky with the real number parsing, and I'm sure it can be improved on. I guess it'll need associated action method code to facilitate easy extract from the Match object, and to sort out types?
Also, it's convention to always have the coordinates in a set order, X-Y, or Longitude-Latitude. Longitudes with a West indicator will convert to negative decimal degrees.
grammar DMS_parser {
token TOP { <point>||<coord> }
token point { <coord> <.ws>? <coord> }
token coord { <group>[<longitude>||<latitude>]? }
token group { <term>+ }
token term { <num> [<degree>||<minute>||<second>] }
token real { <int> '.' <int> }
token num { <minus>? <real>||<int> }
token minus { '-' }
token int { \d+ }
proto token longitude {*}
token longitude:sym<E> { <sym> }
token longitude:sym<e> { <sym> }
token longitude:sym<W> { <sym> }
token longitude:sym<w> { <sym> }
proto token latitude {*}
token latitude:sym<N> { <sym> }
token latitude:sym<n> { <sym> }
token latitude:sym<S> { <sym> }
token latitude:sym<s> { <sym> }
proto token degree {*}
# <°> is U+00B0 ('\x[0080]')
token degree:sym<°> { <sym> }
# <d> is U+0064 ('\x[0064]')
token degree:sym<d> { <sym> }
proto token minute {*}
# <′> is U+2032 ('\x[2032]')
token minute:sym<′> { <sym> }
# <'> is U+0027 ('\x[0027]')
token minute:sym<'> { <sym> }
proto token second {*}
# <″> is U+2033 ('\x[2033]')
token second:sym<″> { <sym> }
# <"> is U+2022 ('\x[2022]')
token second:sym<"> { <sym> }
}
say DMS_parser.parse(<4°>);
say DMS_parser.parse(<45°>);
say DMS_parser.parse(<45°30′>);
say DMS_parser.parse(<45°30′20″>);
say DMS_parser.parse(<45°30′20.546″>);
say DMS_parser.parse(<3′>);
say DMS_parser.parse(<30′>);
say DMS_parser.parse(<30′2″>);
say DMS_parser.parse(<30′20″>);
say DMS_parser.parse(<30′20.546″>);
say DMS_parser.parse(<2″>);
say DMS_parser.parse(<20″>);
say DMS_parser.parse(<20.546″>);
# examples of proj_string's
say DMS_parser.parse(<121d13'52.432"W 37d28'57.767"N>);
say DMS_parser.parse(<2d20'55"E48d51'12"N>);
The above code is free to use as anyone sees fit.
Hi @bazzaar - this is very nice - thanks for the suggestion and the code example. The errors you show are explained by the fact that Physics::Measure does not support the partial variants that you want.
Sadly, I am not able to commit any tuits to this module at the moment. Let's leave this as an open issue for now and I will see what I can make of it later.
Alternatively, you could consider making a new raku module that overrides a standard Physics::Measure::Angle object with this behaviour?
There is some precedence for this in my Physics::Navigation module. class NavAngle is Angle {...}
Also this module has the notion of Latitude, Longitude and Position objects. That way you can adapt the print side also... but still benefit from the "unit math" that Physics::Measure / Physics::Unit offers (AngularSpeed = Angle/Duration, SolidAngle = Angle^2).
My superficial look at PROJ suggests that there is a gap in the market for a raku PROJ capability and tbh my Physics::Navigation module is not intended to be a core Geo library, rather a precursor to exploring raku capabilities around my Yacht::Navigation hobby and so does not have (eg) Google Maps or GPS formats (and tests). So I would imagine that a common interface to import / export to/from Physics::Measure <=> "Geo::PROJ" would be suitable for most use cases.
First of all, many thanks for making this module :-)
Tried to assign :
use Physics::Measure :ALL;
my $θ1 = ♎️<30′30″>;
say $θ1;
resulting in the following errors, also tried
my $θ1 = ♎️<2′>;
with similar errors too.Not a big issue as
my $θ1 = ♎️<0°2′0″>;
does parse, however it would be nice if just minutes, or even just seconds would parse on their own.My use case was to create a 1st pass set of control points at a defined grid (2' spacing) over an map image to be geo-(located/rectified), the points file will be imported into GRASS GIS project and individual points repositioned in the georectify GUI.