import logging
import os
import threading
import flask
from flask import render_template, send_from_directory
from werkzeug.serving import make_server
[docs]class ServerThread(threading.Thread):
"""
Create a thread to run server in backgound
:param port: a flask app
:param app: pick the port to serve the cesium viewer (default port 8787)
"""
def __init__(self, app, port):
threading.Thread.__init__(self)
self.server = make_server("127.0.0.1", port, app)
self.ctx = app.app_context()
self.ctx.push()
[docs] def run(self):
logging.info("starting server")
self.server.serve_forever()
[docs] def shutdown(self):
self.server.shutdown()
[docs]class CesiumServer:
"""
Serve cesium viewer locally
:param port: pick the port to serve the cesium viewer (default port 8787)
"""
def __init__(
self,
tiles_directory: str = None,
port: int = 8787,
) -> None:
self.port = port
self.url = "http://127.0.0.1:{}".format(str(port))
self.live = False
self.server_thread = None
self.tiles_directory = tiles_directory
self._tiles = None
def __repr__(self):
return "<CesiumServer url:%s live:%s>" % (self.url, self.live)
@property
def tiles_served(self):
if self.tiles_directory is None:
logging.info(
"Cannot find tile directory. Please set CesiumViewer.cesium_server.tiles_directory attribute"
)
return None
else:
return [x for x in os.listdir(self.tiles_directory)]
@property
def tiles_path(self):
if self.tiles_directory is None:
logging.info(
"Cannot find tile directory. Please set CesiumViewer.cesium_server.tiles_directory attribute"
)
return None
else:
return [os.path.realpath(x) for x in os.listdir(self.tiles_directory)]
@property
def tiles_url(self):
if not self.tiles_served:
logging.info("No tiles in directory %s" % self.tiles_directory)
return None
else:
return [
{
"name": tile,
"resource": self.url + "/tiles/" + tile + "/tileset.json",
"colorbar": self.url + "/tiles/" + tile + "/colorbar.json",
}
for tile in self.tiles_served
]
[docs] def start_server(self):
dirname = os.path.dirname(__file__)
template_dir = os.path.join(dirname, "templates")
static_dir = os.path.join(dirname, "static")
tiles_dir = self.tiles_directory
app = flask.Flask(
"myapp", template_folder=template_dir, static_folder=static_dir
)
@app.route("/")
def home():
return render_template("example.html", jsonobj=self.tiles_url)
@app.route("/tiles/<path:filepath>")
def tiles(filepath):
return send_from_directory(tiles_dir, filepath)
self.server_thread = ServerThread(app, self.port)
self.server_thread.start()
self.live = True
logging.info("server started")
logging.info(self.url)
[docs] def stop_server(self):
self.server_thread.shutdown()
self.live = False