🌐 Local tile server for viewing geospatial raster files with ipyleaflet

Overview

🌐 Local Tile Server for Geospatial Rasters

PyPI codecov

Need to visualize a rather large raster (gigabytes) you have locally? This is for you.

A Flask application for serving tiles from large raster files in the Slippy Maps standard (i.e., /zoom/x/y.png)

Disclaimer: I whipped this together over a weekend and I'm definitely going to change a few things moving forward to make it more stable/robust. This means that things will most likely break between minor releases (I use the major.minor.patch versioning scheme).

tile-diagram

🌟 Highlights

  • Create a local tile server for large geospatial images
  • Extract regions of interest (ROIs) interactively
  • View local raster files with ipyleaflet

Under the hood, this uses large_image to launch a tile server in a background thread which will serve raster imagery to a tile viewer (see ipyleaflet examples below). This tile server can efficiently deliver varying levels of detail of your raster imagery to your viewer; it helps to have pre-tiled, Cloud Optimized GeoTIFFs (COG), but no wories if not as large_image will tile and cache for you when opening the raster.

There is an included, standalone web viewer leveraging GeoJS. You can use the web viewer to select and extract regions of interest from rasters.

⬇️ Installation

Install from PyPI: https://pypi.org/project/flask-tileserver/

pip install flask-tileserver

πŸ“ A Brief Note on Installing GDAL

GDAL can be a pain in the πŸ‘ to install, and you may want to handle GDAL before installing flask-tileserver.

If on linux, I highly recommend using the large_image_wheels from Kitware.

pip install --find-links=https://girder.github.io/large_image_wheels --no-cache GDAL

Otherwise, I recommend using conda:

conda install -c conda-forge GDAL

πŸ’­ Feedback

Please share your thoughts and questions on the Discussions board. If you would like to report any bugs or make feature requests, please open an issue.

If filing a bug report, please share a scooby Report:

import tileserver
print(tileserver.Report())

πŸš€ Usage

πŸƒ ipyleaflet Tile Layers

The TileServer class is a nifty tool to launch a tile server as a background thread to serve image tiles from any raster file on your local file system. Additionally, it can be used in conjunction with the get_leaflet_tile_layer utility to create an ipyleaflet.TileLayer for interactive visualization in a Jupyter notebook. Here is an example:

from tileserver import get_leaflet_tile_layer, TileServer
from ipyleaflet import Map

# First, create a tile server from local raster file
tile_server = TileServer('~/Desktop/TC_NG_SFBay_US_Geo.tif')

# Create ipyleaflet tile layer from that server
t = get_leaflet_tile_layer(tile_server)

# Create ipyleaflet map, add tile layer, and display
m = Map(center=tile_server.center())
m.add_layer(t)
m

ipyleaflet

πŸ₯“ Two Rasters at Once

from tileserver import get_leaflet_tile_layer
from ipyleaflet import Map, ScaleControl, FullScreenControl, SplitMapControl

m = Map(center=(37.7249511580583, -122.27230466902257), zoom=9)

# Create 2 tile layers from 2 separate raster files
l = get_leaflet_tile_layer('~/Desktop/TC_NG_SFBay_US_Geo.tif',
                           band=1, palette='matplotlib.Viridis_20', vmin=50, vmax=200)
r = get_leaflet_tile_layer('~/Desktop/small.tif',
                           band=2, palette='matplotlib.Plasma_6', vmin=0, vmax=150)

control = SplitMapControl(left_layer=l, right_layer=r)
m.add_control(control)
m.add_control(ScaleControl(position='bottomleft'))
m.add_control(FullScreenControl())
m

ipyleaflet-double

🎯 Using ipyleaflet for ROI Extraction

from tileserver import get_leaflet_tile_layer, TileServer
from ipyleaflet import Map, ScaleControl, FullScreenControl, DrawControl

# First, create a tile server from local raster file
tile_server = TileServer('~/Desktop/TC_NG_SFBay_US_Geo.tif')

# Create ipyleaflet tile layer from that server
t = get_leaflet_tile_layer(tile_server)

# Create ipyleaflet map, add layers, add draw control, display
m = Map(center=(37.7249511580583, -122.27230466902257), zoom=9)
m.add_layer(t)
m.add_control(ScaleControl(position='bottomleft'))
m.add_control(FullScreenControl())
draw_control = DrawControl()
m.add_control(draw_control)
m

ipyleaflet-draw-roi

from shapely.geometry import Polygon

# Inspect `draw_control.data` to get the ROI
bbox = draw_control.data[0]
p = Polygon([tuple(l) for l in bbox['geometry']['coordinates'][0]])
left, bottom, right, top = p.bounds

roi_path = tile_server.extract_roi(left, right, bottom, top)
roi_path
r = get_leaflet_tile_layer(roi_path)

