natural-earth-vector/tools/unique_stable_ids/generate_unique_stable_ids.py

90 lines
2.9 KiB
Python
Raw Permalink Normal View History

import fiona
from shapely.geometry import shape, mapping
import requests
import logging
import json
import sys
import argparse
parser = argparse.ArgumentParser(description='Add unique ne_id to Natural Earth theme features based on Brooklyn Ints.')
parser.add_argument("--input", "-i", type=str, required=True)
parser.add_argument("--output", "-o", type=str, required=True)
args = parser.parse_args()
def generate_id():
url = 'https://api.brooklynintegers.com/rest/'
params = {'method':'brooklyn.integers.create'}
try :
rsp = requests.post(url, params=params)
data = rsp.content
except Exception, e:
logging.error(e)
return 0
try:
data = json.loads(data)
except Exception, e:
logging.error(e)
return 0
return data.get('integer', 0)
with fiona.open( args.input, 'r', encoding='utf-8' ) as source:
# Copy the source schema and add two new properties.
sink_schema = source.schema.copy()
# add ne_id property if not present in the schema add it
if not hasattr( sink_schema['properties'], 'ne_id'):
sink_schema['properties']['ne_id'] = 'int'
# Create a sink for processed features with the same format and
# coordinate reference system as the source.
with fiona.open(
args.output, 'w',
crs=source.crs,
driver=source.driver,
encoding='utf-8',
schema=sink_schema,
) as sink:
# setup counter to track which feature we're on
f_counter = 1
total_features = len(list(source))
for feature in source:
# report which feature we're processing
sys.stdout.write("\r " + str(f_counter) + " of " + str(total_features))
# but don't spam with new lines
sys.stdout.flush()
try:
# when a feature's ne_id property is null or 0 then request a new Brooklyn Int and store that to the feature's ne_id property
if not hasattr( sink_schema['properties'], 'ne_id'):
2021-05-13 00:00:09 -07:00
# generate a Brooklyn int and assign to feature new ne_id property
feature['properties'].update(
ne_id = generate_id() )
sink.write(feature)
else:
if feature['properties']['ne_id'] is null or feature['properties']['ne_id'] == 0:
2021-05-13 00:00:09 -07:00
# generate a Brooklyn int and assign to feature existing ne_id property with empty values
feature['properties'].update(
ne_id = generate_id() )
sink.write(feature)
except Exception, e:
logging.exception("Error processing feature %s:", feature['id'])
# increment counter
f_counter += 1
# The sink file is written to disk and closed when its block ends.