Skip to content

Commit cff5256

Browse files
committed
feat: add --debug flag, improve logging & help
closes #9
1 parent 4dfa08b commit cff5256

3 files changed

Lines changed: 49 additions & 5 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ pip install .
3939
```
4040
Usage: geoclustering [OPTIONS] FILENAME
4141
42+
Tool to cluster geolocations. A cluster is created when a certain number of
43+
points (--size) each are within a given distance (--distance) of at least
44+
one other point in the cluster. Input is supplied as a csv file. At a
45+
minimum, each row needs to have a 'lat' and a 'lon' column. Other rows are
46+
reflected to the output.
47+
4248
Options:
4349
-d, --distance FLOAT (in km) Max. distance between two points in
4450
a cluster. [required]
@@ -52,6 +58,7 @@ Options:
5258
Default: dbscan
5359
--open Open the generated visualization in the
5460
default browser automatically.
61+
--debug Print debug output.
5562
--help Show this message and exit.
5663
```
5764

geoclustering/__main__.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1+
from pathlib import Path
12
import click
3+
import os
24
import webbrowser
35

46
import geoclustering.clustering as clustering
57
import geoclustering.encoding as encoding
68
import geoclustering.io as io
79

810

9-
@click.command()
11+
def print_debug(s):
12+
click.secho(s, fg="bright_black")
13+
14+
15+
@click.command(
16+
help="Tool to cluster geolocations. A cluster is created when a certain number of points (--size) each are within a given distance (--distance) of at least one other point in the cluster. Input is supplied as a csv file. At a minimum, each row needs to have a 'lat' and a 'lon' column. Other rows are reflected to the output."
17+
)
1018
@click.option(
1119
"--distance",
1220
"-d",
@@ -43,9 +51,15 @@
4351
is_flag=True,
4452
help="Open the generated visualization in the default browser automatically.",
4553
)
54+
@click.option("--debug", is_flag=True, help="Print debug output.")
4655
@click.argument("filename", type=click.Path(exists=True))
47-
def main(distance, size, output, filename, algorithm, open):
56+
def main(distance, size, output, filename, algorithm, open, debug):
57+
if debug:
58+
print_debug(f"Reading input from {Path(filename).absolute()}")
59+
4860
df = io.read_csv_file(filename)
61+
if debug:
62+
print_debug(f"Read {len(df)} valid coordinates")
4963

5064
clusters = clustering.cluster_locations(
5165
df=df, algorithm=algorithm, radius_km=distance, min_cluster_size=size
@@ -55,14 +69,18 @@ def main(distance, size, output, filename, algorithm, open):
5569
click.echo("Did not find clusters matching input parameters.")
5670
return
5771

72+
print_debug(f"Found {len(clusters)} valid clusters using {algorithm}")
73+
5874
encoded = encoding.encode_clusters(clusters)
5975

6076
io.write_output_file(output, "result.txt", encoded["string"])
6177
io.write_output_file(output, "result.json", encoded["json"])
6278
io.write_output_file(output, "result.geojson", encoded["geojson"])
6379
vis = io.write_visualization(output, "result.html", encoded["geojson"])
80+
click.echo(f"Output files saved to {Path(output).absolute()}")
6481

6582
if open:
83+
print_debug(f"Opening visualization in default browser")
6684
webbrowser.open_new_tab("file://" + str(vis.absolute()))
6785

6886

geoclustering/io.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,22 @@
22
from pathlib import Path
33
from pkg_resources import resource_filename
44
import json
5-
import json
65
import pandas as pd
76
import numpy as np
7+
import os
8+
import sys
9+
10+
11+
class HiddenPrints:
12+
"""Disables stdout prints for a block of code."""
13+
14+
def __enter__(self):
15+
self._original_stdout = sys.stdout
16+
sys.stdout = open(os.devnull, "w")
17+
18+
def __exit__(self, exc_type, exc_val, exc_tb):
19+
sys.stdout.close()
20+
sys.stdout = self._original_stdout
821

922

1023
def is_valid_lat(val: str) -> bool:
@@ -64,7 +77,10 @@ def write_output_file(dirname, filename, data):
6477

6578
def write_visualization(dirname, filename, data):
6679
"""Write a visualization, ensuring parent directories."""
67-
map = KeplerGl()
80+
# Hide kepler stdout output.
81+
with HiddenPrints():
82+
map = KeplerGl()
83+
6884
map.add_data(data=data, name="clusters")
6985

7086
# config configures a default color scheme for our clusters layer.
@@ -73,6 +89,9 @@ def write_visualization(dirname, filename, data):
7389
map.config = json.loads(f.read())
7490

7591
filepath = ensure_file_path(dirname, filename)
76-
map.save_to_html(file_name=str(filepath), center_map=True)
92+
93+
# Hide kepler stdout output.
94+
with HiddenPrints():
95+
map.save_to_html(file_name=str(filepath), center_map=True)
7796

7897
return filepath

0 commit comments

Comments
 (0)