m2 = Map(
        center=(37.7249511580583, -122.27230466902257),
        zoom=9,
       )
m2.add_layer(r)
m2.add_control(ScaleControl(position='bottomleft'))
m2.add_control(FullScreenControl())
m2

ipyleaflet-roi

πŸ—ΊοΈ Example Datasets

A few example datasets are included with tileserver. A particularly useful one has global elevation data which you can use to create high resolution Digital Elevation Models (DEMs) of a local region.

from tileserver import get_leaflet_tile_layer, examples
from ipyleaflet import Map, DrawControl

# Load example tile layer from publicly available DEM source
tile_server = examples.get_elevation()

# Create ipyleaflet tile layer from that server
t = get_leaflet_tile_layer(tile_server,
                           band=1, vmin=-500, vmax=5000,
                           palette='mycarta.Cube1_19',
                           opacity=0.75)

m = Map(zoom=2)
m.add_layer(t)
draw_control = DrawControl()
m.add_control(draw_control)
m

elevation

Then you can follow the same routine as described above to extract an ROI.

I zoomed in over Golden, Colorado and drew a polygon of the extent of the DEM I would like to create:

golden

And perform the extraction:

from shapely.geometry import Polygon

# Inspect `draw_control.data` to get the ROI
bbox = draw_control.data[0]
p = Polygon([tuple(l) for l in bbox['geometry']['coordinates'][0]])
left, bottom, right, top = p.bounds

roi_path = tile_server.extract_roi(left, right, bottom, top)

r = get_leaflet_tile_layer(roi_path, band=1,
                           palette='mycarta.Cube1_19', opacity=0.75)

m2 = Map(
        center=(39.763427033262175, -105.20614908076823),
        zoom=12,
       )
m2.add_layer(r)
m2

golden-dem

Here is another example with the Virtual Earth satellite imagery

from tileserver import get_leaflet_tile_layer, examples
from ipyleaflet import Map, DrawControl

# Load example tile layer from publicly available imagery
tile_server = examples.get_virtual_earth()

# Create ipyleaflet tile layer from that server
t = get_leaflet_tile_layer(tile_server,opacity=1)

m = Map(center=(39.751343612695145, -105.22181306125279), zoom=18)
m.add_layer(t)
draw_control = DrawControl()
m.add_control(draw_control)
m

kafadar

πŸ–₯️ Local Web Application

Launch the tileserver from the commandline to use the included web application where you can view the raster and extract regions of interest.

python -m tileserver path/to/raster.tif

webviewer

webviewer-roi

Usage Notes

  • get_leaflet_tile_layer accepts either an existing TileServer or a path from which to create a TileServer under the hood.
  • The color palette choices come from palettable.
