Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: flake8 Lint

on: [push, pull_request]

jobs:
flake8-lint:
runs-on: ubuntu-latest
name: Lint with flake8
steps:
- uses: actions/checkout@v1
- uses: ricardochaves/python-lint@v1.3.0
with:
use-pylint: false
use-pycodestyle: false
use-flake8: true
use-black: false
use-mypy: false
use-isort: false
7 changes: 0 additions & 7 deletions .github/workflows/python-test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ jobs:
- name: Install Mapshader code
run: |
$CONDA/bin/pip install -e .
- name: Lint with flake8
run: |
# $CONDA/bin/conda install flake8
# stop the build if there are Python syntax errors or undefined names
# $CONDA/bin/flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# $CONDA/bin/flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
$CONDA/bin/pip install pytest
Expand Down
5 changes: 4 additions & 1 deletion conda.recipe/run_test.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
import mapshader;mapshader.test()
import mapshader


mapshader.test()
7 changes: 6 additions & 1 deletion mapshader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@ def hello(services=None):
print('\tServices', file=sys.stdout)
print('\t--------\n', file=sys.stdout)
for s in services:
service_msg = f'\t > {s.name} - {s.service_type} - {s.source.geometry_type} - {s.source.description}'
service_msg = '\t > {0} - {1} - {2} - {3}'.format(
s.name,
s.service_type,
s.source.geometry_type,
s.source.description
)
print(service_msg, file=sys.stdout)
2 changes: 1 addition & 1 deletion mapshader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def to_raster(source: MapSource,
return create_agg(source, xmin, ymin, xmax, ymax, None, None, None, height, width)


def render_map(source: MapSource,
def render_map(source: MapSource, # noqa: C901
xmin: float = None, ymin: float = None,
xmax: float = None, ymax: float = None,
x: float = None, y: float = None,
Expand Down
141 changes: 83 additions & 58 deletions mapshader/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ def flask_to_geojson(source: MapSource):
if not source.is_loaded:
source.load()

q = request.args.get('q')
limit = request.args.get('limit')
offset = request.args.get('offset')
simplify = request.args.get('simplify')
bbox = request.args.get('bbox')

resp = render_geojson(source)
return resp

Expand Down Expand Up @@ -128,58 +122,89 @@ def service_page(service: MapService):
plot = build_previewer(service)
script, div = components(dict(preview=plot))

template = Template('''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<title>{{service.name}}</title>
{{ resources }}
{{ script }}
<style>

.embed-wrapper {
display: flex;
justify-content: space-evenly;
}

body {
font-family: "Roboto", sans-serif;
}

.header {
padding: 10px;
}
</style>
</head>
<body>
{{ psutils_html }}
<div class="header">
<h3>{{service.name}}</h3>
<hr />
<h5><strong>Client URL:</strong> {{service.client_url}}</h5>
<h5><strong>Description:</strong> {{service.source.description}}</h5>
<h5><strong>Geometry Type:</strong> {{service.source.geometry_type.capitalize()}}</h5>
</div>
<hr />
<div class="embed-wrapper">
{% for key in div.keys() %}
{{ div[key] }}
{% endfor %}
</div>
<hr />
<div class="header">
<h4>Details</h4>
<hr />
<h5><strong>Data Path:</strong> {{service.source.filepath}}</h5>
<h5><strong>Span:</strong> {{service.source.span}}</h5>
<h5><strong>Overviews:</strong> {{service.source.overviews.keys()}}</h5>
<h5><strong>Aggregation Method:</strong> {{service.source.agg_func}}</h5>
<h5><strong>Colormap Interpolation Method:</strong> {{service.source.shade_how}}</h5>
</div>
</body>
</html>
''')
template = Template(
'''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<title>{{service.name}}</title>
{{ resources }}
{{ script }}
<style>
.embed-wrapper {
display: flex;
justify-content: space-evenly;
}
body {
font-family: "Roboto", sans-serif;
}
.header {
padding: 10px;
}
</style>
</head>
<body>
{{ psutils_html }}
<div class="header">
<h3>{{service.name}}</h3>
<hr />
<h5><strong>Client URL:</strong>
{{service.client_url}}
</h5>
<h5><strong>Description:</strong>
{{service.source.description}}
</h5>
<h5><strong>Geometry Type:</strong>
{{service.source.geometry_type.capitalize()}}
</h5>
</div>
<hr />
<div class="embed-wrapper">
{% for key in div.keys() %}
{{ div[key] }}
{% endfor %}
</div>
<hr />
<div class="header">
<h4>Details</h4>
<hr />
<h5>
<strong>
Data Path:
</strong>
{{service.source.filepath}}
</h5>
<h5>
<strong>
Span:
</strong>
{{service.source.span}}
</h5>
<h5>
<strong>
Overviews:
</strong>
{{service.source.overviews.keys()}}
</h5>
<h5>
<strong>
Aggregation Method:
</strong>
{{service.source.agg_func}}
</h5>
<h5>
<strong>
Colormap Interpolation Method:
</strong>
{{service.source.shade_how}}
</h5>
</div>
</body>
</html>
'''
)

resources = INLINE.render()
html = template.render(resources=resources,
Expand Down
10 changes: 3 additions & 7 deletions mapshader/io.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import rioxarray
import xarray as xr
import datashader as ds
import geopandas as gpd
import numpy as np
from affine import Affine

from os.path import expanduser

import geopandas as gpd
import numpy as np
import xarray as xr


def load_raster(file_path, xmin=None, ymin=None,
Expand Down
22 changes: 6 additions & 16 deletions mapshader/mercator.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,12 @@ def to_ogc_tile_metadata(self, output_file_path):
'''
pass


def to_esri_tile_metadata(self, output_file_path):
'''
Create ESRI tile metadata JSON
'''
pass


def is_valid_tile(self, x, y, z):

if x < 0 or x >= math.pow(2, z):
Expand All @@ -72,18 +70,15 @@ def is_valid_tile(self, x, y, z):

return True


# TODO ngjit?
def _get_resolution(self, z):
return self.initial_resolution / (2 ** z)


def get_resolution_by_extent(self, extent, height, width):
x_rs = (extent[2] - extent[0]) / width
y_rs = (extent[3] - extent[1]) / height
return [x_rs, y_rs]


def get_level_by_extent(self, extent, height, width):
x_rs = (extent[2] - extent[0]) / width
y_rs = (extent[3] - extent[1]) / height
Expand All @@ -100,41 +95,34 @@ def get_level_by_extent(self, extent, height, width):
i += 1
return (i-1)


def pixels_to_meters(self, px, py, level):
res = self._get_resolution(level)
mx = (px * res) - self.x_origin_offset
my = (py * res) - self.y_origin_offset
return (mx, my)


def meters_to_pixels(self, mx, my, level):
res = self._get_resolution(level)
px = (mx + self.x_origin_offset) / res
py = (my + self.y_origin_offset) / res
return (px, py)


def pixels_to_tile(self, px, py, level):
tx = math.ceil(px / self.tile_size)
tx = tx if tx == 0 else tx - 1
ty = max(math.ceil(py / self.tile_size) - 1, 0)
# convert from TMS y coordinate
return (int(tx), invert_y_tile(int(ty), level))


def pixels_to_raster(self, px, py, level):
map_size = self.tile_size << level
return (px, map_size - py)


def meters_to_tile(self, mx, my, level):
px, py = self.meters_to_pixels(mx, my, level)
return self.pixels_to_tile(px, py, level)


def get_tiles_by_extent(self, extent, level):

# unpack extent and convert to tile coordinates
xmin, ymin, xmax, ymax = extent
# note y coordinates are reversed since they are in opposite direction to meters
Expand All @@ -151,10 +139,12 @@ def get_tiles_by_extent(self, extent, level):

return tiles


def get_tile_meters(self, tx, ty, level):
ty = invert_y_tile(ty, level) # convert to TMS for conversion to meters
ty = invert_y_tile(ty, level) # convert to TMS for conversion to meters
xmin, ymin = self.pixels_to_meters(tx * self.tile_size, ty * self.tile_size, level)
xmax, ymax = self.pixels_to_meters((tx + 1) * self.tile_size, (ty + 1) * self.tile_size, level)
xmax, ymax = self.pixels_to_meters(
(tx + 1) * self.tile_size,
(ty + 1) * self.tile_size,
level,
)
return (xmin, ymin, xmax, ymax)

2 changes: 1 addition & 1 deletion mapshader/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class MapSource(object):

def __init__(self,
def __init__(self, # noqa: C901
name=None,
description=None,
filepath=None,
Expand Down
5 changes: 4 additions & 1 deletion mapshader/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@

wgs84_proj_str = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'

us_national_equal_area_str = '+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs'
us_national_equal_area_str = (
'+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 '
'+b=6370997 +units=m +no_defs'
)

projections = {
3857: wb_proj_str,
Expand Down
Loading