Plus Code/latlong/query to iOS-Shortcuts-like shareable text
Go to file
Mark Joshwel 1eddae00fc
meta: bump
oops
2023-06-21 12:40:37 +08:00
.github/workflows ci(qc): rename build step, rm extra step in test 2023-06-21 04:42:00 +08:00
.gitignore meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00
devbox.json meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00
devbox.lock meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00
poetry.lock meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00
pyproject.toml meta: bump 2023-06-21 12:40:37 +08:00
README.md docs: update example (#11) 2023-06-21 01:24:31 +00:00
requirements.txt meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00
surplus.py meta: bump 2023-06-21 09:16:23 +08:00
test.py cc: remove woodlands test + brackets 2023-06-21 04:53:02 +08:00
UNLICENCE meta: add files, 1.0.0 2023-06-02 19:39:25 +00:00

surplus

Plus Code to iOS-Shortcuts-like shareable text

$ surplus 9R3J+R9 Singapore
surplus version 1.1.3
Thomson Plaza
301 Upper Thomson Road
Sin Ming, Bishan
574408
Central, Singapore
>>> from surplus import surplus, Localcode
>>> Localcode(code="8RPQ+JW", locality="Singapore").full_length()
(True, '6PH58RPQ+JW')
>>> surplus("6PH58RPQ+JW")
(True, 'Caldecott Stn Exit 4\nToa Payoh Link\n298106\nCentral, Singapore')

Installing

Install surplus directly from GitHub using pip:

pip install git+https://github.com/markjoshwel/surplus

Usage

Command-line Interface

usage: surplus [-h] [-d] [-v] [query ...]

Plus Code to iOS-Shortcuts-like shareable text

positional arguments:
  query          full-length Plus Code (6PH58QMF+FX),
                 local code (8QMF+FX Singapore), or
                 latlong (1.3336875, 103.7749375)

options:
  -h, --help     show this help message and exit
  -d, --debug    prints lat, long and reverser
                 response dict to stderr
  -v, --version  prints version information to stderr
                 and exits

API Reference

surplus.surplus()

pluscode to shareable text conversion function

  • signature

    def surplus(
        query: str | Localcode | Latlong,
        reverser: typing.Callable = geopy.geocoders.Nominatim(user_agent="surplus").reverse,
        debug: bool = False,
    ) -> tuple[bool, str]:
      ...
    
  • arguments

    • query: str | surplus.Localcode | surplus.Latlong

    • reverser: typing.Callable = geopy.geocoders.Nominatim(user_agent="surplus").reverser
      latlong to location function, accesses a dict from .raw attribute of return object function should be able to take a string with two floats and return a geopy.Location-like object (None checking is done)

      # code used by surplus
      location: dict[str, Any] = reverser(f"{lat}, {lon}").raw
      

      dict should be similar to nominatim raw dicts

    • debug: bool = False
      prints lat, long and reverser response dict to stderr

  • returns tuple[bool, str]

    • (True, <str>)
      conversion succeeded, second element is the resultant string
    • (False, <str>)
      conversion failed, second element is an error message string

surplus.parse_query()

function that parses a string Plus Code, local code or latlong into a str, surplus.Localcode or surplus.Latlong respectively

  • signature:

    def parse_query(
      query: str, debug: bool = False
    ) -> tuple[Literal[True], str | Localcode | Latlong] | tuple[Literal[False], str]:
    
  • arguments:

    • query: str
      string Plus Code, local code or latlong
  • returns tuple[Literal[True], str | Localcode | Latlong] | tuple[Literal[False], str]

    • (True, <str | surplus.Localcode | surplus.Latlong>)
      conversion succeeded, second element is resultant Plus code string, surplus.Localcode or surplus.Latlong
    • (False, <str>)
      conversion failed, second element is an error message string

surplus.handle_query()

function that gets returns a surplus.Latlong from a Plus Code string, surplus.Localcode or surplus.Latlong object.
used after surplus.parse_query().

  • signature:

    def handle_query(
        query: str | Localcode | Latlong, debug: bool = False
    ) -> tuple[Literal[True], Latlong] | tuple[Literal[False], str]:
    
  • arguments:

  • returns tuple[Literal[True], Latlong] | tuple[Literal[False], str]

    • (True, <surplus.Latlong>)
      conversion succeeded, second element is a surplus.Latlong
    • (False, <str>) conversion failed, second element is an error message string

surplus.Localcode

typing.NamedTuple representing short Plus Code with locality

  • parameters:

    • code: str Plus Code - e.g.: "8QMF+FX"
    • locality: str e.g.: "Singapore"

surplus.Localcode.full_length()

method that calculates full-length Plus Code using locality

  • signature:

    def full_length(
        self, geocoder: Callable = Nominatim(user_agent="surplus").geocode
    ) -> tuple[bool, str]:
    
  • arguments:

    • geocoder: typing.Callable = geopy.geocoders.Nominatim(user_agent="surplus").geocode
      place/locality to location function, accesses .longitude and .latitude if returned object is not None
  • returns:

    • (True, <str>)
      conversion succeeded, second element is the resultant Plus Code string
    • (False, <str>)
      conversion failed, second element is an error message string

surplus.Latlong

typing.NamedTuple representing a pair of latitude and longitude coordinates

  • parameters:

    • lat: float
      latitudinal coordinate
    • long: float
      longitudinal coordinate

Developing

Prerequisites:

Alternatively, use devbox for a hermetic development environment powered by Nix.

devbox shell    # skip this if you aren't using devbox
poetry install
poetry shell

The format is wrong/different!

If surplus generates wrong text for a particular Plus Code, submit an issue.

Ensure you detail the following:

  1. The erroneous Plus Code, local code or latlong, or a similar coordinate that reproduces the same error

  2. Output from the terminal, with --debug enabled or debug=True

  3. How it should look like instead

Licence

surplus is free and unencumbered software released into the public domain. For more information, please refer to the UNLICENCE, http://unlicense.org/ or the Python module docstring.