diff --git a/examples/Use_Custom_algorithm.ipynb b/examples/Use_Custom_algorithm.ipynb
new file mode 100644
index 0000000..cc7adda
--- /dev/null
+++ b/examples/Use_Custom_algorithm.ipynb
@@ -0,0 +1,583 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "b6633f73",
+ "metadata": {},
+ "source": [
+ "### Use Custom Algorithm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "55915667",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import time\n",
+ "import httpx\n",
+ "\n",
+ "from folium import Map, TileLayer\n",
+ "\n",
+ "from rio_viz.app import Client"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "5c65b3d5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Client is alive: True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Create rio-viz Client (using server-thread to launch backgroud task)\n",
+ "client = Client(\"https://data.geo.admin.ch/ch.swisstopo.swissalti3d/swissalti3d_2019_2573-1085/swissalti3d_2019_2573-1085_0.5_2056_5728.tif\")\n",
+ "\n",
+ "# Gives some time for the server to setup\n",
+ "time.sleep(1)\n",
+ "\n",
+ "# Check that client is running\n",
+ "print(\"Client is alive: \", client.server.is_alive())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "85e4c1e0",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'bounds': [7.090624928537461,\n",
+ " 45.916058441028206,\n",
+ " 7.1035698381384185,\n",
+ " 45.925093000254144],\n",
+ " 'band_metadata': [['1',\n",
+ " {'STATISTICS_COVARIANCES': '10685.98787505646',\n",
+ " 'STATISTICS_EXCLUDEDVALUES': '-9999',\n",
+ " 'STATISTICS_MAXIMUM': '2015.0944824219',\n",
+ " 'STATISTICS_MEAN': '1754.471184271',\n",
+ " 'STATISTICS_MINIMUM': '1615.8128662109',\n",
+ " 'STATISTICS_SKIPFACTORX': '1',\n",
+ " 'STATISTICS_SKIPFACTORY': '1',\n",
+ " 'STATISTICS_STDDEV': '103.37305197708'}]],\n",
+ " 'band_descriptions': [['1', '']],\n",
+ " 'dtype': 'float32',\n",
+ " 'nodata_type': 'Nodata',\n",
+ " 'colorinterp': ['gray'],\n",
+ " 'driver': 'GTiff',\n",
+ " 'count': 1,\n",
+ " 'nodata_value': -9999.0,\n",
+ " 'overviews': [2, 4, 8],\n",
+ " 'width': 2000,\n",
+ " 'height': 2000}"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "ERROR 4: `/vsimem/8c6cd926-2cc0-4138-a382-2f1fc16e0663/8c6cd926-2cc0-4138-a382-2f1fc16e0663.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d9861410-f66e-4709-b891-6d15ac92408a/d9861410-f66e-4709-b891-6d15ac92408a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/099effc9-09f7-4cd1-b671-340f9da28965/099effc9-09f7-4cd1-b671-340f9da28965.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/29ef73e7-2ee7-4d4d-b9ce-cb0c1af38b33/29ef73e7-2ee7-4d4d-b9ce-cb0c1af38b33.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/976a4f57-d579-4667-aaca-6fc51720f680/976a4f57-d579-4667-aaca-6fc51720f680.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/c061feb8-5efd-4268-8830-896705e04c9c/c061feb8-5efd-4268-8830-896705e04c9c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fe6df937-8c35-43a6-a3f0-cb43a2a28d41/fe6df937-8c35-43a6-a3f0-cb43a2a28d41.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e21083b0-51d0-4d8d-b97f-b53fe1e9c1ef/e21083b0-51d0-4d8d-b97f-b53fe1e9c1ef.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7b9c3042-78b8-47c1-9eef-336bba2f8a1b/7b9c3042-78b8-47c1-9eef-336bba2f8a1b.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a5d6ec97-7e30-4165-96e8-02ec4dd1daf7/a5d6ec97-7e30-4165-96e8-02ec4dd1daf7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f611fcf0-f996-44c2-a2f5-acfb9119f9d2/f611fcf0-f996-44c2-a2f5-acfb9119f9d2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e98c229b-de9d-4f06-994d-52bd0f1c8987/e98c229b-de9d-4f06-994d-52bd0f1c8987.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9ef836e4-aa4b-4ca6-a7ca-7001bb6f4ff8/9ef836e4-aa4b-4ca6-a7ca-7001bb6f4ff8.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8fb656e6-bf35-4ff6-b410-e206580b5d26/8fb656e6-bf35-4ff6-b410-e206580b5d26.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/4cd68238-d2f2-4fa0-a3a4-c8ecd3c87a11/4cd68238-d2f2-4fa0-a3a4-c8ecd3c87a11.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/0b1b43c6-14bb-40ad-bc68-3d7a2cd909cb/0b1b43c6-14bb-40ad-bc68-3d7a2cd909cb.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/bef02363-f5b9-40cb-9dd3-731896f00695/bef02363-f5b9-40cb-9dd3-731896f00695.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a1189368-9480-42c7-8eb3-e26036be5d4f/a1189368-9480-42c7-8eb3-e26036be5d4f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/da993d9b-0072-4085-b478-ecd0184d5faa/da993d9b-0072-4085-b478-ecd0184d5faa.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/febe651e-4188-4931-ab94-3ca2c97d9119/febe651e-4188-4931-ab94-3ca2c97d9119.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/71ebe625-f2aa-406f-8d54-8fa231d41d21/71ebe625-f2aa-406f-8d54-8fa231d41d21.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7cbf7bad-1502-4edc-88ac-a86b9fa47427/7cbf7bad-1502-4edc-88ac-a86b9fa47427.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/4656ebf9-49e0-4820-a28b-e1d3bddc3a5d/4656ebf9-49e0-4820-a28b-e1d3bddc3a5d.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a54a3ed4-cc8e-43ed-a818-141cddccc129/a54a3ed4-cc8e-43ed-a818-141cddccc129.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3003a177-9849-4c1a-8616-02bff25241b8/3003a177-9849-4c1a-8616-02bff25241b8.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ccee0cd3-812b-4703-80e8-fa8b1a0098d5/ccee0cd3-812b-4703-80e8-fa8b1a0098d5.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/b2f85633-68a5-47b4-8e14-4c12af6452b8/b2f85633-68a5-47b4-8e14-4c12af6452b8.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8c0d620f-e607-4e58-85e5-a5f02621f384/8c0d620f-e607-4e58-85e5-a5f02621f384.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/53926e1c-d5e4-4018-8309-c2cc9826dd55/53926e1c-d5e4-4018-8309-c2cc9826dd55.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ced2afdb-6301-4a98-a71e-7df8bf1a9ca5/ced2afdb-6301-4a98-a71e-7df8bf1a9ca5.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3c687de8-d9d4-4210-b3f0-6856406e27ca/3c687de8-d9d4-4210-b3f0-6856406e27ca.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fffd4ff3-b8bc-4e68-a41c-83985489aa96/fffd4ff3-b8bc-4e68-a41c-83985489aa96.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/31c9db77-39c0-4da9-a687-0c163f88da9f/31c9db77-39c0-4da9-a687-0c163f88da9f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fff4f1df-5ce1-40f1-be11-30b446a94690/fff4f1df-5ce1-40f1-be11-30b446a94690.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8d7bfe7c-9bcf-4301-8ef1-0d19891080e8/8d7bfe7c-9bcf-4301-8ef1-0d19891080e8.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/09108421-0b54-4914-a871-39a49a365405/09108421-0b54-4914-a871-39a49a365405.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2018dfc7-30a6-426e-a636-bf63b58bb360/2018dfc7-30a6-426e-a636-bf63b58bb360.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d1fdadf9-9323-441b-90ed-c19ec1f6db32/d1fdadf9-9323-441b-90ed-c19ec1f6db32.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8c5375b4-cea6-4283-b974-29bd8869f319/8c5375b4-cea6-4283-b974-29bd8869f319.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fd8c0908-bca8-4bc4-95d9-4076142b4beb/fd8c0908-bca8-4bc4-95d9-4076142b4beb.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/c94ab093-9476-4ac0-b246-d6d6690cbdb7/c94ab093-9476-4ac0-b246-d6d6690cbdb7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/28686a4c-104c-4f94-a8ba-b723ab47480d/28686a4c-104c-4f94-a8ba-b723ab47480d.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/6db1b030-9172-4d12-ab1b-d5bc12c61140/6db1b030-9172-4d12-ab1b-d5bc12c61140.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/28161fdc-ffed-425f-89de-b4e20ee4101c/28161fdc-ffed-425f-89de-b4e20ee4101c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/60fb86fa-f98e-4a7a-aa51-debd312a4846/60fb86fa-f98e-4a7a-aa51-debd312a4846.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/42170581-ead2-4bc6-ac77-7614a520a8c5/42170581-ead2-4bc6-ac77-7614a520a8c5.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/04522367-4592-47e0-8ed6-b93a10e5b57c/04522367-4592-47e0-8ed6-b93a10e5b57c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/028fd491-e61c-41c1-a8cf-a5429951fe20/028fd491-e61c-41c1-a8cf-a5429951fe20.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a3eecc09-58bb-4070-a96c-283f62794b96/a3eecc09-58bb-4070-a96c-283f62794b96.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d892816e-4b87-46c8-9657-d419aeaaaf96/d892816e-4b87-46c8-9657-d419aeaaaf96.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/6ec10004-f947-49bd-be32-65ea556a1a4f/6ec10004-f947-49bd-be32-65ea556a1a4f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/aa089a74-73f5-48cf-acaf-8e947520a3fb/aa089a74-73f5-48cf-acaf-8e947520a3fb.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2a8a54fa-4d6e-4224-8512-3b6032b00c07/2a8a54fa-4d6e-4224-8512-3b6032b00c07.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/64daa6fb-2a6d-4430-9b60-634ad933a95a/64daa6fb-2a6d-4430-9b60-634ad933a95a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/90361ac4-e0b8-4e44-aa2b-9a7ef4a84fb2/90361ac4-e0b8-4e44-aa2b-9a7ef4a84fb2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/620d302c-98f6-4cd7-9026-441a4f541f38/620d302c-98f6-4cd7-9026-441a4f541f38.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2d7ee809-4503-4253-aba0-70ddcad9184f/2d7ee809-4503-4253-aba0-70ddcad9184f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/abccac86-44fb-4656-837d-c588a5eebc8e/abccac86-44fb-4656-837d-c588a5eebc8e.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ac004344-9db7-4fea-9d81-e4ef96db10b5/ac004344-9db7-4fea-9d81-e4ef96db10b5.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3152c7a1-89aa-44c1-b34d-1d3c1905179a/3152c7a1-89aa-44c1-b34d-1d3c1905179a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9907a98d-1bae-4f81-8430-d857707a06d6/9907a98d-1bae-4f81-8430-d857707a06d6.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/edc0ec60-461a-479a-aa9b-1597f04e6aab/edc0ec60-461a-479a-aa9b-1597f04e6aab.tif' not recognized as a supported file format.\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "ERROR 4: `/vsimem/77a2a7af-cb1e-4cb3-97be-2667cf144b15/77a2a7af-cb1e-4cb3-97be-2667cf144b15.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/c5e75510-3e57-4bff-9622-cc2667679fd5/c5e75510-3e57-4bff-9622-cc2667679fd5.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/061c7672-b2e1-4fa1-a9c1-31e840a8f21a/061c7672-b2e1-4fa1-a9c1-31e840a8f21a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e6fefd0c-89df-41bf-ad36-802152f7e265/e6fefd0c-89df-41bf-ad36-802152f7e265.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ceb3f6f3-9826-4c54-9b53-3679ae92c65c/ceb3f6f3-9826-4c54-9b53-3679ae92c65c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/dc3b0d06-6b2f-461b-9d36-1026d9c2ce72/dc3b0d06-6b2f-461b-9d36-1026d9c2ce72.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/b7a3a45d-c0e5-4b17-9ef7-ff5cec9c1ba0/b7a3a45d-c0e5-4b17-9ef7-ff5cec9c1ba0.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/dbd602f3-2067-48a8-9554-975a75ff421c/dbd602f3-2067-48a8-9554-975a75ff421c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7cf9b685-f1b9-4a0a-b2dc-63eb41b5c4ee/7cf9b685-f1b9-4a0a-b2dc-63eb41b5c4ee.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e9b95fc9-8222-472f-8ba8-2e5f6c9bdb60/e9b95fc9-8222-472f-8ba8-2e5f6c9bdb60.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/92abe698-83e7-4d15-86f5-fa8ec4212353/92abe698-83e7-4d15-86f5-fa8ec4212353.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d91321c0-4dce-43f0-b4ec-b778419406db/d91321c0-4dce-43f0-b4ec-b778419406db.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/1d4389d1-52c5-482f-a295-e49845fb4a1c/1d4389d1-52c5-482f-a295-e49845fb4a1c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/df17c135-f266-42cc-bc49-e06335eb65b3/df17c135-f266-42cc-bc49-e06335eb65b3.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/28b0e750-bc52-41fd-b53c-58e76f94af94/28b0e750-bc52-41fd-b53c-58e76f94af94.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d99ed4e8-7678-4cbd-a9f9-8993aa8b49ea/d99ed4e8-7678-4cbd-a9f9-8993aa8b49ea.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/996c96f3-0e5e-4363-ad86-7cea785b36a2/996c96f3-0e5e-4363-ad86-7cea785b36a2.tif' not recognized as a supported file format.\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Fetch info\n",
+ "httpx.get(f\"{client.endpoint}/info\").json()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "4cc8c900",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
Make this Notebook Trusted to load map: File -> Trust Notebook
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "ERROR 4: `/vsimem/f955f700-6747-4874-81d8-6b6a77c766ac/f955f700-6747-4874-81d8-6b6a77c766ac.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/6669cead-1916-4c9c-ae69-f4a8840c3595/6669cead-1916-4c9c-ae69-f4a8840c3595.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/b782a5a6-53da-43f8-b519-c5d535b8cd8f/b782a5a6-53da-43f8-b519-c5d535b8cd8f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e440ed76-76ce-4d95-8e2e-ff8783cd8424/e440ed76-76ce-4d95-8e2e-ff8783cd8424.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/46fc6594-ad5c-4d6f-b89b-677fb3b3ef04/46fc6594-ad5c-4d6f-b89b-677fb3b3ef04.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/15907b94-d2b8-4d4c-bce5-ab6a0ad9626a/15907b94-d2b8-4d4c-bce5-ab6a0ad9626a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/6ca42758-9ac9-4a72-8522-c97bee66e3f9/6ca42758-9ac9-4a72-8522-c97bee66e3f9.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/374e8f5e-67b1-4407-99cb-d7e10d9b0f27/374e8f5e-67b1-4407-99cb-d7e10d9b0f27.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2572f394-5dbc-41bc-ae37-adff572ae920/2572f394-5dbc-41bc-ae37-adff572ae920.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f4e65c65-fdd3-4e2a-8899-5f55bc21660f/f4e65c65-fdd3-4e2a-8899-5f55bc21660f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/6677f11b-4172-4f76-8bfb-0985e46ac495/6677f11b-4172-4f76-8bfb-0985e46ac495.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f2af8eab-341d-4ea9-a461-c3d2ede8e9dc/f2af8eab-341d-4ea9-a461-c3d2ede8e9dc.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3c978711-a7f5-4db6-a597-d053b2eca92b/3c978711-a7f5-4db6-a597-d053b2eca92b.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/819e7b92-e1f8-4f7f-a6ef-8d2e370249d7/819e7b92-e1f8-4f7f-a6ef-8d2e370249d7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/b84a358b-9eec-479d-89b1-7dbf6630f1ce/b84a358b-9eec-479d-89b1-7dbf6630f1ce.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9e4f2569-680a-40c3-8604-6e7cc9528b86/9e4f2569-680a-40c3-8604-6e7cc9528b86.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/685e6ce4-8e42-4847-b013-38c34df48b46/685e6ce4-8e42-4847-b013-38c34df48b46.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/36896641-95cc-4b51-a797-a0fec3aceb37/36896641-95cc-4b51-a797-a0fec3aceb37.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/756e7cae-c5e7-4489-b255-c0886783a436/756e7cae-c5e7-4489-b255-c0886783a436.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f2b735c2-bc5a-42a9-b17f-538510e3d410/f2b735c2-bc5a-42a9-b17f-538510e3d410.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a5be8e99-2ad1-470f-aec5-78c0868b9e03/a5be8e99-2ad1-470f-aec5-78c0868b9e03.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8fe161be-609b-49b4-9e7c-3f75d793cba2/8fe161be-609b-49b4-9e7c-3f75d793cba2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/003994e0-ac70-4b1c-a2f1-56ce0de781b3/003994e0-ac70-4b1c-a2f1-56ce0de781b3.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/99114d04-6df2-4af2-9b56-91c2a1c3e2e4/99114d04-6df2-4af2-9b56-91c2a1c3e2e4.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ea2c3cde-7503-48bf-b638-be6a3e5197fa/ea2c3cde-7503-48bf-b638-be6a3e5197fa.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f2e73fbf-a3ef-48d1-a0f0-53f20956b205/f2e73fbf-a3ef-48d1-a0f0-53f20956b205.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/4cd72d17-54f5-4f23-8221-f4faf5d61342/4cd72d17-54f5-4f23-8221-f4faf5d61342.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a536b17d-b31f-4af5-af9a-b84c34638880/a536b17d-b31f-4af5-af9a-b84c34638880.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/96e9d294-f29d-4771-8f4c-9debece4fbcc/96e9d294-f29d-4771-8f4c-9debece4fbcc.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/1b396f9d-cd97-4734-8796-1108ff93e04b/1b396f9d-cd97-4734-8796-1108ff93e04b.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/53722767-7f83-40f0-8df0-fb93edf3a26f/53722767-7f83-40f0-8df0-fb93edf3a26f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/799d6009-a3fd-4b93-9b4b-94fe31de0317/799d6009-a3fd-4b93-9b4b-94fe31de0317.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e867eec2-c679-4acc-a5c3-503225f60f91/e867eec2-c679-4acc-a5c3-503225f60f91.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/131d0274-1b37-44d2-adc0-62ccab073943/131d0274-1b37-44d2-adc0-62ccab073943.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/294f5041-dad6-4939-b772-b76cb3844b2d/294f5041-dad6-4939-b772-b76cb3844b2d.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f137c96d-40b8-483f-b7b3-918c2307c2f3/f137c96d-40b8-483f-b7b3-918c2307c2f3.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ec7305da-17fb-4f2e-a0d7-e2cf7720f2c6/ec7305da-17fb-4f2e-a0d7-e2cf7720f2c6.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8ad1b2d2-4177-4f55-b2ef-4948dd6b514f/8ad1b2d2-4177-4f55-b2ef-4948dd6b514f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/5818fbee-c342-4de6-98f3-2991958b289c/5818fbee-c342-4de6-98f3-2991958b289c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a4c04dfb-954f-4ba0-b607-2e0c32314d96/a4c04dfb-954f-4ba0-b607-2e0c32314d96.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/40089c70-f25d-4d35-8642-e6dc3284be64/40089c70-f25d-4d35-8642-e6dc3284be64.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fffe4775-b044-4213-ad1a-d0912adaae67/fffe4775-b044-4213-ad1a-d0912adaae67.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2f7f80b6-5176-4c95-80d5-3abb0a28afe7/2f7f80b6-5176-4c95-80d5-3abb0a28afe7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/45ccebbf-773e-4d6a-a696-3f6df08af5d1/45ccebbf-773e-4d6a-a696-3f6df08af5d1.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/cb6f2f62-b007-48bf-b09d-7101b84752c7/cb6f2f62-b007-48bf-b09d-7101b84752c7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a3953087-486d-4c77-bf5d-7f80cae9652f/a3953087-486d-4c77-bf5d-7f80cae9652f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/86ea8b22-3b38-4b93-85c8-b1253eef5065/86ea8b22-3b38-4b93-85c8-b1253eef5065.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7d48e8b6-23db-40b7-8fba-ee87208ebb9b/7d48e8b6-23db-40b7-8fba-ee87208ebb9b.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3338713a-f518-4a16-9406-0896863842f2/3338713a-f518-4a16-9406-0896863842f2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d03a531e-4301-440c-9a50-8e109f790bec/d03a531e-4301-440c-9a50-8e109f790bec.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/70213974-f861-4fa5-a1c8-2559c185eb89/70213974-f861-4fa5-a1c8-2559c185eb89.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d893b528-06f7-4dde-bfba-a5113224842c/d893b528-06f7-4dde-bfba-a5113224842c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d809e260-c6df-4e25-a4d0-f315f82e2116/d809e260-c6df-4e25-a4d0-f315f82e2116.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a6c8b25d-3531-423b-b689-71e2a6699506/a6c8b25d-3531-423b-b689-71e2a6699506.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/bb7a060b-170f-4d70-9821-f7a237c79db3/bb7a060b-170f-4d70-9821-f7a237c79db3.tif' not recognized as a supported file format.\n"
+ ]
+ }
+ ],
+ "source": [
+ "r = httpx.get(\n",
+ " f\"{client.endpoint}/tilejson.json\",\n",
+ " params = {\n",
+ " \"algo\": \"hillshade\",\n",
+ " }\n",
+ ").json()\n",
+ "\n",
+ "bounds = r[\"bounds\"]\n",
+ "m = Map(\n",
+ " location=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
+ " zoom_start=r[\"minzoom\"]\n",
+ ")\n",
+ "\n",
+ "aod_layer = TileLayer(\n",
+ " tiles=r[\"tiles\"][0],\n",
+ " opacity=1,\n",
+ " attr=\"Yo!!\"\n",
+ ")\n",
+ "aod_layer.add_to(m)\n",
+ "m"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "id": "54d674e9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "Make this Notebook Trusted to load map: File -> Trust Notebook
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "ERROR 4: `/vsimem/8345f3a6-8f87-4235-a86d-4ccc4b69b084/8345f3a6-8f87-4235-a86d-4ccc4b69b084.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8999743e-9bb7-459e-9cd0-385f79f4c240/8999743e-9bb7-459e-9cd0-385f79f4c240.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/a7a24aed-ddf3-469b-97ae-c45d142f3027/a7a24aed-ddf3-469b-97ae-c45d142f3027.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/3e85c07b-6d68-425d-9042-6ebc2ca7e712/3e85c07b-6d68-425d-9042-6ebc2ca7e712.tif' not recognized as a supported file format.\n"
+ ]
+ }
+ ],
+ "source": [
+ "import json\n",
+ "\n",
+ "r = httpx.get(\n",
+ " f\"{client.endpoint}/tilejson.json\",\n",
+ " params = {\n",
+ " \"algo\": \"contours\",\n",
+ " \"algo_params\": json.dumps(\n",
+ " {\n",
+ " \"increment\": 20,\n",
+ " \"thickness\": 2,\n",
+ " \"minz\": 1600,\n",
+ " \"maxz\": 2000\n",
+ " }\n",
+ " ),\n",
+ " }\n",
+ ").json()\n",
+ "\n",
+ "bounds = r[\"bounds\"]\n",
+ "m = Map(\n",
+ " location=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
+ " zoom_start=r[\"minzoom\"]\n",
+ ")\n",
+ "\n",
+ "aod_layer = TileLayer(\n",
+ " tiles=r[\"tiles\"][0],\n",
+ " opacity=1,\n",
+ " attr=\"Yo!!\"\n",
+ ")\n",
+ "aod_layer.add_to(m)\n",
+ "m"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "e2d3d5bc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "client.shutdown()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "1c80efe0",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Client is alive: True\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Create rio-viz Client (using server-thread to launch backgroud task)\n",
+ "client = Client(\"https://njogis-imagery.s3.us-west-2.amazonaws.com/2020/cog/K7A3.tif\")\n",
+ "\n",
+ "# Gives some time for the server to setup\n",
+ "time.sleep(1)\n",
+ "\n",
+ "# Check that client is running\n",
+ "print(\"Client is alive: \", client.server.is_alive())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "ced4b27d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "Make this Notebook Trusted to load map: File -> Trust Notebook
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "r = httpx.get(\n",
+ " f\"{client.endpoint}/tilejson.json\",\n",
+ " params = {\n",
+ " # Data is stored as RGB-NIR\n",
+ " \"bidx\": [4, 1, 2],\n",
+ " }\n",
+ ").json()\n",
+ "\n",
+ "bounds = r[\"bounds\"]\n",
+ "m = Map(\n",
+ " location=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
+ " zoom_start=r[\"minzoom\"]\n",
+ ")\n",
+ "\n",
+ "aod_layer = TileLayer(\n",
+ " tiles=r[\"tiles\"][0],\n",
+ " opacity=1,\n",
+ " attr=\"Yo!!\"\n",
+ ")\n",
+ "aod_layer.add_to(m)\n",
+ "m"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "3f2ba1c4",
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "Make this Notebook Trusted to load map: File -> Trust Notebook
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/vincentsarago/Dev/vincentsarago/rasterio/rasterio/io.py:140: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.\n",
+ " return writer(mempath, 'w+', driver=driver, width=width,\n",
+ "ERROR 4: `/vsimem/f1472321-4de2-48cb-afb5-75d180c8a639/f1472321-4de2-48cb-afb5-75d180c8a639.tif' not recognized as a supported file format.\n",
+ "/Users/vincentsarago/Dev/CogeoTiff/rio-viz/rio_viz/algorithm/index.py:26: RuntimeWarning: invalid value encountered in true_divide\n",
+ " arr = numpy.where(img.mask, (b2 - b1) / (b2 + b1), 0)\n",
+ "ERROR 4: `/vsimem/2ec751dc-1929-4db0-a69c-9eb483cc88b6/2ec751dc-1929-4db0-a69c-9eb483cc88b6.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/829da3a7-5e37-4718-a5dc-79c89559dccf/829da3a7-5e37-4718-a5dc-79c89559dccf.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/0434dea0-f6ba-4df2-b54c-0fecdf73fc0a/0434dea0-f6ba-4df2-b54c-0fecdf73fc0a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/5a19cb46-45b4-4eed-bff3-8989a4a41df3/5a19cb46-45b4-4eed-bff3-8989a4a41df3.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fcf027e1-5a80-4a89-84f6-726e459774e7/fcf027e1-5a80-4a89-84f6-726e459774e7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ce3849d4-9d3e-4fa6-a82b-4a48a775b649/ce3849d4-9d3e-4fa6-a82b-4a48a775b649.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/0feb947d-c69b-4e2e-8098-d87b20859773/0feb947d-c69b-4e2e-8098-d87b20859773.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/18140de1-dd19-44d8-b9e8-58ca2d2799a8/18140de1-dd19-44d8-b9e8-58ca2d2799a8.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/05e7c19d-7c4d-4faf-9b67-0528f3724f45/05e7c19d-7c4d-4faf-9b67-0528f3724f45.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/24bdb3ea-e07d-49eb-baab-6a3249d1d016/24bdb3ea-e07d-49eb-baab-6a3249d1d016.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d788a4a2-f6cb-4a11-ac5b-357a8062173a/d788a4a2-f6cb-4a11-ac5b-357a8062173a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/0946f024-709d-4ea1-a74b-e8292ca036ef/0946f024-709d-4ea1-a74b-e8292ca036ef.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2c0444ef-ba9e-43df-bbd7-7576e61bf379/2c0444ef-ba9e-43df-bbd7-7576e61bf379.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7d2fbe19-e923-4271-b700-41d6ecb2f372/7d2fbe19-e923-4271-b700-41d6ecb2f372.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/92576950-ecff-4890-aca4-c107548a33fd/92576950-ecff-4890-aca4-c107548a33fd.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/2d264e13-4545-4739-8eb7-576256e4edad/2d264e13-4545-4739-8eb7-576256e4edad.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/28ac6ef3-91dc-4ef1-bbce-a9ef714b12db/28ac6ef3-91dc-4ef1-bbce-a9ef714b12db.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/48891e0b-e245-463f-b960-5d9c5b329266/48891e0b-e245-463f-b960-5d9c5b329266.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/7d69d4a3-3a36-452e-9daf-3ddfab72461d/7d69d4a3-3a36-452e-9daf-3ddfab72461d.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/004df73f-5123-4333-b325-f9037b114494/004df73f-5123-4333-b325-f9037b114494.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ef6a1b64-7fdc-45f3-831a-072d5c08fd53/ef6a1b64-7fdc-45f3-831a-072d5c08fd53.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/1762b5e6-0859-414b-8921-5f06ba326312/1762b5e6-0859-414b-8921-5f06ba326312.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f6dee829-83ff-4d46-9c9b-60e21d1c2a66/f6dee829-83ff-4d46-9c9b-60e21d1c2a66.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/5149188e-b7a9-4cf2-bcac-05877b0427de/5149188e-b7a9-4cf2-bcac-05877b0427de.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e4084833-07e1-4db9-8139-539cda1e866d/e4084833-07e1-4db9-8139-539cda1e866d.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/999b7ca8-c3f9-4617-8abb-30cd47f14815/999b7ca8-c3f9-4617-8abb-30cd47f14815.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/49d61503-98be-4802-a6b8-bdcf4dc0cc50/49d61503-98be-4802-a6b8-bdcf4dc0cc50.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/857870d5-9f96-424b-8b72-e784a1b7bc5a/857870d5-9f96-424b-8b72-e784a1b7bc5a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9b0ee1f9-8011-4094-81bd-a033ef27b653/9b0ee1f9-8011-4094-81bd-a033ef27b653.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9a190ffc-f713-41cb-9d0d-2bae575b64ec/9a190ffc-f713-41cb-9d0d-2bae575b64ec.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e099c7b7-6b13-462d-967b-474d66728b3c/e099c7b7-6b13-462d-967b-474d66728b3c.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f121d8bd-269f-4854-a25e-951589ce1084/f121d8bd-269f-4854-a25e-951589ce1084.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f782bd18-7615-46f9-bb73-7094591f0949/f782bd18-7615-46f9-bb73-7094591f0949.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/d8148503-f70d-4046-a526-767bae53e13f/d8148503-f70d-4046-a526-767bae53e13f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/dea1c171-f3de-4a87-9e8f-267f10776be3/dea1c171-f3de-4a87-9e8f-267f10776be3.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/5847a2a3-7d9a-49c1-89b0-07d2167c9ac7/5847a2a3-7d9a-49c1-89b0-07d2167c9ac7.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/8b8babd9-cdc5-4c16-bd83-41a23dde53a4/8b8babd9-cdc5-4c16-bd83-41a23dde53a4.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/cf259fb5-9370-40c8-a02f-438d25debce6/cf259fb5-9370-40c8-a02f-438d25debce6.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/e37ceebd-ec35-4d2a-9090-c0da8b5c1cd2/e37ceebd-ec35-4d2a-9090-c0da8b5c1cd2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/c8ef8a26-c74d-4516-b34e-2ab4e8646deb/c8ef8a26-c74d-4516-b34e-2ab4e8646deb.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f86997cf-ce46-402a-8f77-f2446dfaf616/f86997cf-ce46-402a-8f77-f2446dfaf616.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/1e0783f1-fe10-4e32-9919-c68cabec7987/1e0783f1-fe10-4e32-9919-c68cabec7987.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/86f66baa-ac92-493f-acb3-1631a6d45f0a/86f66baa-ac92-493f-acb3-1631a6d45f0a.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/b8572f2c-3bcb-4b83-8abb-161e308a0e10/b8572f2c-3bcb-4b83-8abb-161e308a0e10.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/92edb04e-ece2-4770-9d43-516440e08c04/92edb04e-ece2-4770-9d43-516440e08c04.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/9d90c2ea-c4b5-41dd-88c3-e238f2a303de/9d90c2ea-c4b5-41dd-88c3-e238f2a303de.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/f31cccd5-bff1-4f53-a5af-e376b7ed8fce/f31cccd5-bff1-4f53-a5af-e376b7ed8fce.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/134f0853-04c9-4416-be2c-4ac993b7dbfd/134f0853-04c9-4416-be2c-4ac993b7dbfd.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/bc517ffc-e13e-4125-a6fd-47817d0b38b2/bc517ffc-e13e-4125-a6fd-47817d0b38b2.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/ab8c15f2-5b95-462c-b2f1-41d0753a2e9f/ab8c15f2-5b95-462c-b2f1-41d0753a2e9f.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/4fd31cc8-13c0-4755-8def-182a77d95fd4/4fd31cc8-13c0-4755-8def-182a77d95fd4.tif' not recognized as a supported file format.\n",
+ "ERROR 4: `/vsimem/fb2e15cc-37b0-484c-be70-796ad3737469/fb2e15cc-37b0-484c-be70-796ad3737469.tif' not recognized as a supported file format.\n"
+ ]
+ }
+ ],
+ "source": [
+ "r = httpx.get(\n",
+ " f\"{client.endpoint}/tilejson.json\",\n",
+ " params = {\n",
+ " # Data is stored as RGB-NIR\n",
+ " \"bidx\": [1, 4],\n",
+ " \"algo\": \"normalizedIndex\",\n",
+ " \"rescale\": \"0,1\",\n",
+ " \"colormap_name\": \"greens\"\n",
+ " }\n",
+ ").json()\n",
+ "\n",
+ "bounds = r[\"bounds\"]\n",
+ "m = Map(\n",
+ " location=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
+ " zoom_start=r[\"minzoom\"]\n",
+ ")\n",
+ "\n",
+ "aod_layer = TileLayer(\n",
+ " tiles=r[\"tiles\"][0],\n",
+ " opacity=1,\n",
+ " attr=\"Yo!!\"\n",
+ ")\n",
+ "aod_layer.add_to(m)\n",
+ "m"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0398886c",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.9"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/pyproject.toml b/pyproject.toml
index 5794e2f..64b86e2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -20,6 +20,7 @@ dynamic = ["version"]
dependencies = [
"braceexpand",
"rio-cogeo>=3.1",
+ "rio-tiler>=3.1.5",
"titiler.core>=0.5,<0.8",
"starlette-cramjam>=0.3,<0.4",
"uvicorn",
diff --git a/rio_viz/algorithm/__init__.py b/rio_viz/algorithm/__init__.py
new file mode 100644
index 0000000..2b3508c
--- /dev/null
+++ b/rio_viz/algorithm/__init__.py
@@ -0,0 +1,15 @@
+"""rio_viz.algorithm."""
+
+from typing import Dict, Type
+
+from rio_viz.algorithm.base import AlgorithmMetadata, BaseAlgorithm # noqa
+from rio_viz.algorithm.dem import Contours, HillShade, TerrainRGB, Terrarium
+from rio_viz.algorithm.index import NormalizedIndex
+
+AVAILABLE_ALGORITHM: Dict[str, Type[BaseAlgorithm]] = {
+ "hillshade": HillShade,
+ "contours": Contours,
+ "normalizedIndex": NormalizedIndex,
+ "terrarium": Terrarium,
+ "terrainrgb": TerrainRGB,
+}
diff --git a/rio_viz/algorithm/base.py b/rio_viz/algorithm/base.py
new file mode 100644
index 0000000..2a92376
--- /dev/null
+++ b/rio_viz/algorithm/base.py
@@ -0,0 +1,37 @@
+"""Algorithm base class."""
+
+import abc
+from typing import Dict, Optional, Sequence
+
+from pydantic import BaseModel
+from rio_tiler.models import ImageData
+
+
+class BaseAlgorithm(BaseModel, metaclass=abc.ABCMeta):
+ """Algorithm baseclass."""
+
+ input_nbands: int
+
+ output_nbands: int
+ output_dtype: str
+ output_min: Optional[Sequence]
+ output_max: Optional[Sequence]
+
+ @abc.abstractmethod
+ def apply(self, img: ImageData) -> ImageData:
+ """Apply"""
+ ...
+
+ class Config:
+ """Config for model."""
+
+ extra = "allow"
+
+
+class AlgorithmMetadata(BaseModel):
+ """Algorithm metadata."""
+
+ name: str
+ inputs: Dict
+ outputs: Dict
+ params: Dict
diff --git a/rio_viz/algorithm/dem.py b/rio_viz/algorithm/dem.py
new file mode 100644
index 0000000..a58d4d3
--- /dev/null
+++ b/rio_viz/algorithm/dem.py
@@ -0,0 +1,163 @@
+"""rio_viz.algorithm DEM."""
+
+import numpy
+from rio_tiler.colormap import apply_cmap, cmap
+from rio_tiler.models import ImageData
+from rio_tiler.utils import linear_rescale
+
+from rio_viz.algorithm.base import BaseAlgorithm
+
+
+class HillShade(BaseAlgorithm):
+ """Hillshade."""
+
+ azimuth: int = 90
+ angle_altitude: float = 90
+
+ input_nbands: int = 1
+
+ output_nbands: int = 1
+ output_dtype: str = "uint8"
+
+ def apply(self, img: ImageData) -> ImageData:
+ """Create hillshade from DEM dataset."""
+ data = img.data[0]
+ mask = img.mask
+
+ x, y = numpy.gradient(data)
+
+ slope = numpy.pi / 2.0 - numpy.arctan(numpy.sqrt(x * x + y * y))
+ aspect = numpy.arctan2(-x, y)
+ azimuthrad = self.azimuth * numpy.pi / 180.0
+ altituderad = self.angle_altitude * numpy.pi / 180.0
+ shaded = numpy.sin(altituderad) * numpy.sin(slope) + numpy.cos(
+ altituderad
+ ) * numpy.cos(slope) * numpy.cos(azimuthrad - aspect)
+ hillshade_array = 255 * (shaded + 1) / 2
+
+ # ImageData only accept image in form of (count, height, width)
+ arr = numpy.expand_dims(hillshade_array, axis=0).astype(dtype=numpy.uint8)
+
+ return ImageData(
+ arr,
+ mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
+
+
+class Contours(BaseAlgorithm):
+ """Contours.
+
+ Original idea from https://custom-scripts.sentinel-hub.com/dem/contour-lines/
+ """
+
+ increment: int = 35
+ thickness: int = 1
+ minz: int = -12000
+ maxz: int = 8000
+
+ input_nbands: int = 1
+
+ output_nbands: int = 3
+ output_dtype: str = "uint8"
+
+ def apply(self, img: ImageData) -> ImageData:
+ """Add contours."""
+ data = img.data
+
+ # Apply rescaling for minz,maxz to 1->255 and apply Terrain colormap
+ arr = linear_rescale(data, (self.minz, self.maxz), (1, 255)).astype("uint8")
+ arr, _ = apply_cmap(arr, cmap.get("terrain"))
+
+ # set black (0) for contour lines
+ arr = numpy.where(data % self.increment < self.thickness, 0, arr)
+
+ return ImageData(
+ arr,
+ img.mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
+
+
+class Terrarium(BaseAlgorithm):
+ """Encode DEM into RGB (Mapzen Terrarium)."""
+
+ input_nbands: int = 1
+
+ output_nbands: int = 3
+ output_dtype: str = "uint8"
+
+ def apply(self, img: ImageData) -> ImageData:
+ """Encode DEM into RGB."""
+ data = numpy.clip(img.data[0] + 32768.0, 0.0, 65535.0)
+ r = data / 256
+ g = data % 256
+ b = (data * 256) % 256
+ arr = numpy.stack([r, g, b]).astype(numpy.uint8)
+ print(arr.shape)
+ return ImageData(
+ arr,
+ img.mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
+
+
+class TerrainRGB(BaseAlgorithm):
+ """Encode DEM into RGB (Mapbox Terrain RGB)."""
+
+ interval: int = 1
+ baseval: int = -10000
+
+ input_nbands: int = 1
+
+ output_nbands: int = 3
+ output_dtype: str = "uint8"
+
+ def apply(self, img: ImageData) -> ImageData:
+ """Encode DEM into RGB (Mapbox Terrain RGB).
+
+ Code from https://github.com/mapbox/rio-rgbify/blob/master/rio_rgbify/encoders.py (MIT)
+
+ """
+
+ def _range_check(datarange):
+ """
+ Utility to check if data range is outside of precision for 3 digit base 256
+ """
+ maxrange = 256**3
+
+ return datarange > maxrange
+
+ round_digits = 0
+
+ data = img.data[0].astype(numpy.float64)
+ data -= self.baseval
+ data /= self.interval
+
+ data = numpy.around(data / 2**round_digits) * 2**round_digits
+
+ rows, cols = data.shape
+ datarange = data.max() - data.min()
+ if _range_check(datarange):
+ raise ValueError("Data of {} larger than 256 ** 3".format(datarange))
+
+ rgb = numpy.zeros((3, rows, cols), dtype=numpy.uint8)
+ rgb[2] = ((data / 256) - (data // 256)) * 256
+ rgb[1] = (((data // 256) / 256) - ((data // 256) // 256)) * 256
+ rgb[0] = (
+ (((data // 256) // 256) / 256) - (((data // 256) // 256) // 256)
+ ) * 256
+
+ return ImageData(
+ rgb,
+ img.mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
diff --git a/rio_viz/algorithm/index.py b/rio_viz/algorithm/index.py
new file mode 100644
index 0000000..7c5b1b8
--- /dev/null
+++ b/rio_viz/algorithm/index.py
@@ -0,0 +1,37 @@
+"""rio_viz.algorithm Normalized Index."""
+
+from typing import Sequence
+
+import numpy
+from rio_tiler.models import ImageData
+
+from rio_viz.algorithm.base import BaseAlgorithm
+
+
+class NormalizedIndex(BaseAlgorithm):
+ """Normalized Difference Index."""
+
+ input_nbands: int = 2
+
+ output_nbands: int = 1
+ output_dtype: str = "float32"
+ output_min: Sequence[float] = [-1.0]
+ output_max: Sequence[float] = [1.0]
+
+ def apply(self, img: ImageData) -> ImageData:
+ """Normalized difference."""
+ b1 = img.data[0].astype("float32")
+ b2 = img.data[1].astype("float32")
+
+ arr = numpy.where(img.mask, (b2 - b1) / (b2 + b1), 0)
+
+ # ImageData only accept image in form of (count, height, width)
+ arr = numpy.expand_dims(arr, axis=0).astype(self.output_dtype)
+
+ return ImageData(
+ arr,
+ img.mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
diff --git a/rio_viz/app.py b/rio_viz/app.py
index 35a5e74..15c82eb 100644
--- a/rio_viz/app.py
+++ b/rio_viz/app.py
@@ -21,6 +21,8 @@
from starlette.types import ASGIApp
from starlette_cramjam.middleware import CompressionMiddleware
+from rio_viz.algorithm import AVAILABLE_ALGORITHM, AlgorithmMetadata
+from rio_viz.dependency import PostProcessParams
from rio_viz.resources.enums import RasterFormat, VectorTileFormat, VectorTileType
from titiler.core.dependencies import (
@@ -36,7 +38,6 @@
HistogramParams,
ImageParams,
ImageRenderingParams,
- PostProcessParams,
StatisticsParams,
)
from titiler.core.models.mapbox import TileJSON
@@ -310,19 +311,26 @@ def preview(
# Adapt options for each reader type
self._update_params(src_dst, layer_params)
- data = src_dst.preview(
+ img = src_dst.preview(
**layer_params,
**dataset_params,
**img_params,
)
dst_colormap = getattr(src_dst, "colormap", None)
- if not format:
- format = RasterFormat.jpeg if data.mask.all() else RasterFormat.png
+ if postprocess_params.image_process:
+ img = postprocess_params.image_process.apply(img)
+
+ if postprocess_params.rescale:
+ img.rescale(postprocess_params.rescale)
+
+ if postprocess_params.color_formula:
+ img.apply_color_formula(postprocess_params.color_formula)
- image = data.post_process(**postprocess_params)
+ if not format:
+ format = RasterFormat.jpeg if img.mask.all() else RasterFormat.png
- content = image.render(
+ content = img.render(
img_format=format.driver,
colormap=colormap or dst_colormap,
**format.profile,
@@ -375,7 +383,7 @@ def part(
# Adapt options for each reader type
self._update_params(src_dst, layer_params)
- data = src_dst.part(
+ img = src_dst.part(
[minx, miny, maxx, maxy],
**layer_params,
**dataset_params,
@@ -383,9 +391,16 @@ def part(
)
dst_colormap = getattr(src_dst, "colormap", None)
- image = data.post_process(**postprocess_params)
+ if postprocess_params.image_process:
+ img = postprocess_params.image_process.apply(img)
+
+ if postprocess_params.rescale:
+ img.rescale(postprocess_params.rescale)
+
+ if postprocess_params.color_formula:
+ img.apply_color_formula(postprocess_params.color_formula)
- content = image.render(
+ content = img.render(
img_format=format.driver,
colormap=colormap or dst_colormap,
**format.profile,
@@ -430,17 +445,24 @@ def geojson_part(
# Adapt options for each reader type
self._update_params(src_dst, layer_params)
- data = src_dst.feature(
+ img = src_dst.feature(
geom.dict(exclude_none=True), **layer_params, **dataset_params
)
dst_colormap = getattr(src_dst, "colormap", None)
- if not format:
- format = RasterFormat.jpeg if data.mask.all() else RasterFormat.png
+ if postprocess_params.image_process:
+ img = postprocess_params.image_process.apply(img)
+
+ if postprocess_params.rescale:
+ img.rescale(postprocess_params.rescale)
- image = data.post_process(**postprocess_params)
+ if postprocess_params.color_formula:
+ img.apply_color_formula(postprocess_params.color_formula)
- content = image.render(
+ if not format:
+ format = RasterFormat.jpeg if img.mask.all() else RasterFormat.png
+
+ content = img.render(
img_format=format.driver,
colormap=colormap or dst_colormap,
**format.profile,
@@ -493,7 +515,7 @@ def tile(
# Adapt options for each reader type
self._update_params(src_dst, layer_params)
- tile_data = src_dst.tile(
+ img = src_dst.tile(
x,
y,
z,
@@ -519,22 +541,27 @@ def tile(
)
content = pixels_encoder(
- tile_data.data,
- tile_data.mask,
- tile_data.band_names,
+ img.data,
+ img.mask,
+ img.band_names,
feature_type=feature_type.value,
)
# Raster Tile
else:
- if not format:
- format = (
- RasterFormat.jpeg if tile_data.mask.all() else RasterFormat.png
- )
+ if postprocess_params.image_process:
+ img = postprocess_params.image_process.apply(img)
+
+ if postprocess_params.rescale:
+ img.rescale(postprocess_params.rescale)
+
+ if postprocess_params.color_formula:
+ img.apply_color_formula(postprocess_params.color_formula)
- image = tile_data.post_process(**postprocess_params)
+ if not format:
+ format = RasterFormat.jpeg if img.mask.all() else RasterFormat.png
- content = image.render(
+ content = img.render(
img_format=format.driver,
colormap=colormap or dst_colormap,
**format.profile,
@@ -654,6 +681,35 @@ def wmts(
media_type="application/xml",
)
+ @self.router.get(
+ "/algorithm",
+ response_model=List[AlgorithmMetadata],
+ )
+ def algo(request: Request):
+ """Handle /algorithm."""
+ algos = []
+ for k, v in AVAILABLE_ALGORITHM.items():
+ props = v.schema()["properties"]
+ ins = {
+ k.replace("input_", ""): v
+ for k, v in props.items()
+ if k.startswith("input_")
+ }
+ outs = {
+ k.replace("output_", ""): v
+ for k, v in props.items()
+ if k.startswith("output_")
+ }
+ params = {
+ k: v
+ for k, v in props.items()
+ if not k.startswith("input_") and not k.startswith("output_")
+ }
+ algos.append(
+ AlgorithmMetadata(name=k, inputs=ins, outputs=outs, params=params)
+ )
+ return algos
+
@self.router.get(
"/",
responses={200: {"description": "Simple COG viewer."}},
diff --git a/rio_viz/dependency.py b/rio_viz/dependency.py
new file mode 100644
index 0000000..2c543e0
--- /dev/null
+++ b/rio_viz/dependency.py
@@ -0,0 +1,49 @@
+"""rio_viz dependency."""
+
+import json
+from dataclasses import dataclass, field
+from enum import Enum
+from typing import List, Optional
+
+from fastapi import Query
+
+from rio_viz.algorithm import AVAILABLE_ALGORITHM
+from rio_viz.algorithm.base import BaseAlgorithm
+
+Algorithm = Enum( # type: ignore
+ "Algorithm", [(a, a) for a in AVAILABLE_ALGORITHM.keys()]
+)
+
+
+@dataclass
+class PostProcessParams:
+ """Data Post-Processing options."""
+
+ rescale: Optional[List[str]] = Query(
+ None,
+ title="Min/Max data Rescaling",
+ description="comma (',') delimited Min,Max range. Can set multiple time for multiple bands.",
+ example=["0,2000", "0,1000", "0,10000"], # band 1 # band 2 # band 3
+ )
+ color_formula: Optional[str] = Query(
+ None,
+ title="Color Formula",
+ description="rio-color formula (info: https://github.com/mapbox/rio-color)",
+ )
+ algorithm: Algorithm = Query(None, description="Algorithm name", alias="algo")
+ algorithm_params: str = Query(
+ None, description="Algorithm parameter", alias="algo_params"
+ )
+
+ image_process: Optional[BaseAlgorithm] = field(init=False, default=None)
+
+ def __post_init__(self):
+ """Post Init."""
+ if self.rescale:
+ self.rescale = [ # type: ignore
+ tuple(map(float, r.replace(" ", "").split(","))) for r in self.rescale
+ ]
+
+ kwargs = json.loads(self.algorithm_params) if self.algorithm_params else {}
+ if self.algorithm:
+ self.image_process = AVAILABLE_ALGORITHM[self.algorithm.name](**kwargs)