-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Created a CLI for the package, made 'area_keys' and 'polygon_features' variable #32
Changes from all commits
76f5bf6
757d2d3
de845e7
46b0df4
14f72fa
5d3ea74
6d2df1d
364b2cf
303bf9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,16 @@ If you want to convert OSM xml or Overpass json/xml to Geojson you can import th | |
Additional parameters for all functions: | ||
|
||
- `filter_used_refs` - (default: `True`) defines geometry filtration strategy (will return all geometry if set as `False`) | ||
- `log_level` - (default: `'ERROR'`) controlls logging level (will print all logs if set as `'INFO'`). More details [here](https://docs.python.org/3/library/logging.html#logging-levels) | ||
- `log_level` - (default: `'ERROR'`) controls logging level (will print all logs if set as `'INFO'`). More details [here](https://docs.python.org/3/library/logging.html#logging-levels) | ||
- `area_keys` - (default: `None`) defines which keys and values of an area should be saved from the list of OSM tags, see `areaKeys.json` for the defaults | ||
- `polygon_features` - (default: `None`) defines a whitelist/blacklist of features to be included in resulting polygons, see `polygon-features.json` for the defaults | ||
|
||
Other handy methods: | ||
|
||
- `overpass_call(str query)` - runs query to overpass-api.de server (retries 5 times in case of error). | ||
- `shape_to_feature(Shape shape, dict properties)` - Converts Shape-object to GeoJSON with passed properties. | ||
|
||
**\*Shape-object - for convinience created simple dict to save Shapely object (geometry) and OSM-properties. Structure of this object:** | ||
**\*Shape-object - for convenience created simple dict to save Shapely object (geometry) and OSM-properties. Structure of this object:** | ||
|
||
```py | ||
shape_obj = { | ||
|
@@ -43,6 +45,17 @@ shape_obj = { | |
} | ||
``` | ||
|
||
After installing via `pip`, the module may also be used as a `argparse`-based command-line script. | ||
Either use the script name directly or call Python with the `-m` option and the package name: | ||
|
||
```sh | ||
osm2geojson --help | ||
``` | ||
|
||
```sh | ||
python3 -m osm2geojson --help | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be possible to use this cli tool without There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed! I've used the |
||
``` | ||
|
||
### Examples | ||
|
||
Convert OSM-xml to Geojson: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import os | ||
import sys | ||
import json | ||
import argparse | ||
|
||
from .main import json2geojson, xml2geojson | ||
|
||
|
||
def setup_parser() -> argparse.ArgumentParser: | ||
def file(v: str) -> str: | ||
if not os.path.exists(v): | ||
raise ValueError(v) | ||
return v | ||
|
||
parser = argparse.ArgumentParser(prog=__package__) | ||
parser.add_argument( | ||
"infile", | ||
type=file, | ||
help="OSM or Overpass JSON file to convert to GeoJSON" | ||
) | ||
parser.add_argument( | ||
"outfile", | ||
help="write output of the processing to the specified file (uses stdout for '-')" | ||
) | ||
parser.add_argument( | ||
"-f", | ||
"--force", | ||
action="store_true", | ||
help="allow overwriting of existing file" | ||
) | ||
logging = parser.add_mutually_exclusive_group() | ||
logging.add_argument( | ||
"-q", | ||
"--quiet", | ||
action="store_true", | ||
help="suppress logging output" | ||
) | ||
logging.add_argument( | ||
"-v", | ||
"--verbose", | ||
action="store_true", | ||
help="enable verbose logging output" | ||
) | ||
parser.add_argument( | ||
"-i", | ||
"--indent", | ||
type=int, | ||
metavar="N", | ||
default=None, | ||
help="indentation using N spaces for the output file (defaults to none)" | ||
) | ||
parser.add_argument( | ||
"--reader", | ||
choices=("json", "xml", "auto"), | ||
default="auto", | ||
help="specify the input file format (either OSM XML or Overpass JSON/XML), defaults to auto-detect" | ||
) | ||
parser.add_argument( | ||
"--no-unused-filter", | ||
action="store_false", | ||
dest="filter_used_refs", | ||
help="don't filter unused references (only in shape JSON)" | ||
) | ||
parser.add_argument( | ||
"--areas", | ||
type=file, | ||
default=None, | ||
metavar="file", | ||
help="JSON file defining the keys that should be included from areas (uses defaults if omitted)" | ||
) | ||
parser.add_argument( | ||
"--polygons", | ||
type=file, | ||
default=None, | ||
metavar="file", | ||
help="JSON file defining the allowed/restricted polygon features (uses defaults if omitted)" | ||
) | ||
return parser | ||
|
||
|
||
def main(args=None) -> int: | ||
args = args or sys.argv[1:] | ||
parser = setup_parser() | ||
args = parser.parse_args(args) | ||
|
||
if args.reader == "xml" or args.reader == "auto" and args.infile.endswith((".osm", ".xml")): | ||
parser_function = xml2geojson | ||
elif args.reader == "json" or args.reader == "auto" and args.infile.endswith(".json"): | ||
parser_function = json2geojson | ||
else: | ||
print("Auto-detecting input file format failed. Consider using --reader.", file=sys.stderr) | ||
return 1 | ||
|
||
if args.outfile != "-" and os.path.exists(args.outfile) and not args.force: | ||
print( | ||
"Output file '{}' already exists. Consider using -f to force overwriting.".format(args.outfile), | ||
file=sys.stderr | ||
) | ||
return 1 | ||
|
||
with open(args.infile) as f: | ||
data = f.read() | ||
|
||
log_level = "WARNING" | ||
if args.quiet: | ||
log_level = "CRITICAL" | ||
elif args.verbose: | ||
log_level = "DEBUG" | ||
|
||
area_keys = None | ||
if args.areas: | ||
with open(args.areas) as f: | ||
area_keys = json.load(f) | ||
if "areaKeys" in area_keys and len(area_keys) == 1: | ||
area_keys = area_keys["areaKeys"] | ||
polygon_features = None | ||
if args.polygons: | ||
with open(args.polygons) as f: | ||
polygon_features = json.load(f) | ||
|
||
result = parser_function( | ||
data, | ||
filter_used_refs=args.filter_used_refs, | ||
log_level=log_level, | ||
area_keys=area_keys, | ||
polygon_features=polygon_features | ||
) | ||
|
||
indent = args.indent | ||
if indent and indent < 0: | ||
indent = None | ||
if args.outfile == "-": | ||
target = sys.stdout | ||
else: | ||
target = open(args.outfile, "w") | ||
|
||
code = 0 | ||
try: | ||
print(json.dumps(result, indent=indent), file=target) | ||
except (TypeError, ValueError) as exc: | ||
print(exc, file=sys.stderr) | ||
print("Falling back to raw dumping the object...", file=sys.stderr) | ||
print(result, file=target) | ||
code = 1 | ||
|
||
if args.outfile != "-": | ||
target.flush() | ||
target.close() | ||
return code | ||
|
||
|
||
exit(main(sys.argv[1:])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for this)