Comments
  • Accessing localtileserver from remote Jupyter environment

    Accessing localtileserver from remote Jupyter environment

    The localtileserver works nicely locally. However, I have not been able to make it work in a cloud environment. I have tested it multiple cloud env without success, such as https://binder.pangeo.io, https://mybinder.org, https://streamlit.io/cloud and Google Colab. Below is the environment.yml I used to create the env. It would be nice to have a working env that users can launch a notebook to test localtileserver with a simple click.

    name: tileserver
    channels:
      - conda-forge
    dependencies:
      - gdal=3.2.2
      - pip
      - pip:
          - geopandas
          - leafmap
          - localtileserver
    
    opened by giswqs 12
  • AttributeError: 'Map' object has no attribute 'add_child'

    AttributeError: 'Map' object has no attribute 'add_child'

    I am trying to run the minimal example and getting this error. Maybe I am missing something big. Screen Shot 2022-03-30 at 8 14 15 AM

    Report:

    Date: Tue Mar 29 23:20:12 2022 UTC

                     OS : Linux
                 CPU(s) : 8
                Machine : x86_64
           Architecture : 64bit
                    RAM : 31.4 GiB
            Environment : Jupyter
    
      Python 3.8.10 (default, Nov 26 2021, 20:14:08)  [GCC 9.3.0]
    
        localtileserver : 0.4.4
                  flask : 2.1.0
          flask_caching : 1.10.1
            flask_restx : 0.5.1
               requests : 2.27.1
               werkzeug : 2.0.3
                  click : 8.0.4
                 scooby : 0.5.12
            large_image : 1.12.0
    large_image_source_gdal : 1.12.0
             cachetools : 5.0.0
                    PIL : 9.0.1
                 psutil : 5.9.0
                  numpy : 1.22.3
             palettable : 3.3.0
                 pyproj : 3.3.0
             osgeo.gdal : 3.0.4
             ipyleaflet : 0.15.0
              traitlets : 5.1.1
                shapely : 1.8.1.post1
                 folium : 0.12.1.post1
             matplotlib : 3.5.1
    

    opened by haseeb33 10
  • Extend to fix ImageOverlay, too?

    Extend to fix ImageOverlay, too?

    Thank you! This repo looks very promising, indeed, and gives me hope to work around https://github.com/jupyter-widgets/ipyleaflet/issues/234! Is there any chance to extend this to load ImageOverlays also from local files and/or memory, like mentioned in that issue's title? That would allow to refresh the image inside an ImageOverlay which should work with this approach, too.

    opened by deeplook 10
  • get_leaflet_tile_layer error (v0.3.13)

    get_leaflet_tile_layer error (v0.3.13)

    Both v0.3.13 and the GitHub source throws the same error when using the example. v0.3.12 works fine.

    from localtileserver import get_leaflet_tile_layer, TileClient
    from ipyleaflet import Map
    
    # First, create a tile server from local raster file
    tile_client = TileClient('~/Downloads/dem.tif')
    
    # Create ipyleaflet tile layer from that server
    t = get_leaflet_tile_layer(tile_client)
    
    # Create ipyleaflet map, add tile layer, and display
    m = Map(center=tile_client.center())
    m.add_layer(t)
    m
    

    v0.3.13 image

    v0.3.12 image

    opened by giswqs 9
  • Bokeh tile server

    Bokeh tile server

    I'd like to use localtileserver in conjunction with bokeh, though I'm not having luck. Ideally, I'd like to spin up a bokeh server, though I haven't had luck within jupyter either. I suspect this is related to 66, just not sure exactly how to point bokeh to the tiles served up by this repo.

    opened by avanetten 8
  • localtileserver with streamlit

    localtileserver with streamlit

    I created an interactive streamlit web app for visualizing local and remote COG based on localtileserver and leafmap. The web app works fine when running locally. However, when deployed to Streamlit Cloud, the tile layer won't show up. I turned on the debug mode and found that the app in streamlit cloud is missing GET /tiles/. See the screenshots and video demo below. Any advice? Thanks.

    Web App: https://share.streamlit.io/giswqs/streamlit-geospatial/app.py?page=Visualize+Raster+Data Source code: https://github.com/giswqs/streamlit-geospatial/blob/master/apps/raster.py

    The app running on Streamlit Cloud (missing GET /tiles/ ) - layer not shown up image

    The app running locally (with GET /tiles/ ) - layer shown up correctly image

    https://user-images.githubusercontent.com/5016453/143720329-fa20b1f8-3f1c-4cb0-9460-735d9d23da19.mp4

    opened by giswqs 8
  • Packaging with pyinstaller

    Packaging with pyinstaller

    Hello, I am using the localetileserver, and it is working but when I try to convert my py to exe the program shows me this error.

    large_image.exceptions.TileSourceError: No available tilesource for C:\Users\iiMox\AppData\Local\Temp_MEI50602\NE1_LR_LC_SR_W_DR.tif

    opened by iiMox 7
  • Deploy on Heroku

    Deploy on Heroku

    Its live at https://localtileserver-demo.herokuapp.com

    I'm using a free dyno so if this gets any traffic at all, it will probably crash

    The changes in this PR make it so that any URL file can be passed as a query param at that URL for viewing. For example:

    https://localtileserver-demo.herokuapp.com?filename=https://opendata.digitalglobe.com/events/california-fire-2020/pre-event/2018-02-16/pine-gulch-fire20/1030010076004E00.tif

    And another file hosted on S3: https://localtileserver-demo.herokuapp.com/?filename=s3://sentinel-cogs/sentinel-s2-l2a-cogs/2020/S2A_31QHU_20200714_0_L2A/B01.tif

    opened by banesullivan 7
  • Multiband support and MPL colormaps

    Multiband support and MPL colormaps

    Resolve #22

    This all feels a bit hacky, but it works. @giswqs, would you please review/test.

    Here is an example

    from localtileserver import get_leaflet_tile_layer, TileClient
    from ipyleaflet import Map
    
    # First, create a tile server from local raster file
    tile_client = TileClient('./landsat.tif')
    
    # Create ipyleaflet tile layer from that server
    t = get_leaflet_tile_layer(tile_client, band=[4, 3, 2])
    
    # Create ipyleaflet map, add tile layer, and display
    m = Map(center=tile_client.center())
    m.add_layer(t)
    m
    
    Screen Shot 2021-12-05 at 1 12 18 PM 1

    or like the screenshots in #22:

    # Create ipyleaflet tile layer from that server
    t = get_leaflet_tile_layer(tile_client, band=[5, 4, 3])
    
    # Create ipyleaflet map, add tile layer, and display
    m = Map(center=tile_client.center())
    m.add_layer(t)
    m
    
    Screen Shot 2021-12-05 at 1 17 28 PM

    To do:

    • [x] Update type hints and documentation
    • [x] Add example to README
    • [ ] User test
    opened by banesullivan 7
  • Add package to conda-forge

    Add package to conda-forge

    Thank you for developing this nice package. I just tested it on my computer, and it works like a charm! I plan to incorporate the package into geemap and leafmap. Would you consider making the package available on conda-forge? Thanks.

    opened by giswqs 6
  • Update flake8 requirement from <5.0.0 to <6.0.0

    Update flake8 requirement from <5.0.0 to <6.0.0

    Updates the requirements on flake8 to permit the latest version.

    Commits
    • 70c0b3d Release 5.0.2
    • 5e69ba9 Merge pull request #1642 from PyCQA/no-home
    • 8b51ee4 skip skipping home if home does not exist
    • 446b18d Merge pull request #1641 from PyCQA/entry-points-not-pickleable
    • b70d7a2 work around un-pickleabiliy of EntryPoint in 3.8.0
    • 91a7fa9 fix order of release notes
    • 405cfe0 Release 5.0.1
    • d20bb97 Merge pull request #1631 from PyCQA/dupe-sys-path
    • fce93b9 prevent duplicate plugin discovery on misconfigured pythons
    • 3f4872a Merge pull request #1628 from mxr/patch-1
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies python 
    opened by dependabot[bot] 5
  • Bump sphinx from 5.3.0 to 6.0.0

    Bump sphinx from 5.3.0 to 6.0.0

    Bumps sphinx from 5.3.0 to 6.0.0.

    Release notes

    Sourced from sphinx's releases.

    v6.0.0

    Changelog: https://www.sphinx-doc.org/en/master/changes.html

    v6.0.0b2

    Changelog: https://www.sphinx-doc.org/en/master/changes.html

    v6.0.0b1

    Changelog: https://www.sphinx-doc.org/en/master/changes.html

    Changelog

    Sourced from sphinx's changelog.

    Release 6.0.0 (released Dec 29, 2022)

    Dependencies

    • #10468: Drop Python 3.6 support
    • #10470: Drop Python 3.7, Docutils 0.14, Docutils 0.15, Docutils 0.16, and Docutils 0.17 support. Patch by Adam Turner

    Incompatible changes

    • #7405: Removed the jQuery and underscore.js JavaScript frameworks.

      These frameworks are no longer be automatically injected into themes from Sphinx 6.0. If you develop a theme or extension that uses the jQuery, $, or $u global objects, you need to update your JavaScript to modern standards, or use the mitigation below.

      The first option is to use the sphinxcontrib.jquery_ extension, which has been developed by the Sphinx team and contributors. To use this, add sphinxcontrib.jquery to the extensions list in conf.py, or call app.setup_extension("sphinxcontrib.jquery") if you develop a Sphinx theme or extension.

      The second option is to manually ensure that the frameworks are present. To re-add jQuery and underscore.js, you will need to copy jquery.js and underscore.js from the Sphinx repository_ to your static directory, and add the following to your layout.html:

      .. code-block:: html+jinja

      {%- block scripts %} {{ super() }} {%- endblock %}

      .. _sphinxcontrib.jquery: https://github.com/sphinx-contrib/jquery/

      Patch by Adam Turner.

    • #10471, #10565: Removed deprecated APIs scheduled for removal in Sphinx 6.0. See :ref:dev-deprecated-apis for details. Patch by Adam Turner.

    • #10901: C Domain: Remove support for parsing pre-v3 style type directives and roles. Also remove associated configuration variables c_allow_pre_v3 and c_warn_on_allowed_pre_v3. Patch by Adam Turner.

    Features added

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies python 
    opened by dependabot[bot] 1
  • Bump python from 3.10.7-slim to 3.11.1-slim

    Bump python from 3.10.7-slim to 3.11.1-slim

    Bumps python from 3.10.7-slim to 3.11.1-slim.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies docker 
    opened by dependabot[bot] 1
  • Bump jupyter/base-notebook from python-3.9.12 to python-3.10.8

    Bump jupyter/base-notebook from python-3.9.12 to python-3.10.8

    Bumps jupyter/base-notebook from python-3.9.12 to python-3.10.8.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies docker 
    opened by dependabot[bot] 0
  • Support for Amazon SageMaker Studio Lab

    Support for Amazon SageMaker Studio Lab

    Amazon SageMaker Studio is a free cloud computing platform, similar to Binder but users can install packages and save files permanently. It seems localtileserver is not working on SageMaker, even after running the following code. Any advice?

    import os
    os.environ["LOCALTILESERVER_CLIENT_PREFIX"] = "proxy/{port}"
    

    image

    image

    image

    image

    opened by giswqs 1
  • Raster image stretch e.g. min max stretching

    Raster image stretch e.g. min max stretching

    Hi, has there been any work or examples on stretching the rasters when used with localtileserver.get_leaflet_tile_layer? Working with uint16 raster at the time and imagery is extremely dark. I have seen this example using the ee library, https://github.com/giswqs/earthengine-py-notebooks/blob/master/Visualization/image_stretch.py, but I have not seen any available args in order to work on stretching the image (https://girder.github.io/large_image/tilesource_options.html#style). Thanks!

    enhancement 
    opened by jordancaraballo 10
  • Very slow on Windows

    Very slow on Windows

    I noticed that localtileserver is very slow on Windows. It took ~13 seconds to generate tiles for thisvery small GeoTIFF (14 MB). It used to be very fast on Linux. I am not sure what causes the issue.

    Animation

    from localtileserver import get_leaflet_tile_layer, TileClient
    from ipyleaflet import Map
    
    # First, create a tile server from local raster file
    client = TileClient('srtm90.tif')
    
    # Create ipyleaflet tile layer from that server
    t = get_leaflet_tile_layer(client)
    
    m = Map(center=client.center(), zoom=client.default_zoom)
    m.add_layer(t)
    m
    

    env

    --------------------------------------------------------------------------------
      Date: Wed Aug 03 16:17:46 2022 Eastern Daylight Time
    
                         OS : Windows
                     CPU(s) : 16
                    Machine : AMD64
               Architecture : 64bit
                        RAM : 31.7 GiB
                Environment : Jupyter
    
      Python 3.10.4 | packaged by conda-forge | (main, Mar 30 2022, 08:38:02) [MSC
      v.1916 64 bit (AMD64)]
    
            localtileserver : 0.5.11
                      flask : 2.1.3
              flask_caching : 1.10.1
                 flask_cors : 3.0.10
                flask_restx : 0.5.1
                   requests : 2.28.1
                   werkzeug : 2.1.2
                      click : 8.1.3
              server_thread : 0.2.0
                     scooby : 0.5.12
                large_image : 1.15.1
    large_image_source_gdal : 1.15.1
                 cachetools : 4.2.4
                        PIL : 9.2.0
                     psutil : 5.9.1
                      numpy : 1.23.1
                 palettable : 3.3.0
                     pyproj : 3.3.1
                 osgeo.gdal : 3.4.2
                 ipyleaflet : 0.17.0
                 jupyterlab : 3.4.4
                  traitlets : 5.3.0
                    shapely : 1.8.2
                     folium : 0.12.1.post1
                 matplotlib : 3.5.2
    --------------------------------------------------------------------------------
    
    bug 
    opened by giswqs 6
