mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-06 10:25:41 +02:00
improvements to lambda wrapper [#13]
This commit is contained in:
@@ -8,3 +8,23 @@
|
|||||||
2. Create a ZIP archive with the `tippecanoe` binary at `bin/tippecanoe` and upload as a Lambda layer
|
2. Create a ZIP archive with the `tippecanoe` binary at `bin/tippecanoe` and upload as a Lambda layer
|
||||||
3. Copy [lambda_function.py](lambda_function.py) (python 3.9 runtime)
|
3. Copy [lambda_function.py](lambda_function.py) (python 3.9 runtime)
|
||||||
4. set the environment variable `OUTPUT_BUCKET` to your output bucket; give lambda IAM role access to input/output buckets
|
4. set the environment variable `OUTPUT_BUCKET` to your output bucket; give lambda IAM role access to input/output buckets
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Sid": "AllowGet",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": "s3:GetObject",
|
||||||
|
"Resource": "arn:aws:s3:::tippecanoe-lambda-input/*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowPut",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": "s3:PutObject",
|
||||||
|
"Resource": "arn:aws:s3:::tippecanoe-lambda-output/*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import os
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
import boto3
|
|
||||||
# if the input bucket is publicly readable
|
|
||||||
# from botocore import UNSIGNED
|
|
||||||
# from botocore.config import Config
|
|
||||||
|
|
||||||
def lambda_handler(event, context):
|
|
||||||
bucket = event['Records'][0]['s3']['bucket']['name']
|
|
||||||
key = event['Records'][0]['s3']['object']['key']
|
|
||||||
#s3 = boto3.client('s3',config=Config(signature_version=UNSIGNED))
|
|
||||||
s3 = boto3.client('s3')
|
|
||||||
s3.download_file(bucket,key,'/tmp/input.geojsonseq')
|
|
||||||
p = subprocess.check_call(['tippecanoe','-o','/tmp/output.mbtiles','/tmp/input.geojsonseq','--force'])
|
|
||||||
s3.upload_file('/tmp/output.mbtiles',os.environ['OUTPUT_BUCKET'],key + ".mbtiles")
|
|
||||||
return {
|
|
||||||
'statusCode': 200,
|
|
||||||
'body': json.dumps('Done!')
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import boto3
|
||||||
|
# if the input bucket is publicly readable
|
||||||
|
# from botocore import UNSIGNED
|
||||||
|
# from botocore.config import Config
|
||||||
|
#s3 = boto3.client('s3',config=Config(signature_version=UNSIGNED))
|
||||||
|
|
||||||
|
def lambda_handler(event, context):
|
||||||
|
bucket_name = event['Records'][0]['s3']['bucket']['name']
|
||||||
|
input_key = event['Records'][0]['s3']['object']['key']
|
||||||
|
tmpdir = '/tmp'
|
||||||
|
run_tippecanoe('tippecanoe',tmpdir,bucket_name, input_key)
|
||||||
|
return {
|
||||||
|
'statusCode': 200,
|
||||||
|
'body': json.dumps('Done!')
|
||||||
|
}
|
||||||
|
|
||||||
|
# input formats: "geojsonseq", "fgb", "geobuf", "geojson", "csv"
|
||||||
|
def split_key(key):
|
||||||
|
if key.endswith(".gz"):
|
||||||
|
root, ext = os.path.splitext(key[0:-3])
|
||||||
|
return root, ext + ".gz"
|
||||||
|
else:
|
||||||
|
return os.path.splitext(key)
|
||||||
|
|
||||||
|
def run_tippecanoe(executable, tmpdir, bucket_name, input_key):
|
||||||
|
s3 = boto3.client('s3')
|
||||||
|
root, ext = split_key(input_key)
|
||||||
|
input_path = os.path.join(tmpdir,'input' + ext)
|
||||||
|
output_path = os.path.join(tmpdir,'output.mbtiles')
|
||||||
|
s3.download_file(bucket_name,input_key,input_path)
|
||||||
|
p = subprocess.Popen([executable,'-o',output_path,input_path,'--force','-u','-U','5'],stderr=subprocess.PIPE)
|
||||||
|
for line in p.stderr:
|
||||||
|
try:
|
||||||
|
j = json.loads(line)
|
||||||
|
s3.put_object(Body=json.dumps(j),Bucket=os.environ['OUTPUT_BUCKET'],Key=root + ".progress")
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
s3.upload_file(output_path,os.environ['OUTPUT_BUCKET'],root + ".mbtiles")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
tmpdir = 'tmp'
|
||||||
|
bucket_name = sys.argv[1]
|
||||||
|
input_key = sys.argv[2]
|
||||||
|
run_tippecanoe('../tippecanoe', tmpdir, bucket_name, input_key)
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
from tippecanoe import split_key
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestTippecanoe(unittest.TestCase):
|
||||||
|
def test_basic(self):
|
||||||
|
root, ext = split_key("file.json")
|
||||||
|
self.assertEqual(root,"file")
|
||||||
|
self.assertEqual(ext,".json")
|
||||||
|
|
||||||
|
def test_basic_gz(self):
|
||||||
|
root, ext = split_key("file.csv.gz")
|
||||||
|
self.assertEqual(root,"file")
|
||||||
|
self.assertEqual(ext,".csv.gz")
|
||||||
|
|
||||||
|
def test_nested_key(self):
|
||||||
|
root, ext = split_key("dir/file.fgb")
|
||||||
|
self.assertEqual(root,"dir/file")
|
||||||
|
self.assertEqual(ext,".fgb")
|
||||||
|
|
||||||
|
def test_nested_key_gz(self):
|
||||||
|
root, ext = split_key("dir/file.geojsonseq.gz")
|
||||||
|
self.assertEqual(root,"dir/file")
|
||||||
|
self.assertEqual(ext,".geojsonseq.gz")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user