Releases(0.5.5)
  • 0.5.5(Apr 29, 2022)

    New features:

    • Add COG validate helper (see #80)
    • Enable * CORS by user choice
    • Add is_geospatial property to TileClient
    • Add default_zoom property to TileClient to determine starting zoom on map
    • Handle tile serving in pixel coordinates for non-geospatial images

    Niceties:

    • Handle large_image source as input to TileClient
    • Add _ipython_display_ to TileClient to quickly display a map in Jupyter
    • Add _repr_png_ to TileClient to quickly show a thumbnail in Qt IPython
    • Add URL form field to web app

    Maintenance:

    • Maintenance of Docker images
    • Internal refactoring to utilize new server-thread package (see #79)
    • Documentation and examples improvements
    Source code(tar.gz)
    Source code(zip)
  • 0.5.3(Apr 18, 2022)

    • Style parameters can now be included as a JSON blob in the request body following the format specified by large-image or as a dict in the syle parameter in the Python client.
    • cmap alias for palette in Python client (see #71)
    • Better error handling
    • Handle Dropbox URLs
    • New save_new_raster helper method
    • Bug fixes, cleanup, and other internal maintenance (see diff)

    This release adds support for rasterio datasets so that users can easily visualize their data when working with rasterio:

    import rasterio
    from ipyleaflet import Map
    from localtileserver import TileClient, get_leaflet_tile_layer
    
    # Open raster with rasterio
    src = rasterio.open('path/to/geo.tif')
    
    # Pass rasterio source to localtileserver
    client = TileClient(src)
    
    t = get_leaflet_tile_layer(client)
    
    m = Map(center=client.center(), zoom=8)
    m.add_layer(t)
    m
    
    Source code(tar.gz)
    Source code(zip)
  • 0.4.2(Feb 6, 2022)

    This release adds support for using localtileserver in remote Jupyter environments (e.g., MyBinder or JupyterHub) through jupyter-server-proxy. Included in this release is a new Docker image on GitHub's package registry for using localtileserver in Jupyter.

    docker pull ghcr.io/banesullivan/localtileserver-jupyter:latest
    docker run -p 8888:8888 ghcr.io/banesullivan/localtileserver-jupyter:latest
    

    To configure this in your own set up, you must set the following environment variables

    • LOCALTILESERVER_CLIENT_PREFIX='proxy/{port}' - Same for everyone using jupyter-server-proxy
    • Optional:
      • LOCALTILESERVER_CLIENT_HOST=127.0.0.1 - The host on which you launch Jupyter (the URL/domain of the Jupyter instance if using MyBinder or JupyterHub)
      • LOCALTILESERVER_CLIENT_PORT=8888 - The port on which you launch Jupyter (leave blank if using MyBinder or JupyterHub)

    There is a demo in https://github.com/banesullivan/localtileserver-demo that shows how this will work on MyBinder by setting the following at run-time:

    # Set host forwarding for MyBinder
    import os
    os.environ['LOCALTILESERVER_CLIENT_PREFIX'] = f"{os.environ['JUPYTERHUB_SERVICE_PREFIX'].lstrip('/')}/proxy/{{port}}"
    

    Resolves #29, #66, and https://github.com/banesullivan/localtileserver-demo/issues/1

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Jan 12, 2022)

    This release has one breaking change (breaking for a small minority of users) where the API endpoints were renamed to have the api/ prefix where applicable (see #51). Other notes:

    • Document style parameters for Thumbnail endpoint (see 7e27db045b7798ba191f0b4350928eda17625c15)
    • Support custom, user-defined palettes (see #54)
    • Cesium Split Viewer (see #47 and https://github.com/banesullivan/localtileserver/discussions/53)
    • Cesium terrain model is now disabled by default (see fe1c2103aa13cbdc49eb5ec2e785e3a35b8907b8)

    Standalone Docker Image - #57

    Now you can easily pull a docker image for the latest release or for a specific Pull Request in the repository. Check out the tags for https://github.com/banesullivan/localtileserver/pkgs/container/localtileserver

    This is particularly useful if you do not want to install GDAL on your system or want a dedicated service for tile serving.

    To use the docker image:

    docker pull ghcr.io/banesullivan/localtileserver:latest
    docker run -p 8000:8000 ghcr.io/banesullivan/localtileserver:latest
    

    Then visit http://0.0.0.0:8000 in your browser. You can pass the ?filename= argument in the URL params to access any URL/S3 file.

    Note that you can mount your file system to access files locally. For example, I mount my Desktop by:

    docker run -p 8000:8000 -v /Users/bane/Desktop/:/data/ ghcr.io/banesullivan/localtileserver:latest
    

    Then I can add the ?filename= parameter to the URL to access the file TC_NG_SFBay_US_Geo.tif file on my desktop. Since this is mounted under /data/ in the container, you must build the path as /data/TC_NG_SFBay_US_Geo.tif, such that the URL would be http://0.0.0.0:8000/?filename=/data/TC_NG_SFBay_US_Geo.tif (or http://0.0.0.0:8000/?filename=%2Fdata%2FTC_NG_SFBay_US_Geo.tif)

    Source code(tar.gz)
    Source code(zip)
  • 0.3.13(Dec 27, 2021)

    Bye-bye, Python 3.6! πŸ‘‹πŸ»

    This release introduces an override to ipyleaflet.TileLayer that constrains the region of requested tiles, per jupyter-widgets/ipyleaflet#888. This significantly reduces the load on the tile server when viewing tiles in an ipyleaflet.Map

    This change required dropping Python 3.6 and was good timing since Python 3.6's Security Support ended Dec 23, 2021 (4 days ago) (ref https://endoflife.date/python). Since conda-forge hasn't been building on Python 3.6 for some time, I'm hoping there is minimal impact here

    Source code(tar.gz)
    Source code(zip)
  • 0.3.12(Dec 20, 2021)

    The last few tags have been full of useful/nice to have features and clean up. The follow is a recap

    • Multi-band support: create composite images from selected bands
    • Automatically opens web browser when launching from command line
    • Under the hood improvements and abstraction of the underlying flask app to a Blueprint
    • Major UI improvements with color mapping options
    • Support user provided CesiumIon tokens
    • Support memcached
    • Better handle bad filenames/URLs with 404 page
    • Improvements to CesiumJS and GeoJS tile viewers
    • Google Analytics support
    • New pixel endpoint
    • New Histogram endpoint
    • New tile sources endpoint
    • New colormaps listing endpoint

    Swagger API Docs

    There is now an /swagger/ view with full API documentation:

    | List | Tiles | |---|---| | Screen Shot 2021-12-20 at 12 41 12 AM | Screen Shot 2021-12-20 at 12 41 27 AM |

    This introduced a new flask-restx dependency.

    Docker Image

    You can now pull a pre-built docker image from the packages of this repository

    docker pull ghcr.io/banesullivan/localtileserver/localtileserver:latest
    

    To run:

    docker run --rm -it -p 8000:8000 ghcr.io/banesullivan/localtileserver/localtileserver
    

    If you want to serve/visualize tiles from files on your local system, simply mount the directory:

    docker run --rm -it -p 8000:8000 -v /path/to/mount/:/data ghcr.io/banesullivan/localtileserver/localtileserver
    

    Then be sure to put the ?filename=/data/... in the URL params

    Source code(tar.gz)
    Source code(zip)
  • 0.3.5(Dec 6, 2021)

    This release adds support for three new features:

    • Choose which bands to use for RGB channels when tile serving
    • Generate thumbnails with the same styling parameters as tile serving
    • Use any Matplotlib colormap as a palette choice

    Example

    There is a new example in the README to demonstrate RGB channel selection:

    from localtileserver import get_leaflet_tile_layer, TileClient
    from ipyleaflet import Map, ScaleControl, FullScreenControl, SplitMapControl
    
    # First, create a tile server from local raster file
    tile_client = TileClient('landsat.tif')
    
    # Create 2 tile layers from same raster viewing different bands
    l = get_leaflet_tile_layer(tile_client, band=[7, 5, 4])
    r = get_leaflet_tile_layer(tile_client, band=[5, 3, 2])
    
    # Make the ipyleaflet map
    m = Map(center=tile_client.center(), zoom=12)
    control = SplitMapControl(left_layer=l, right_layer=r)
    m.add_control(control)
    m.add_control(ScaleControl(position='bottomleft'))
    m.add_control(FullScreenControl())
    m
    
    ipyleaflet-multi-bands

    Thumbnails

    and you can also generate styled thumbnails with

    tile_client.thumbnail(band=[5, 3, 2], output_path='thumbnail_styled.png')
    

    thumbnail

    as opposed to the default channels:

    tile_client.thumbnail(output_path='thumbnail_default.png')
    

    thumbnail

    Matplotlib Colormaps

    and you can plot any single band with a matplotlib colormap by:

    l = get_leaflet_tile_layer(tile_client, band=7, palette='rainbow')
    
    
    m = Map(center=tile_client.center(), zoom=10)
    m.add_layer(l)
    m
    
    Screen Shot 2021-12-05 at 6 15 32 PM 1 Source code(tar.gz)
    Source code(zip)
  • 0.3.4(Nov 27, 2021)

    This adds support for serving tiles from remote raster files through GDAL's Virtual Storage Interface. Simply pass your http<s>:// or s3:// URL to the TileClient. This will work quite well for pre-tiled Cloud Optimized GeoTiffs, but I do not recommend doing this with non-tiled raster formats.

    Further, this release contains a few internal changes that dramatically improve the performance of the underlying tile server. Users can control whether the server is run in a multi-threaded or multi-process manner.

    from localtileserver import get_folium_tile_layer
    from localtileserver import TileClient
    from folium import Map
    
    # This is a ~3GiB image
    url = 'https://opendata.digitalglobe.com/events/california-fire-2020/pre-event/2018-02-16/pine-gulch-fire20/1030010076004E00.tif'
    
    # First, create a tile server from local raster file
    tile_client = TileClient(url)
    
    # Create folium tile layer from that server
    t = get_folium_tile_layer(tile_client)
    
    m = Map(location=tile_client.center())
    m.add_child(t)
    m
    
    vsi-raster Source code(tar.gz)
    Source code(zip)
  • 0.3.2(Nov 26, 2021)

    Now you can easily create tile layers for viewing with Folium!

    from localtileserver import get_folium_tile_layer
    from localtileserver import TileClient
    from folium import Map
    
    # First, create a tile server from local raster file
    tile_client = TileClient('~/Desktop/TC_NG_SFBay_US_Geo.tif')
    
    # Create folium tile layer from that server
    t = get_folium_tile_layer(tile_client)
    
    m = Map(location=tile_client.center())
    m.add_child(t)
    m
    

    https://user-images.githubusercontent.com/22067021/143659402-f1ee453c-4c56-4908-a7d7-1e34c83a3edf.mov

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Nov 25, 2021)

  • 0.2.3(Nov 24, 2021)

    Now included are some prebaked UI controls for ipyleaflet that let you easily extract ROIs. Take a look at the example in the README.

    https://user-images.githubusercontent.com/22067021/143311931-e19647d0-74bc-490a-821c-8046fc9c5dfa.mov

    Source code(tar.gz)
    Source code(zip)
  • 0.2.2(Nov 24, 2021)

    The default viewer in the included web app now uses CesiumJS!

    https://user-images.githubusercontent.com/22067021/143178656-12e6e0fa-b601-4746-aae9-726d6f109fee.mov

    Source code(tar.gz)
    Source code(zip)
Owner
Bane Sullivan
R&D Engineer @Kitware. Interested in all things geocomputing and visualization
Bane Sullivan
Wraps GEOS geometry functions in numpy ufuncs.

PyGEOS PyGEOS is a C/Python library with vectorized geometry functions. The geometry operations are done in the open-source geometry library GEOS. PyG

362 Dec 23, 2022
A package built to support working with spatial data using open source python

EarthPy EarthPy makes it easier to plot and manipulate spatial data in Python. Why EarthPy? Python is a generic programming language designed to suppo

Earth Lab 414 Dec 23, 2022
Tool to suck data from ArcGIS Server and spit it into PostgreSQL

chupaESRI About ChupaESRI is a Python module/command line tool to extract features from ArcGIS Server map services. Name? Think "chupacabra" or "Chupa

John Reiser 34 Dec 04, 2022
Tile Map Service and OGC Tiles API for QGIS Server

Tiles API Add tiles API to QGIS Server Tiles Map Service API OGC Tiles API Tile Map Service API - TMS The TMS API provides these URLs: /tms/? to get i

3Liz 6 Dec 01, 2021
PySAL: Python Spatial Analysis Library Meta-Package

Python Spatial Analysis Library PySAL, the Python spatial analysis library, is an open source cross-platform library for geospatial data science with

Python Spatial Analysis Library 1.1k Dec 18, 2022
3D extension built off of shapely to make working with geospatial/trajectory data easier in python.

PyGeoShape 3D extension to shapely and pyproj to make working with geospatial/trajectory data easier in python. Getting Started Installation pip The e

Marc Brittain 5 Dec 27, 2022
Search and download Copernicus Sentinel satellite images

sentinelsat Sentinelsat makes searching, downloading and retrieving the metadata of Sentinel satellite images from the Copernicus Open Access Hub easy

837 Dec 28, 2022
Python script that can be used to generate latitude/longitude coordinates for GOES-16 full-disk extent.

goes-latlon Python script that can be used to generate latitude/longitude coordinates for GOES-16 full-disk extent. 🌎 πŸ›°οΈ The grid files can be acces

Douglas Uba 3 Apr 06, 2022
Mmdb-server - An open source fast API server to lookup IP addresses for their geographic location

mmdb-server mmdb-server is an open source fast API server to lookup IP addresses

Alexandre Dulaunoy 67 Nov 25, 2022
A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.

Django Countries A Django application that provides country choices for use with forms, flag icons static files, and a country field for models. Insta

Chris Beaven 1.2k Jan 03, 2023
Python library to visualize circular plasmid maps

Plasmidviewer Plasmidviewer is a Python library to visualize plasmid maps from GenBank. This library provides only the function to visualize circular

Mori Hideto 9 Dec 04, 2022
Implemented a Google Maps prototype that provides the shortest route in terms of distance

Implemented a Google Maps prototype that provides the shortest route in terms of distance, the fastest route, the route with the fewest turns, and a scenic route that avoids roads when provided a sou

1 Dec 26, 2021
Python interface to PROJ (cartographic projections and coordinate transformations library)

pyproj Python interface to PROJ (cartographic projections and coordinate transformations library). Documentation Stable: http://pyproj4.github.io/pypr

832 Dec 31, 2022
The geospatial toolkit for redistricting data.

maup maup is the geospatial toolkit for redistricting data. The package streamlines the basic workflows that arise when working with blocks, precincts

Metric Geometry and Gerrymandering Group 60 Dec 05, 2022
Obtain a GNSS position fix from an 11-millisecond raw GNSS signal snapshot

Obtain a GNSS position fix from an 11-millisecond raw GNSS signal snapshot without any prior knowledge about the position of the receiver and only coarse knowledge about the time.

Jonas Beuchert 2 Nov 17, 2022
Documentation and samples for ArcGIS API for Python

ArcGIS API for Python ArcGIS API for Python is a Python library for working with maps and geospatial data, powered by web GIS. It provides simple and

Esri 1.4k Dec 30, 2022
This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

0 Dec 27, 2021
Rasterio reads and writes geospatial raster datasets

Rasterio Rasterio reads and writes geospatial raster data. Geographic information systems use GeoTIFF and other formats to organize and store gridded,

Mapbox 1.9k Jan 07, 2023
gjf: A tool for fixing invalid GeoJSON objects

gjf: A tool for fixing invalid GeoJSON objects The goal of this tool is to make it as easy as possible to fix invalid GeoJSON objects through Python o

Yazeed Almuqwishi 91 Dec 06, 2022
Simulation and Parameter Estimation in Geophysics

Simulation and Parameter Estimation in Geophysics - A python package for simulation and gradient based parameter estimation in the context of geophysical applications.

SimPEG 390 Dec 15, 2022